I am using the algorithm framework and on main.py I am trying to find 14 day RSI of SPY to use as one of several indicators of market conditions, others to be added later, which will determine model set used for alpha, universe, etc. but the RSI determination is not working. QC appears to be using LEAN v2.5.0.0.17034.  I set a 14-period daily RSI for SPY with TradeBarConsolidator and RegisterIndicator should be IsReady=True with ~36.55 on 2018-12-31 (Yahoo adjusted closes, 4 up/9 down days over 14 periods), but stays IsReady=False at Samples=14, crashing post-warm-up on 2019-01-03. Code uses standard v2 setup—expecting RSI ready after 14 daily bars from consolidator. Is this a v2.5 RSI bug? How do I make RSI work without crashing?

 

  1. # region imports
  2. from AlgorithmImports import *
  3. from universe import (StrongBullUniverseModel, WeakBullUniverseModel, SidewaysUpUniverseModel,
  4. SidewaysDownUniverseModel, WeakBearUniverseModel, StrongBearUniverseModel)
  5. from alpha import (StrongBullAlphaModel, WeakBullAlphaModel, SidewaysUpAlphaModel,
  6. SidewaysDownAlphaModel, WeakBearAlphaModel, StrongBearAlphaModel)
  7. from portfolio import (StrongBullPortfolioModel, WeakBullPortfolioModel, SidewaysUpPortfolioModel,
  8. SidewaysDownPortfolioModel, WeakBearPortfolioModel, StrongBearPortfolioModel)
  9. from risk import (StrongBullRiskModel, WeakBullRiskModel, SidewaysUpRiskModel,
  10. SidewaysDownRiskModel, WeakBearRiskModel, StrongBearRiskModel)
  11. from execution import (StrongBullExecutionModel, WeakBullExecutionModel, SidewaysUpExecutionModel,
  12. SidewaysDownExecutionModel, WeakBearExecutionModel, StrongBearExecutionModel)
  13. # endregion
  14. class MatrixMarketAlgo(QCAlgorithm):
  15. def initialize(self):
  16. self.set_start_date(2019, 1, 1)
  17. self.set_end_date(2019, 1, 7)
  18. self.set_cash(100000)
  19. self.UniverseSettings.Resolution = Resolution.Daily
  20. self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol
  21. self.rsi = self.RSI(self.spy, 14, Resolution.Daily)
  22. consolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
  23. consolidator.DataConsolidated += self.on_consolidated_data
  24. self.SubscriptionManager.AddConsolidator(self.spy, consolidator)
  25. self.RegisterIndicator(self.spy, self.rsi, consolidator)
  26. self.SetWarmUp(14, Resolution.Daily)
  27. self.market_condition = None
  28. self.prev_condition = None
  29. self.universe_models = {
  30. "strong_bull": StrongBullUniverseModel(), "weak_bull": WeakBullUniverseModel(),
  31. "sideways_up": SidewaysUpUniverseModel(), "sideways_down": SidewaysDownUniverseModel(),
  32. "weak_bear": WeakBearUniverseModel(), "strong_bear": StrongBearUniverseModel()
  33. }
  34. self.alpha_models = {
  35. "strong_bull": StrongBullAlphaModel(), "weak_bull": WeakBullAlphaModel(),
  36. "sideways_up": SidewaysUpAlphaModel(), "sideways_down": SidewaysDownAlphaModel(),
  37. "weak_bear": WeakBearAlphaModel(), "strong_bear": StrongBearAlphaModel()
  38. }
  39. self.portfolio_models = {
  40. "strong_bull": StrongBullPortfolioModel(), "weak_bull": WeakBullPortfolioModel(),
  41. "sideways_up": SidewaysUpPortfolioModel(), "sideways_down": SidewaysDownPortfolioModel(),
  42. "weak_bear": WeakBearPortfolioModel(), "strong_bear": StrongBearPortfolioModel()
  43. }
  44. self.risk_models = {
  45. "strong_bull": StrongBullRiskModel(), "weak_bull": WeakBullRiskModel(),
  46. "sideways_up": SidewaysUpRiskModel(), "sideways_down": SidewaysDownRiskModel(),
  47. "weak_bear": WeakBearRiskModel(), "strong_bear": StrongBearRiskModel()
  48. }
  49. self.execution_models = {
  50. "strong_bull": StrongBullExecutionModel(), "weak_bull": WeakBullExecutionModel(),
  51. "sideways_up": SidewaysUpExecutionModel(), "sideways_down": SidewaysDownExecutionModel(),
  52. "weak_bear": WeakBearExecutionModel(), "strong_bear": StrongBearExecutionModel()
  53. }
  54. self.universe_model = self.universe_models["strong_bull"]
  55. self.alpha_model = self.alpha_models["strong_bull"]
  56. self.portfolio_model = self.portfolio_models["strong_bull"]
  57. self.risk_model = self.risk_models["strong_bull"]
  58. self.execution_model = self.execution_models["strong_bull"]
  59. self.AddUniverseSelection(self.universe_model)
  60. self.AddAlpha(self.alpha_model)
  61. self.SetPortfolioConstruction(self.portfolio_model)
  62. self.SetRiskManagement(self.risk_model)
  63. self.SetExecution(self.execution_model)
  64. self.Schedule.On(self.DateRules.EveryDay(self.spy), self.TimeRules.At(16, 30), self.update_market_and_models)
  65. def on_consolidated_data(self, sender, bar):
  66. self.Debug(f"Consolidator at {bar.EndTime}: SPY Close={bar.Close}, RSI - Samples={self.rsi.Samples}, IsReady={self.rsi.IsReady}, Value={self.rsi.Current.Value if self.rsi.IsReady else 'N/A'}")
  67. def update_market_and_models(self):
  68. if self.IsWarmingUp:
  69. return
  70. self.Debug(f"Update at {self.Time}: RSI - IsReady={self.rsi.IsReady}, Value={self.rsi.Current.Value if self.rsi.IsReady else 'N/A'}")
  71. if self.rsi.IsReady:
  72. rsi_value = self.rsi.Current.Value
  73. if rsi_value >= 90:
  74. self.market_condition = "strong_bull"
  75. elif rsi_value >= 70:
  76. self.market_condition = "weak_bull"
  77. elif rsi_value >= 50:
  78. self.market_condition = "sideways_up"
  79. elif rsi_value >= 30:
  80. self.market_condition = "sideways_down"
  81. elif rsi_value >= 10:
  82. self.market_condition = "weak_bear"
  83. else:
  84. self.market_condition = "strong_bear"
  85. else:
  86. self.market_condition = None
  87. if self.market_condition is None:
  88. self.Log("ERROR: Market condition is None - insufficient data or RSI not ready")
  89. raise Exception("Market condition calculation failed - stopping algo")
  90. if self.prev_condition is not None and self.market_condition != self.prev_condition:
  91. self.Log(f"ALERT: Market condition changed from {self.prev_condition} to {self.market_condition}")
  92. self.universe_model = self.universe_models[self.market_condition]
  93. self.alpha_model = self.alpha_models[self.market_condition]
  94. self.portfolio_model = self.portfolio_models[self.market_condition]
  95. self.risk_model = self.risk_models[self.market_condition]
  96. self.execution_model = self.execution_models[self.market_condition]
  97. self.SetUniverseSelection(self.universe_model)
  98. self.SetAlpha(self.alpha_model)
  99. self.SetPortfolioConstruction(self.portfolio_model)
  100. self.SetRiskManagement(self.risk_model)
  101. self.SetExecution(self.execution_model)
  102. self.Log(f"Market condition set to: {self.market_condition}")
  103. self.prev_condition = self.market_condition
  104. def on_data(self, data):
  105. if self.spy in data and data[self.spy] is not None:
  106. self.Debug(f"on_data at {self.Time}: SPY Close={data[self.spy].Close}, RSI - Samples={self.rsi.Samples}, IsReady={self.rsi.IsReady}, Value={self.rsi.Current.Value if self.rsi.IsReady else 'N/A'}")
  107. self.Log(f"ON_DATA START: Slice at {self.Time}, Market: {self.market_condition}")
  108. for symbol in self.universe_model.symbols:
  109. if data.ContainsKey(symbol):
  110. self.Debug(f"on_data: {symbol.Value} received")
  111. insights = self.alpha_model.Update(self, data)
  112. targets = self.portfolio_model.CreateTargets(self, insights)
  113. adjusted_targets = self.risk_model.ManageRisk(self, targets)
  114. self.execution_model.Execute(self, adjusted_targets)
  115. self.Log(f"ON_DATA END: Slice processed")
+ Expand

Author

Prefer Not To Say

10 days ago