Overall Statistics |
Total Trades 57 Average Win 0.63% Average Loss -0.38% Compounding Annual Return 5.744% Drawdown 2.700% Expectancy 0.046 Net Profit 1.201% Sharpe Ratio 0.624 Probabilistic Sharpe Ratio 42.297% Loss Rate 61% Win Rate 39% Profit-Loss Ratio 1.66 Alpha -0.059 Beta 0.579 Annual Standard Deviation 0.063 Annual Variance 0.004 Information Ratio -2.434 Tracking Error 0.054 Treynor Ratio 0.068 Total Fees $65.03 Estimated Strategy Capacity $43000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X |
# https://quantpedia.com/Screener/Details/14 class MomentumEffectAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 7, 1) # Set Start Date self.SetCash(100000) # Set Strategy Cash self.UniverseSettings.Resolution = Resolution.Minute self.macd = {} # Dict of Momentum indicator keyed by Symbol self.atr = {} self.userlist = ["SPY"] #User list self.spy = self.AddEquity("SPY", Resolution.Minute).Symbol self.AutomaticIndicatorWarmup = True self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction) self.counter = 0 self.consolidatorCounter = 0 # self.Schedule.On(self.DateRules.EveryDay("SPY"), # self.TimeRules.Every(timedelta(minutes=31)), # self.Trade) def ThirtyMinuteHandler(self, sender, bar): self.consolidatorCounter += 1 if self.consolidatorCounter == self.counter: for i in self.Securities.Keys: self.Debug(self.atr[i].Current.Value) if self.macd[i].Current.Value > self.macd[i].Signal.Current.Value: self.SetHoldings(i, 1) elif self.macd[i].Signal.Current.Value > self.macd[i].Current.Value: self.Liquidate(i) self.consolidatorCounter = 0 def Trade(self): pass def CoarseSelectionFunction(self, coarse): return [x.Symbol for x in coarse if x.Symbol.Value in self.userlist] def FineSelectionFunction(self, fine): return [x.Symbol for x in fine if x.Symbol.Value in self.userlist] def OnData(self, data): ''' Use scheduled event or this ''' # if self.Time.minutes % 30 == 1: # self.Trade() pass def OnSecuritiesChanged(self, changes): # Clean up data for removed securities and Liquidate for security in changes.RemovedSecurities: pass for security in changes.AddedSecurities: #if security.Symbol == self.spy: continue thirtyMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=30)) thirtyMinuteConsolidator.DataConsolidated += self.ThirtyMinuteHandler # Register consolidator to get automatically updated with minute data self.SubscriptionManager.AddConsolidator(security.Symbol, thirtyMinuteConsolidator) if security.Symbol not in self.macd: self.macd[security.Symbol] = MovingAverageConvergenceDivergence(12, 26, 9, MovingAverageType.Exponential) self.atr[security.Symbol] = AverageTrueRange(20, MovingAverageType.Simple) self.RegisterIndicator(security.Symbol, self.macd[security.Symbol], thirtyMinuteConsolidator, Field.Open) self.RegisterIndicator(security.Symbol, self.atr[security.Symbol], thirtyMinuteConsolidator) self.counter = len(self.macd.keys()) ''' Manually warm up of a tradebar indicator ''' # history = algorithm.History(symbol, 14, Resolution.Daily) # atr = algorithm.ATR(symbol, 14, MovingAverageType.Simple, Resolution.Daily) # for tuple in history.loc[symbol].itertuples(): # bar = TradeBar(tuple.Index, symbol, tuple.open, tuple.high, tuple.low, tuple.close, tuple.volume) # atr.Update(bar)