{"record":{"id":"b0d2bf2be2fcdc84","repo":"QuantConnect/Lean","slug":"empty-history-data-frame-for-symbol","errorCode":null,"errorMessage":"Empty history data frame for {symbol}","messagePattern":"Empty history data frame for (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/PandasDataFrameHistoryAlgorithm.py","lineNumber":97,"sourceCode":"\n        # we can loop over the return value from these functions and we get TradeBars\n        # we can use these TradeBars to initialize indicators or perform other math\n        self.spy_daily_sma.reset()\n        for index, trade_bar in trade_bar_history.loc[\"SPY\"].iterrows():\n            self.spy_daily_sma.update(index, trade_bar[\"close\"])\n\n        # we can loop over the return values from these functions and we'll get Quandl data\n        # this can be used in much the same way as the trade_bar_history above\n        self.spy_daily_sma.reset()\n        for index, quandl in quandl_history.loc[\"CHRIS/CME_SP1\"].iterrows():\n            self.spy_daily_sma.update(index, quandl[\"settle\"])\n\n        self.set_holdings(self.eur, 1)\n\n    def assert_history_index(self, df, column, expected, ticker, symbol):\n\n        if df.empty:\n            raise AssertionError(f\"Empty history data frame for {symbol}\")\n        if column not in df:\n            raise AssertionError(f\"Could not unstack df. Columns: {', '.join(df.columns)} | {column}\")\n\n        value = df.iat[0,0]\n        df2 = df.xs(df.index.get_level_values('time')[0], level='time')\n        df3 = df[column].unstack(level=0)\n\n        try:\n\n            # str(Symbol.ID)\n            self.assert_history_count(f\"df.iloc[0]\", df.iloc[0], len(df.columns))\n            self.assert_history_count(f\"df.loc[str({symbol.id})]\", df.loc[str(symbol.id)], expected)\n            self.assert_history_count(f\"df.xs(str({symbol.id}))\", df.xs(str(symbol.id)), expected)\n            self.assert_history_count(f\"df.at[(str({symbol.id}),), '{column}']\", list(df.at[(str(symbol.id),), column]), expected)\n            self.assert_history_count(f\"df2.loc[str({symbol.id})]\", df2.loc[str(symbol.id)], len(df2.columns))\n            self.assert_history_count(f\"df3[str({symbol.id})]\", df3[str(symbol.id)], expected)\n            self.assert_history_count(f\"df3.get(str({symbol.id}))\", df3.get(str(symbol.id)), expected)\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/PandasDataFrameHistoryAlgorithm.py#L79-L115","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ndef assert_history_index(self, df, column, expected, ticker, symbol):\n    if df.empty:\n        raise AssertionError(f\"Empty history data frame for {symbol}\")\n\n# after (report the request context that produced the empty frame)\ndef assert_history_index(self, df, column, expected, ticker, symbol):\n    if df.empty:\n        raise AssertionError(\n            f\"Empty history data frame for {symbol} ({ticker}); \"\n            f\"requested range may lack data\")","handlingStrategy":"validation","validationCode":"# Guard the helper against empty frames before indexing\ndef assert_history_index(self, df, column, expected, ticker, symbol):\n    if df is None or df.empty:\n        self.debug(f\"Empty history for {symbol}; skipping index assertion\")\n        return","typeGuard":"def history_frame_usable(df):\n    \"\"\"True when the frame is non-empty and safe to index.\"\"\"\n    return df is not None and not df.empty and len(df.columns) > 0","tryCatchPattern":null,"preventionTips":["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."],"tags":["quantconnect","lean","history","pandas","empty-data","custom-data","python"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}