QuantConnect/Lean · error · AssertionError
Empty history data frame for {symbol}
Error message
Empty history data frame for {symbol} What it means
Guard at the top of assert_history_index that the passed history dataframe is non-empty before indexing into it. The helper does df.iat[0,0], df.xs(...), and df.unstack(...) which all require at least one row. The assertion fires when a History call returned an empty frame for a symbol, so subsequent indexing would fail with a less clear error.
Source
Thrown at Algorithm.Python/PandasDataFrameHistoryAlgorithm.py:97
# we can loop over the return value from these functions and we get TradeBars
# we can use these TradeBars to initialize indicators or perform other math
self.spy_daily_sma.reset()
for index, trade_bar in trade_bar_history.loc["SPY"].iterrows():
self.spy_daily_sma.update(index, trade_bar["close"])
# we can loop over the return values from these functions and we'll get Quandl data
# this can be used in much the same way as the trade_bar_history above
self.spy_daily_sma.reset()
for index, quandl in quandl_history.loc["CHRIS/CME_SP1"].iterrows():
self.spy_daily_sma.update(index, quandl["settle"])
self.set_holdings(self.eur, 1)
def assert_history_index(self, df, column, expected, ticker, symbol):
if df.empty:
raise AssertionError(f"Empty history data frame for {symbol}")
if column not in df:
raise AssertionError(f"Could not unstack df. Columns: {', '.join(df.columns)} | {column}")
value = df.iat[0,0]
df2 = df.xs(df.index.get_level_values('time')[0], level='time')
df3 = df[column].unstack(level=0)
try:
# str(Symbol.ID)
self.assert_history_count(f"df.iloc[0]", df.iloc[0], len(df.columns))
self.assert_history_count(f"df.loc[str({symbol.id})]", df.loc[str(symbol.id)], expected)
self.assert_history_count(f"df.xs(str({symbol.id}))", df.xs(str(symbol.id)), expected)
self.assert_history_count(f"df.at[(str({symbol.id}),), '{column}']", list(df.at[(str(symbol.id),), column]), expected)
self.assert_history_count(f"df2.loc[str({symbol.id})]", df2.loc[str(symbol.id)], len(df2.columns))
self.assert_history_count(f"df3[str({symbol.id})]", df3[str(symbol.id)], expected)
self.assert_history_count(f"df3.get(str({symbol.id}))", df3.get(str(symbol.id)), expected)
View on GitHub (pinned to d2c3659f87)
Solutions
- Before calling assert_history_index, verify the History result is non-empty for that symbol and, if empty, skip or fail with a clearer upstream message.
- Confirm the symbol's data files exist and are non-empty for the requested range.
- Ensure the correct data type/resolution is requested for the symbol (e.g. custom data vs equity bars).
- Widen the date window or pick a known-populated range for that data source.
Example fix
# before
def assert_history_index(self, df, column, expected, ticker, symbol):
if df.empty:
raise AssertionError(f"Empty history data frame for {symbol}")
# after (report the request context that produced the empty frame)
def assert_history_index(self, df, column, expected, ticker, symbol):
if df.empty:
raise AssertionError(
f"Empty history data frame for {symbol} ({ticker}); "
f"requested range may lack data") Defensive patterns
Strategy: validation
Validate before calling
# Guard the helper against empty frames before indexing
def assert_history_index(self, df, column, expected, ticker, symbol):
if df is None or df.empty:
self.debug(f"Empty history for {symbol}; skipping index assertion")
return Type guard
def history_frame_usable(df):
"""True when the frame is non-empty and safe to index."""
return df is not None and not df.empty and len(df.columns) > 0 Prevention
- Confirm data files exist and are non-empty for the symbol/range before asserting non-empty.
- Request the correct data type/resolution for the symbol.
- Skip index assertions for symbols whose data is known to be sparse.
When it happens
Trigger: assert_history_index is called with a dataframe where df.empty is True. This means the upstream History(...) request for that symbol/type returned no rows — e.g. no data on disk for the symbol/date range, the data type (Quandl/custom) had no rows, or the symbol's history was filtered out by exchange hours/normalization.
Common situations: A custom/Quandl data source produced no rows for the requested window. The symbol's data files are missing or empty for the backtest range. The history request used a resolution/data type the symbol does not support, yielding an empty frame. A date range falls entirely outside the symbol's available data.
Related errors
- Could not unstack df. Columns: {', '.join(df.columns)} | {co
- History call failed: {e}
- SPY tick history is empty
- Unexpected columns in SPY tick history
- {symbols}, {symbol.id}, {symbol}, {ticker}. {e}
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/b0d2bf2be2fcdc84.
Report an issue: GitHub.