Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -9.075 Tracking Error 0.079 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
# region imports from AlgorithmImports import * import datetime # endregion class NdxMonthly(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 12, 1) # self.SetEndDate(2023, 12, 31) self.SetEndDate(datetime.date.today()) self.SetCash(100000) self.SetSecurityInitializer(lambda security: security.SetDataNormalizationMode(DataNormalizationMode.SplitAdjusted)) self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol self.spx = self.AddIndex("SPX", Resolution.Daily).Symbol self.spy_ema5 = self.EMA(self.spy, 5) self.spy_sma200 = self.SMA(self.spy, 200) # set data normaliaztion mode self.UniverseSettings.Resolution = Resolution.Daily self.universe_etf = self.AddUniverse(self.Universe.ETF("QQQ", Market.USA, self.UniverseSettings, self.ETFConstituentsFilter)) self.EnableAutomaticIndicatorWarmUp = True self.indicators = {} def ETFConstituentsFilter(self, constituents: List[ETFConstituentData]) -> List[Symbol]: indicators = {} for c in constituents: symbol = c.Symbol if c not in self.ActiveSecurities.Keys: self.AddEquity(symbol, Resolution.Daily) roc_short = self.ROC(symbol, 120).Current.Value * 100 roc_long = self.ROC(symbol, 240).Current.Value * 100 sma120 = self.SMA(symbol, 120) ema10 = self.EMA(symbol, 10) momentum = roc_short * (252/120) * .95 + roc_long * (252/240) * 1.05 # slightly weighted towards long factor = 0.4 * self.ROC(symbol, 63).Current.Value * 100 + 0.2 * self.ROC(symbol, 126).Current.Value * 100 + 0.2 * self.ROC(symbol, 189).Current.Value * 100 + 0.2 * self.ROC(symbol, 252).Current.Value * 100 # Add the indicators to the dictionary indicators[symbol] = round(momentum, 2) # remove securities that we are subsribed to but are not in constituents for symbol in self.ActiveSecurities.Keys: if symbol not in indicators: self.RemoveSecurity(symbol) self.indicators = {c.Symbol: indicators[c.Symbol] for c in constituents} return [c.Symbol for c in constituents] def OnData(self, data: Slice) -> None: if self.IsWarmingUp: # log we are in warmup period self.Log("Warming up...") return bull_mkt = self.spy_ema5.Current.Value > self.spy_sma200.Current.Value if bull_mkt: # and self.Time.day == 1: self.Log("Bull market - number of universe members are currently " + str(len(self.indicators))) else: self.Log(f'Not bull market. SPY EMA5: {self.spy_ema5.Current.Value}, SPY SMA200: {self.spy_sma200.Current.Value}') # for symbol, indicator in self.indicators.items(): # self.Log(f"{symbol}: monthly momo {indicator['momentum']}") # sort the universe by momentum sorted_dict = dict(sorted(self.indicators.items(), key=lambda x: x[1], reverse=True)) symbol_dict = {symbol.Value: value for symbol, value in sorted_dict.items()} # Only keep the top 20 items in symbol_dict symbol_dict = dict(list(symbol_dict.items())[:20]) self.Log("Sorted universe by momentum") self.Log(str(symbol_dict)) str_output = '' for symbol, indicator in symbol_dict.items(): str_output += f"{symbol},{indicator}\n" try: spx_history = self.History([self.spx], 1, Resolution.Daily) spx_close = spx_history.loc[self.spx].close[-1] self.Log(f"SPX close price: {spx_close}") self.Log(str(spx_history)) except: self.Log("Error getting SPX close price")