ZhuLinsen/daily_stock_analysis · warning · DataFetchError

BaostockFetcher 不支持美股 {stock_code},请使用 AkshareFetcher 或 Yfin

Error message

BaostockFetcher 不支持美股 {stock_code},请使用 AkshareFetcher 或 YfinanceFetcher

What it means

A guard DataFetchError raised at the top of BaostockFetcher's fetch path when _is_us_code(stock_code) is True. Baostock covers only mainland A-shares; US tickers are rejected immediately (before code conversion or login) with a message naming the correct sources (Akshare or Yfinance). The intent is for DataFetcherManager to catch it and fall through to a US-capable fetcher.

Source

Thrown at data_provider/baostock_fetcher.py:205

        retry=retry_if_exception_type((ConnectionError, TimeoutError)),
        before_sleep=before_sleep_log(logger, logging.WARNING),
    )
    def _fetch_raw_data(self, stock_code: str, start_date: str, end_date: str) -> pd.DataFrame:
        """
        从 Baostock 获取原始数据
        
        使用 query_history_k_data_plus() 获取日线数据
        
        流程:
        1. 检查是否为美股(不支持)
        2. 使用上下文管理器管理连接
        3. 转换股票代码格式
        4. 调用 API 查询数据
        5. 将结果转换为 DataFrame
        """
        # 美股不支持,抛出异常让 DataFetcherManager 切换到其他数据源
        if _is_us_code(stock_code):
            raise DataFetchError(f"BaostockFetcher 不支持美股 {stock_code},请使用 AkshareFetcher 或 YfinanceFetcher")

        # 港股不支持,抛出异常让 DataFetcherManager 切换到其他数据源
        if _is_hk_market(stock_code):
            raise DataFetchError(f"BaostockFetcher 不支持港股 {stock_code},请使用 AkshareFetcher")

        # 北交所不支持,抛出异常让 DataFetcherManager 切换到其他数据源
        if is_bse_code(stock_code):
            raise DataFetchError(
                f"BaostockFetcher 不支持北交所 {stock_code},将自动切换其他数据源"
            )
        
        # 转换代码格式
        bs_code = self._convert_stock_code(stock_code)
        
        logger.debug(f"调用 Baostock query_history_k_data_plus({bs_code}, {start_date}, {end_date})")
        
        with self._baostock_session() as bs:
            try:

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Dispatch by market before calling: US symbols go to Akshare/Yfinance/AlphaVantage.
  2. If Baostock must stay in a shared chain, keep it behind market-aware sources or accept the fallback cost.
  3. Verify _is_us_code's heuristic covers your symbol format so US codes never reach the login/query stage.

Example fix

# before
df = baostock_fetcher.fetch('AAPL', start, end)  # raises guard

# after
from data_provider.utils import is_us_stock_code
if is_us_stock_code(code):
    df = yfinance_fetcher.fetch(code, start, end)
else:
    df = baostock_fetcher.fetch(code, start, end)
Defensive patterns

Strategy: validation

Validate before calling

from data_provider.utils import is_us_stock_code
if is_us_stock_code(code):
    fetcher = yfinance_fetcher  # US goes here
else:
    fetcher = baostock_fetcher

Type guard

from data_provider.utils import is_us_stock_code

def is_baostock_eligible(code: str) -> bool:
    """False for US codes Baostock rejects at its entry guard."""
    return not is_us_stock_code(code)

Try / catch

try:
    df = baostock_fetcher.fetch(code, start, end)
except DataFetchError as e:
    if '不支持美股' in str(e):
        df = yfinance_fetcher.fetch(code, start, end)
    else:
        raise

Prevention

When it happens

Trigger: Passing US tickers ('AAPL', 'AMD', 'TSLA') to BaostockFetcher.fetch — typically because Baostock is early in the source priority list and the code format (bare uppercase letters) matches _is_us_code. No network call is made; the raise is deterministic.

Common situations: Single default fetcher used for a multi-market watchlist; US ticker with digits (e.g. some tickers) that the heuristic may or may not catch; testing with mixed symbols against one fetcher.

Related errors


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