ZhuLinsen/daily_stock_analysis · error · DataFetchError

Yahoo Finance 未查询到 {stock_code} 的数据

Error message

Yahoo Finance 未查询到 {stock_code} 的数据

What it means

YfinanceFetcher downloaded successfully but the resulting DataFrame is empty after column filtering, so the symbol simply has no data on Yahoo Finance. Common with delisted/renamed tickers, unsupported exchanges, or yf_code conversions this repo does for A/HK shares (e.g. 600519 -> 600519.SS, 00700 -> 0700.HK) that Yahoo does not recognize.

Source

Thrown at data_provider/yfinance_fetcher.py:227

            # 使用 yfinance 下载数据
            df = yf.download(
                tickers=yf_code,
                start=start_date,
                end=end_date,
                progress=False,  # 禁止进度条
                auto_adjust=True,  # 自动调整价格(复权)
                multi_level_index=True
            )

            # 筛选出 yf_code 的列, 避免多只股票数据混淆
            if isinstance(df.columns, pd.MultiIndex) and len(df.columns) > 1:
                ticker_level = df.columns.get_level_values(1)
                mask = ticker_level == yf_code
                if mask.any():
                    df = df.loc[:, mask].copy()

            if df.empty:
                raise DataFetchError(f"Yahoo Finance 未查询到 {stock_code} 的数据")

            return df

        except Exception as e:
            if isinstance(e, DataFetchError):
                raise
            raise DataFetchError(f"Yahoo Finance 获取数据失败: {e}") from e

    def _normalize_data(self, df: pd.DataFrame, stock_code: str) -> pd.DataFrame:
        """
        标准化 Yahoo Finance 数据

        yfinance 返回的列名:
        Open, High, Low, Close, Volume(索引是日期)

        注意:新版 yfinance 返回 MultiIndex 列名,如 ('Close', 'AMD')
        需要先扁平化列名再进行处理

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Verify the symbol on finance.yahoo.com exactly as converted (print yf_code before the call).
  2. Check the requested date range actually contains trading sessions for that market.
  3. If the MultiIndex filter emptied the frame, inspect df.columns — a yfinance upgrade may have changed level ordering; adjust the mask or pin the yfinance version.
  4. Route to another fetcher (Tushare for A-shares, Akshare) via the fallback chain when Yahoo has no coverage.

Example fix

# before
df = yf.download('0700.HK', ...)  # wrong digit count for HK -> empty

# after
df = yf.download('0700.HK'.lstrip('0').zfill(4) + '.HK', ...)  # ensure 4-digit HK code
Defensive patterns

Strategy: validation

Validate before calling

import yfinance as yf

t = yf.Ticker(yf_code)
info_keys = set()
try:
    info_keys = set(t.fast_info.keys())
except Exception:
    pass
has_data = bool(info_keys) or not t.history(period="5d").empty
if not has_data:
    raise ValueError(f"Yahoo has no data for {yf_code}; check the symbol")

Type guard

def yahoo_symbol_ok(yf_code: str) -> bool:
    import yfinance as yf
    try:
        return not yf.Ticker(yf_code).history(period="5d").empty
    except Exception:
        return False

Try / catch

try:
    df = yfinance_fetcher.fetch_stock_data(code)
except DataFetchError as e:
    if "未查询到" in str(e):
        df = akshare_fetcher.fetch_stock_data(code)  # symbol not on Yahoo
    else:
        raise

Prevention

When it happens

Trigger: yf.download returns an empty frame for the ticker (bad symbol, delisted, no trading data in the requested window), or the MultiIndex filter drops all columns because the level-1 ticker string does not match yf_code exactly (case or suffix mismatch).

Common situations: Typo'd or delisted US ticker; A-share code converted to the wrong suffix (.SS vs .SZ); HK code format mismatch with Yahoo's 4-digit .HK convention; requesting a date range with no sessions; yfinance version change altering the column layout so the mask filters everything out.

Related errors


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