1. from AlgorithmImports import *
  2. #from AlgorithmImports.Indicators import *
  3. import joblib
  4. class RandomForestAlgorithm(QCAlgorithm):
  5. def Initialize(self):
  6. self.SetStartDate(2000, 1, 1) # Set the start date
  7. self.SetEndDate(2000, 1, 31)
  8. self.SetCash(100000) # Set the initial cash balance
  9. # Load the machine learning model
  10. model_key = 'spy_randomforest_predictor'
  11. if self.ObjectStore.ContainsKey(model_key):
  12. file_name = self.ObjectStore.GetFilePath(model_key)
  13. self.model = joblib.load(file_name)
  14. else:
  15. # Handle the case when the model is not found
  16. self.Error(f"Model '{model_key}' not found.")
  17. self.Quit() # You may want to exit the algorithm here
  18. #self.SetBenchmark("SPY") # Set the benchmark
  19. self.spy = self.AddEquity("SPY").Symbol # Add SPY data
  20. # Add the VIX data using AddData
  21. self.vix = self.AddData(CBOE, "VIX", Resolution.Daily).Symbol
  22. # Add USTYCR data using AddData
  23. self.syield10yr = self.AddData(USTreasuryYieldCurveRate, "USTYCR", Resolution.Daily).Symbol
  24. # Initialize rolling windows
  25. self.vix_window = RollingWindow[float](30)
  26. self.spy_window = RollingWindow[float](30)
  27. self.syield10yr_window = RollingWindow[float](30)
  28. # Initialize indicators
  29. self.mfi = MoneyFlowIndex(14)
  30. self.macd = MovingAverageConvergenceDivergence(12, 26, 9, MovingAverageType.Wilders)
  31. self.williams = WilliamsPercentR(14)
  32. self.stochastic = Stochastic(14, 3, 3)
  33. # Attach indicators to SPY data
  34. self.RegisterIndicator(self.spy, self.mfi, Resolution.Daily)
  35. self.RegisterIndicator(self.spy, self.macd, Resolution.Daily)
  36. self.RegisterIndicator(self.spy, self.williams, Resolution.Daily)
  37. self.RegisterIndicator(self.spy, self.stochastic, Resolution.Daily)
  38. # Initialize a counter to keep track of warm-up period
  39. #self.warm_up_counter = 0
  40. self.SetWarmUp(30) # Set the warm-up period
  41. def OnData(self, slice):
  42. if slice.ContainsKey("VIX.CBOE") and slice.ContainsKey(self.spy) and slice.ContainsKey("USTYCR"):
  43. # Access the data if it exists
  44. vix_data = slice["VIX.CBOE"]
  45. spy_data = slice[self.spy]
  46. syield10yr_data = slice["USTYCR"]
  47. # Update rolling windows with new data
  48. self.vix_window.Add(vix_data.Close)
  49. self.spy_window.Add(spy_data.Close)
  50. self.syield10yr_window.Add(syield10yr_data.TenYear)
  51. # Increment the warm-up counter
  52. #self.warm_up_counter += 1
  53. if self.IsWarmingUp:
  54. return
  55. else:
  56. df = self.CalculateFeatures()
  57. prediction = self.GetPrediction(df)
  58. if prediction == "Up":
  59. self.SetHoldings(self.spy, 1)
  60. else:
  61. self.SetHoldings(self.spy, 0)
  62. #else:
  63. # Data is not available, handle this case (e.g., log a message)
  64. #self.Debug("Data not available for one or more symbols")
  65. def CalculateFeatures(self):
  66. # Calculate your features from the data and create a DataFrame
  67. # Replace this with your specific feature calculation logic
  68. # Ensure that the DataFrame has the required columns ('vix_lagged', 'return_shift', etc.)
  69. # Example placeholder for feature calculation:
  70. vix_lagged = self.vix_window[0] # Replace with actual calculation
  71. return_shift = self.spy_window[0] # Replace with actual calculation
  72. change_yield_rate_shift = self.syield10yr_window[0] # Replace with actual calculation
  73. # Calculate MFI, MACD, Williams %R, and Stochastic Oscillator using indicators
  74. mfi = self.mfi.Current.Value
  75. macd = self.macd.Current.Value
  76. williams = self.williams.Current.Value
  77. stochastic = self.stochastic.Current.Value
  78. # Create a DataFrame with the calculated features
  79. df = pd.DataFrame({
  80. 'vix_lagged': vix_lagged,
  81. 'return_shift': return_shift,
  82. 'change_yield_rate_shift': change_yield_rate_shift,
  83. 'mfi': mfi,
  84. 'macd': macd,
  85. 'williams': williams,
  86. 'stochastic': stochastic
  87. })
  88. self.Debug(df.tail(1))
  89. return df.tail(1) # Return the last row of the DataFrame
  90. def GetPrediction(self, df):
  91. # Ensure that you have enough data for prediction
  92. if len(df) == 0:
  93. return "NotEnoughData"
  94. # Make the prediction using your machine learning model
  95. prediction = self.model.predict(df)
  96. if prediction == 1:
  97. return "Up"
  98. else:
  99. return "Down"
+ Expand

Author

Octavio del Sueldo

September 2023