Overall Statistics |
Total Trades 31 Average Win 3.67% Average Loss -3.46% Compounding Annual Return 83.236% Drawdown 25.100% Expectancy 0.177 Net Profit 11.550% Sharpe Ratio 1.637 Probabilistic Sharpe Ratio 53.608% Loss Rate 43% Win Rate 57% Profit-Loss Ratio 1.06 Alpha 1.055 Beta -1.76 Annual Standard Deviation 0.516 Annual Variance 0.266 Information Ratio 1.148 Tracking Error 0.631 Treynor Ratio -0.48 Total Fees $57.35 |
class FuturesMovingAverageCrossOverExample2(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) #Set Start Date self.SetEndDate(2018, 3,6) #Set End Date self.SetCash(100000) #Set Strategy Cash self.SetTimeZone('America/Los_Angeles') # Set timezone self.reset = True self.SymbolData = { } self.AddEquity("SPY", Resolution.Minute) futureES = self.AddFuture(Futures.Indices.SP500EMini) futureES.SetFilter(0, 360) self.Schedule.On(self.DateRules.Every(DayOfWeek.Tuesday), self.TimeRules.AfterMarketOpen("SPY", 10), self.ScheduleDemo) def OnData(self, slice): # Reset any open positions based on a contract rollover. if self.reset: self.reset = False self.Log('RESET: closing all positions') self.Liquidate() def OnSecuritiesChanged(self, changes): for added in changes.AddedSecurities: # Only trade Futures if added.Type != SecurityType.Future: continue symbol = added.Symbol if symbol not in self.SymbolData: macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Minute) self.SymbolData[symbol] = AssetData(macd) for removed in changes.RemovedSecurities: assetData = self.SymbolData.pop(removed.Symbol, None) if assetData: self.Liquidate(removed.Symbol) assetData.Dispose() def ScheduleDemo(self): tolerance = 0.003 for symbol, assetData in self.SymbolData.items(): security = self.Securities[symbol] # Only new positions not invested if security.Invested: continue price = security.Price signalDeltaPercent = assetData.macd.Current.Value - assetData.macd.Signal.Current.Value if signalDeltaPercent < -tolerance: #Go long self.MarketOrder(symbol, 1) assetData.takeProfit = self.LimitOrder(symbol, -1, price*1.03) assetData.stopLoss = self.StopMarketOrder(symbol, -1, price*0.97) if signalDeltaPercent > tolerance: #Go short self.MarketOrder(symbol, -1) assetData.takeProfit = self.LimitOrder(symbol, 1, price*0.97) assetData.stopLoss = self.StopMarketOrder(symbol, 1, price*1.03) def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return assetData = self.SymbolData.get(orderEvent.Symbol, None) if assetData: assetData.Cancel(orderEvent.OrderId) class AssetData: def __init__(self, macd): self.macd = macd self.takeProfit = None self.stopLoss = None def Cancel(self, id): '''cancel one order if the other was filled''' if self.takeProfit is not None and id == self.takeProfit.OrderId: self.stopLoss.Cancel() if self.stopLoss is not None and id == self.stopLoss.OrderId: self.takeProfit.Cancel() def Dispose(self): '''cancel submitted orders''' if self.takeProfit is not None: self.takeProfit.Cancel() if self.stopLoss is not None: self.stopLoss.Cancel()