QuantConnect/Lean · error · AssertionError
SPY tick history is empty
Error message
SPY tick history is empty
What it means
Regression assertion that the SPY tick history dataframe returned by History is not empty. It checks history.shape[0] == 0 after a successful (non-throwing) call. An empty frame means the call succeeded but yielded zero rows — the request was valid yet no data rows were returned.
Source
Thrown at Algorithm.Python/PandasDataFrameFromMultipleTickTypeTickHistoryRegressionAlgorithm.py:39
class PandasDataFrameFromMultipleTickTypeTickHistoryRegressionAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2013, 10, 8)
self.set_end_date(2013, 10, 8)
spy = self.add_equity("SPY", Resolution.MINUTE).symbol
subscriptions = [x for x in self.subscription_manager.subscriptions if x.symbol == spy]
if len(subscriptions) != 2:
raise AssertionError(f"Expected 2 subscriptions, but found {len(subscriptions)}")
history = pd.DataFrame()
try:
history = self.history(Tick, spy, timedelta(days=1), Resolution.TICK)
except Exception as e:
raise AssertionError(f"History call failed: {e}")
if history.shape[0] == 0:
raise AssertionError("SPY tick history is empty")
if not np.array_equal(history.columns.to_numpy(), ['askprice', 'asksize', 'bidprice', 'bidsize', 'exchange', 'lastprice', 'quantity']):
raise AssertionError("Unexpected columns in SPY tick history")
self.quit()
View on GitHub (pinned to d2c3659f87)
Solutions
- Confirm on-disk tick data exists for SPY on 2013-10-08 (a trading day) and the file is non-empty.
- Verify the history window (timedelta(days=1) from start date) overlaps an actual trading session with ticks.
- If data is genuinely absent for that range, widen the window or pick a known-populated date rather than asserting non-empty.
- Check data normalization / exchange-hour filtering is not stripping all rows.
Example fix
# before
if history.shape[0] == 0:
raise AssertionError("SPY tick history is empty")
# after (fall back to a wider window or fail with the queried range)
if history.shape[0] == 0:
history = self.history(Tick, spy, timedelta(days=5), Resolution.TICK)
if history.shape[0] == 0:
raise AssertionError(
f"SPY tick history is empty for window starting {self.start_date}") Defensive patterns
Strategy: validation
Validate before calling
# Check row count and widen the window if empty rather than asserting
history = self.history(Tick, spy, timedelta(days=1), Resolution.TICK)
if history.shape[0] == 0:
history = self.history(Tick, spy, timedelta(days=5), Resolution.TICK)
if history.shape[0] == 0:
self.debug(f"No SPY tick rows for window; data may be missing") Type guard
def history_has_rows(history):
"""True when the returned history frame contains at least one row."""
return history is not None and history.shape[0] > 0 Prevention
- Verify the date window overlaps an actual trading session with tick data.
- Log history.shape[0] before asserting non-empty so gaps are visible.
- Prefer a known-populated date range for tick-history regression tests.
When it happens
Trigger: self.history(Tick, spy, timedelta(days=1), Resolution.TICK) returns a dataframe with zero rows. This happens when the date window contains no tick data (e.g. 2013-10-08 is outside the available data range, a weekend/holiday, or the market was closed), when the symbol's tick data files are empty/missing-but-tolerated, or when filters (exchange hours, data normalization) removed all rows.
Common situations: The backtest date range does not overlap with on-disk tick data for SPY. A data import produced empty tick files. The start/end date fell on a non-trading day. The data reader found the config but the zip/CSV contained no rows for that day.
Related errors
- Expected 2 subscriptions, but found {len(subscriptions)}
- History call failed: {e}
- Unexpected columns in SPY tick history
- Empty history data frame for {symbol}
- _customWarmUp indicator was expected to be ready
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/6fa7eebc31f72f84.
Report an issue: GitHub.