Problem Description
Solution
To ensure your moving average (or any indicator) has enough data before using it in your logic within QuantConnect, you should utilize two specific mechanisms: the is_ready property and the set_warm_up method.
1. The is_ready Property
Every indicator object in LEAN has a boolean property called is_ready (or IsReady in C#). This property returns True only when the indicator has received enough data points to produce a valid value.
2. The set_warm_up Method
To avoid waiting for the indicator to fill up during the start of your backtest (which causes you to miss trades), you should use self.set_warm_up(period). This feeds historical data into your algorithm before the start date, ensuring indicators are ready immediately when the simulation begins.
Implementation Example
The following code demonstrates how to initialize a Simple Moving Average (SMA), warm up the algorithm, and check if the indicator is ready before trading.
from AlgorithmImports import *
class MovingAverageReadinessAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2020, 1, 1)
self.set_end_date(2023, 1, 1)
self.set_cash(100000)
# 1. Add Security
self.symbol = self.add_equity("SPY", Resolution.DAILY).symbol
# 2. Define the Indicator
# We need 30 data points for this SMA to be valid
self.period = 30
self.sma = self.sma(self.symbol, self.period, Resolution.DAILY)
# 3. Set Warm Up
# This automatically feeds historical data into the algorithm
# before the StartDate so the SMA is ready immediately.
self.set_warm_up(self.period)
def on_data(self, data: Slice):
# 4. Safety Check
# Always check .is_ready. Even with SetWarmUp, this is best practice
# to prevent errors if data is missing or during live trading restarts.
if not self.sma.is_ready:
return
# Trading Logic
# Because of SetWarmUp, this will execute on the very first day of the backtest
if self.securities[self.symbol].price > self.sma.current.value:
if not self.portfolio.invested:
self.set_holdings(self.symbol, 1.0)
elif self.securities[self.symbol].price < self.sma.current.value:
if self.portfolio.invested:
self.liquidate(self.symbol)
Key Details
self.sma(...): This helper method creates the indicator and automatically registers it to receive data updates.self.set_warm_up(self.period): If you omit this,self.sma.is_readywill beFalsefor the first 30 days of the backtest, and the algorithm will do nothing during that time.if not self.sma.is_ready: return: This acts as a guard clause. If the indicator isn't fully formed, the method exits immediately, preventing the code from crashing when trying to accessself.sma.current.value.
Q&A
Q: What happens if I don't use set_warm_up?
A: If you do not use set_warm_up, the algorithm will start at your StartDate with empty indicators. You will have to wait for $N$ bars (the length of your indicator) of live simulation time to pass before is_ready becomes true.
Q: Can I warm up using a specific time span instead of a number of bars?
A: Yes. You can pass a timedelta to the method. For example: self.set_warm_up(timedelta(days=60)). This is useful if you have indicators with different periods and want to cover the longest one.
Q: Does is_ready work for custom Python indicators?
A: Yes, provided your custom indicator inherits from PythonIndicator and you correctly implement the Update method to manage the IsReady flag (usually by checking if the internal window is full).
Q: How do I check if a RollingWindow is ready?
A: RollingWindow objects also have an is_ready property. It returns True only when the window is completely full (i.e., the count of items equals the size of the window).