The documatation recommends using RollingWindows rather than making multiple Historical Data Requests..
"We recommend using RollingWindows to hold periods of data instead of making multiple Historical Data Requests. It is much more efficient as we just need to update the RollingWindow with the latest data point, while a History call fetches the whole requested period and synchronizes the data".
Sounds great. I'm all for efficiency!
However, is it correct that prices in RollingWindows will not automatically be back adjusted for splits and dividends?
If so, I assume it is up to me then to manually adjust the prices. But I'm not sure how. Is there an example algorithm that someone could point me to that handles price adjustments for RollingWindows?
Thanks in advance.
Charles Naccio
I'm interested in this as well as we primarily trade small cap stocks which go through reverse splits quite often.
Steve Jost
Doing a bit more testing, I think I answered the question if prices in rolling windows are adjusted for splits and dividends. At the moment I am not live trading so the observation applies only to backtest. The answer is that prices are adjusted for splits but not for dividends.
I used AAPL as a test case and I see prices in my rolling window are adjusted for the 4:1 split that occurred on Aug 31, 2020. Prices are not adjusted however, for the dividend that occurred on Nov 6, 2020. I tried all different Data Normalization settings for AAPL including TotalReturn but none of these provide dividend adjusted prices.
That said the prices in my rolling window are the same as prices using a Historical Data request. Both provide split adjusted prices but neither adjusts for dividends.
import pandas as pd
import numpy as np
class RollingWindowAdjustedPrices(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 8, 28)
self.SetEndDate(2020, 11, 9)
self.SetCash(100000)
EquityObj = self.AddEquity("AAPL", Resolution.Daily)
self.SymbolObj = EquityObj.Symbol
self.Securities[self.SymbolObj].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)
self.rolling_window = pd.DataFrame()
self.window_size = 51
self.SetWarmUp(self.window_size)
def OnData(self, data):
if self.SymbolObj not in data.Bars:
return
close = data[self.SymbolObj].Close
if self.IsWarmingUp:
# Add latest close to rolling window
row = pd.DataFrame({"close": [close]}, index=[data.Time])
self.rolling_window = self.rolling_window.append(row).iloc[-self.window_size:]
return
closes = np.append(self.rolling_window['close'].values, close)[-self.window_size:]
row = pd.DataFrame({"close": [close]}, index=[data.Time])
self.rolling_window = self.rolling_window.append(row).iloc[-self.window_size:]
def OnEndOfAlgorithm(self):
self.Log(f"\nRolling Window:\n{self.rolling_window.to_string()}\n")
self.Log(" ")
histCloses = self.History(self.SymbolObj,self.window_size,Resolution.Daily)['close'].unstack(level=0).dropna()
self.Log(f"\nHistory Window:\n{histCloses.to_string()}\n")
Jared Broad
1) Prices in backtesting by default in LEAN are adjusted for splits and dividends; live mode is always the live/raw prices.
2) However, is it correct that prices in RollingWindows will not automatically be back adjusted for splits and dividends?
-> When you get a split or dividend event you should repopulate the rolling window with a history request.
If you believe there is a missing dividend please post a data issue to the data explorer with a backtest to reproduce the issue. This is the relevant page that shows the latest missing dividend.
Generally please try and avoid making categorical statements that conflict with the documentation. They are generally incorrect, but worse confuse community members who will just scan the post and not understand the nuance.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Charles Naccio
Wanted to note here that in my case, the issue was actually missing split data for one specific name. As Jared mentioned, it was easy enough to re-populate rolling windows with in response to a spilt event. After notifying support, the issue was quickly fixed.
Steve Jost
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!