Historical Data

Warm Up Periods

Introduction

LEAN supports an automated fast-forward system called "Warm Up". It simulates winding back the clock from the time you deploy the algorithm. In a backest, this is the StartDatestart_date of your algorithm. In live trading, it's the current date. Warm Up is a great way to prepare your algorithm and its indicators for trading.

Set Warm Up Periods

You can set a warm-up period based on a period of time or a number of bars. To set a warm-up, in your algorithm's Initializeinitialize method, call the SetWarmUpset_warm_up method.

// Wind time back 7 days from start
SetWarmUp(TimeSpan.FromDays(7));

// Feed in 100 bars before start date
SetWarmUp(100);
# Wind time back 7 days from start
self.set_warm_up(timedelta(7))

# Feed in 100 bars before start date
self.set_warm_up(100)

If you pass a timedeltaTimeSpan argument, the warm-up period consists of that timedeltaTimeSpan before the start date and pipes in data that matches the resolution of your data subscriptions.

If you pass just an integer argument, LEAN calculates the start of the warm-up period for each of your security subscriptions by using the number of bars you specify, the resolution of each security, and the trading calendar of each security. After it calculates the start time of the warm-up period for each security, it sets the earliest start time as the start of the algorithm warm-up period. For instance, in the following example, the warm-up period consists of 100 minute resolution bars for SPY and as many second resolution bars for BTCUSD that occur from the start of the SPY warm-up period to the algorithm StartDatestart_date.

AddEquity("SPY", Resolution.Minute, fillForward: false);
AddCrypto("BTCUSD", Resolution.Second, fillForward: false);
SetWarmUp(100);
self.add_equity("SPY", Resolution.MINUTE, fill_forward=False)
self.add_crypto("BTCUSD", Resolution.SECOND, fill_forward=False)
self.set_warm_up(100)

To use a specific resolution of data for the warm-up period, pass a resolution argument to the SetWarmUpset_warm_up method.

// Feed in 100 days of daily data before the start date
SetWarmUp(TimeSpan.FromDays(100), Resolution.Daily);

// Feed in data for 100 trading days of daily data before the start date
SetWarmUp(100, Resolution.Daily);
# Feed in 100 days of daily data before the start date
self.set_warm_up(timedelta(days=100), Resolution.DAILY)

# Feed in data for 100 trading days before the start date
self.set_warm_up(100, Resolution.DAILY)

If you pass a timedeltaTimeSpan and a resolution, the warm-up period consists of the time period and resolution you set, regardless of the resolution of your data subscriptions.

If you pass an integer and a resolution, the warm-up period consists of the number of bars and resolution you set, regardless of the resolution of your data subscriptions. In this case, LEAN calculates the start of the warm-up period for each of your security subscriptions just like it does when you only pass an integer argument. After it calculates the start time of the warm-up period for each security, it sets the earliest start time as the start of the algorithm warm-up period.

If you pass a resolution argument and you registered indicators or consolidators for automatic updates, the warm-up period resolution must be less than or equal to the lowest resolution of your automatic indicators and consolidators. For instance, in the following example, the indicators use minute resolution data, so you can set the warm-up period to use tick, second, or minute resolution data.

_spy = AddEquity("SPY", Resolution.Minute, fillForward: false).Symbol;
_btc = AddCrypto("BTCUSD", Resolution.Second, fillForward: false).Symbol;

_spySma = SMA(_spy, 10);
_btcSMA = SMA(_btc, 10, Resolution.Minute);

SetWarmUp(100, Resolution.Minute);
self._spy = self.add_equity("SPY", Resolution.MINUTE, fill_forward=False).symbol
self._btc = self.add_crypto("BTCUSD", Resolution.SECOND, fill_forward=False).symbol

self._spy_sma = self.sma(self._spy, 10)
self._btc_sma = self.sma(self._btc, 10, Resolution.MINUTE)

self.set_warm_up(100, Resolution.MINUTE)

Warm Up Vs Reality

You may need to distinguish warm-up data from real data. To check if the algorithm is currently in a warm up period, use the IsWarmingUpis_warming_up property.

// In Initialize
var emaFast = EMA("IBM", 50);
var emaSlow = EMA("IBM", 100);
SetWarmup(100);

// In OnData: Don't run if the indicators aren't ready
if (IsWarmingUp) return;
# In Initialize
self._ema_fast = self.ema("IBM", 50);
self._ema_slow = self.ema("IBM", 100);
self.set_warmup(100);

// In OnData: Don't run if the indicators aren't ready
if self.is_warming_up: return

Event Handler

The OnWarmupFinishedon_warmup_finished event handler executes when the warm up period ends, even if you don't set a warm up period.

public override void OnWarmupFinished()
{
    // Done warming up
}
def on_warmup_finished(self) -> None:
    pass # Done warming up

Limitations

You can't place trades during the warm-up period because they would be operating on fictional fast-forwarded data.

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: