| 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)