Bug Report: Backtest silently executes a ~1-day window ~90 days before "today" instead of the configured date range
Summary
When running a backtest with set_start_date(2026, 6, 15) and set_end_date(2026, 8, 6), the algorithm's initialize() correctly registers this date range (confirmed via logging self.start_date / self.end_date immediately after configuration). However, the actual simulation never runs in this window. Instead, on_data fires (or fails to fire) only within a single day located approximately 90 days before the real-world date the backtest was run on — and this "phantom" date shifts forward by roughly one day for each day that passes in real time, tracking the current calendar date rather than the configured backtest range.
This has been reproduced across multiple separate projects (ruling out a project-level cache issue) and across three different LEAN Engine build numbers (2.5.0.0.18035, .18036, .18041), so it does not appear to be tied to one specific engine build either.
Account / Project details
- Account: Free tier, organization "FREE"
- Projects tested: "Larping Fred" (original) and a newly created second project (same result)
- Asset: MES (Micro E-mini S&P 500), via Futures.Indices.MICRO_SP_500_E_MINI
- Dataset: US Futures by AlgoSeek (confirmed via self.history() that price data for the requested June–August 2026 range genuinely exists — see evidence below)
Minimal reproduction code
from AlgorithmImports import *
class DebugScheduledCheck(QCAlgorithm):
def initialize(self):
self.set_start_date(2026, 6, 15)
self.set_end_date(2026, 8, 6)
self.set_cash(10000)
future = self.add_future(Futures.Indices.MICRO_SP_500_E_MINI, Resolution.MINUTE)
future.set_filter(0, 90)
self.future_symbol = future.symbol
self.log(f"INIT: start={self.start_date}, end={self.end_date}")
self.first_time = None
self.last_time = None
self.data_call_count = 0
def on_data(self, slice: Slice):
self.data_call_count += 1
if self.first_time is None:
self.first_time = self.time
self.log(f"FIRST on_data call at: {self.time}")
self.last_time = self.time
def on_end_of_algorithm(self):
self.log(f"LAST on_data call at: {self.last_time}")
self.log(f"Total on_data calls: {self.data_call_count}")
self.log(f"Configured range was: {self.start_date} to {self.end_date}")
Evidence: the "phantom date" tracks the real calendar date, not the configured range
Across multiple runs on different real-world dates, the actual simulated window was always ~90 days before "today", regardless of the code:
Run date (approx.)INIT log (correct)Actual simulated day (from on_data/log timestamps)Days before run date~Aug 18start=2026-06-15, end=2026-08-062026-05-25 to 2026-05-26~90~Aug 24start=2026-06-15, end=2026-08-062026-05-28 to 2026-05-29~90~Aug 25start=2026-06-15, end=2026-08-062026-05-29 to 2026-05-30~90Aug 29start=2026-06-15, end=2026-08-062026-05-31 (0 on_data calls, only 15 data points processed)~90Sample log output from the most recent run (Aug 29):
2026-05-31 00:00:00 : Launching analysis ... with LEAN Engine v2.5.0.0.18041
2026-06-15 00:00:00 : INIT: start=2026-06-15 00:00:00, end=2026-08-06 23:59:59.999999
2026-05-31 13:31:00 : LAST on_data call at: None
2026-05-31 13:31:00 : Total on_data calls: 0
2026-05-31 13:31:00 : Configured range was: 2026-05-31 00:00:00 to 2026-05-31 23:59:59.999999
2026-05-31 13:31:00 : Algorithm completed ... Processing total of 15 data points.
Note the final log line: self.start_date/self.end_date, when read again in on_end_of_algorithm(), now report 2026-05-31 to 2026-05-31 — different from what was logged in initialize() moments earlier in the same run. This strongly suggests the engine is silently overwriting/clamping the configured date range at some point during execution, rather than a data-availability issue.
What has already been ruled out
- Data not available for the target period: Ruled out — a direct self.history(self.future_symbol, start, end, Resolution.MINUTE) call for the June 2026 range returns real price data (500 bars) with plausible fields (askclose, volume, etc.).
- Free-tier date-range restriction: Not documented anywhere in the pricing/docs (the free "B-MICRO" backtesting node is documented as having only a 20-second start delay and 200 backtests/day limit — no stated date restriction).
- Payment wall for futures data: Ruled out per the official AlgoSeek US Futures pricing page (free cloud access to the most popular US futures for backtest/research).
- Project-level cache issue: Ruled out — reproduced in a brand-new project with the same code, not just the original "Larping Fred" project.
- Browser/UI caching of an old backtest result: Ruled out — each run produces a distinct Algorithm Id, and the "Backtest Project" button (not a Debug/preview mode) was confirmed to be the one used.
- Incorrect date configuration in code: Ruled out — INIT logging confirms self.start_date/self.end_date are correctly set to the intended range immediately after set_start_date/set_end_date.
Working hypothesis
There appears to be an undocumented rolling-window limitation (~90 days) affecting backtest execution for Futures data on the free tier — possibly related to how continuous/canonical future contract data is served during actual simulation (as opposed to self.history() calls, which do return correct data for the full requested range). The date window silently clamps to a ~90-day-old single day rather than raising an error.
Request
Could you please confirm whether:
- There is an undocumented data/backtest window restriction for Futures (specifically MES / AlgoSeek US Futures) on the free tier, and
- Why self.start_date/self.end_date would report a different value in on_end_of_algorithm() than what was logged in initialize() within the same run.
Happy to provide the full project code, additional logs, or grant temporary access if that helps investigate.
Frederik Degen
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!