ZhuLinsen/daily_stock_analysis · error · DataFetchError

[Finnhub] No data returned for {symbol}

Error message

[Finnhub] No data returned for {symbol}

What it means

Finnhub answered HTTP 200 but the candle payload is unusable: status field 's' != 'ok' or the close array 'c' is empty/missing. Finnhub uses s='no_data' for valid symbols with no bars in range and s can reflect invalid symbols too, so this covers both 'no coverage' and 'wrong window'.

Source

Thrown at data_provider/finnhub_fetcher.py:69

        url = f"{_FINNHUB_BASE_URL}/stock/candle"
        params = {
            'symbol': symbol,
            'resolution': 'D',
            'from': start_ts,
            'to': end_ts,
            'token': self._api_key,
        }

        try:
            self.random_sleep(0.3, 0.8)
            resp = requests.get(url, params=params, timeout=15)
            resp.raise_for_status()
            data = resp.json()
        except Exception as e:
            raise DataFetchError(f"[Finnhub] HTTP request failed for {symbol}: {e}") from e

        if data.get('s') != 'ok' or not data.get('c'):
            raise DataFetchError(f"[Finnhub] No data returned for {symbol}")

        return pd.DataFrame({
            'c': data['c'],
            'h': data['h'],
            'l': data['l'],
            'o': data['o'],
            't': data['t'],
            'v': data['v'],
        })

    def _normalize_data(self, df: pd.DataFrame, stock_code: str) -> pd.DataFrame:
        if df.empty:
            return df

        df = df.copy()
        df['date'] = pd.to_datetime(df['t'], unit='s').dt.date
        df = df.rename(columns={
            'o': 'open', 'h': 'high', 'l': 'low',

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Shift start/end dates into the symbol's actual trading history (e.g. after IPO date) and retry.
  2. Verify the symbol on finnhub.com — delisted or unsupported tickers yield no_data permanently; route those to Yfinance.
  3. Fail over via DataFetcherManager to the next US source for this symbol rather than retrying the same window blindly.
Defensive patterns

Strategy: fallback

Validate before calling

# confirm the symbol has bars in the window before calling
# e.g. check listing date from a metadata source, or just widen window:
df = finnhub.get_daily_data(symbol, start='1990-01-01', end=today)  # probe once

Try / catch

try:
    df = finnhub.get_daily_data(symbol, start, end)
except DataFetchError as e:
    if 'No data returned' in str(e):
        df = manager.get_daily_data(symbol, start, end)  # Yfinance usually covers it

Prevention

When it happens

Trigger: GET /stock/candle where from/to window predates the symbol's listing, the symbol is delisted/misspelled, or free-tier restrictions exclude it (some tickers/IPOs). Finnhub returns s='no_data' with empty arrays.

Common situations: See trigger scenarios.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/9d9c267ae220e31f. Report an issue: GitHub.