Overall Statistics |
Total Trades 64 Average Win 0.18% Average Loss 0% Compounding Annual Return -0.985% Drawdown 7.600% Expectancy 0 Net Profit -2.352% Sharpe Ratio -0.097 Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha -0.007 Beta 0.001 Annual Standard Deviation 0.073 Annual Variance 0.005 Information Ratio -0.578 Tracking Error 0.157 Treynor Ratio -7.325 Total Fees $64.00 |
namespace QuantConnect { /* * QuantConnect University: Full Basic Template: * * The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect. * We have explained some of these here, but the full algorithm can be found at: * https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs */ public class BasicTemplateAlgorithm : QCAlgorithm { decimal alpha; decimal lastClose; /*int a; bool buy;*/ private const string Symbol = "SPY"; private readonly List<OrderTicket> _openOrders = new List<OrderTicket>(); //Initialize the data and resolution you require for your strategy: public override void Initialize() { alpha = new Decimal(1.05); lastClose = new Decimal(1); /*a = 0; buy = true;*/ //Start and End Date range for the backtest: SetStartDate(2014, 1, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash allocation SetCash(25000); //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Equity, "SPY", Resolution.Hour); } public static decimal nextBid(decimal a, decimal price){ return price*a; } public static decimal nextAsk(decimal a, decimal price){ return price*(2-a); } private bool CheckPairOrdersForFills(OrderTicket longOrder, OrderTicket shortOrder) { if (longOrder.Status == OrderStatus.Filled) { Log(shortOrder.OrderType + ": Cancelling short order, long order is filled."); shortOrder.Cancel("Long filled."); return true; } if (shortOrder.Status == OrderStatus.Filled) { Log(longOrder.OrderType + ": Cancelling long order, short order is filled."); longOrder.Cancel("Short filled"); return true; } return false; } private bool TimeIs(int hour1, int hour2, int hour3) { return Time.Hour == hour1 || Time.Hour == hour2 || Time.Hour == hour3; } //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol. public void OnData(TradeBars data) { //decimal ask = 0; //decimal bid = 0; decimal close = data["SPY"].Close; decimal cash = Portfolio.Cash; int quantity = (int)Math.Floor(cash / (10*close)); if(TimeIs(10,13,15) && ((cash/10) < Portfolio.GetBuyingPower(Symbol, OrderDirection.Hold))){ if(!Portfolio.HoldStock){ OrderTicket newTicket = LimitOrder(Symbol, quantity, close*.99m); _openOrders.Add(newTicket); newTicket = LimitOrder(Symbol, -quantity, close*1.01m); _openOrders.Add(newTicket); if (_openOrders.Count == 2){ Debug("-----HOLA"); // check if either is filled and cancel the other var longOrder = _openOrders[0]; var shortOrder = _openOrders[1]; if (CheckPairOrdersForFills(longOrder, shortOrder)) { Debug("----SI"); _openOrders.Clear(); return; } var newLongLimit = longOrder.Get(OrderField.LimitPrice) + 0.01m; var newShortLimit = shortOrder.Get(OrderField.LimitPrice) - 0.01m; Log("Updating limits - Long: " + newLongLimit.ToString("0.00") + " Short: " + newShortLimit.ToString("0.00")); longOrder.Update(new UpdateOrderFields { // we could change the quantity, but need to specify it //Quantity = LimitPrice = newLongLimit, Tag = "Update #" + (longOrder.UpdateRequests.Count + 1) }); shortOrder.Update(new UpdateOrderFields { LimitPrice = newShortLimit, Tag = "Update #" + (shortOrder.UpdateRequests.Count + 1) }); } } } } } }