ZhuLinsen/daily_stock_analysis · warning · DataFetchError
EfinanceFetcher 不支持港股日线 {stock_code},请使用 AkshareFetcher 或其他港
Error message
EfinanceFetcher 不支持港股日线 {stock_code},请使用 AkshareFetcher 或其他港股数据源 What it means
Intentional capability guard in EfinanceFetcher._fetch_raw_data: efinance's history K-line endpoint can return wrong-market data for HK codes, so港股 codes are rejected upfront and delegated to AkShare/Tushare/YFinance/Longbridge. Deliberate correctness protection, not a bug.
Source
Thrown at data_provider/efinance_fetcher.py:386
- 美股:不支持,抛出异常让 DataFetcherManager 切换到其他数据源
- 普通股票:使用 ef.stock.get_quote_history()
- ETF 基金:使用 ef.stock.get_quote_history()(ETF 是交易所证券,使用股票 K 线接口)
流程:
1. 判断代码类型(美股/股票/ETF)
2. 设置随机 User-Agent
3. 执行速率限制(随机休眠)
4. 调用对应的 efinance API
5. 处理返回数据
"""
# 美股不支持,抛出异常让 DataFetcherManager 切换到 AkshareFetcher/YfinanceFetcher
if _is_us_code(stock_code):
raise DataFetchError(f"EfinanceFetcher 不支持美股 {stock_code},请使用 AkshareFetcher 或 YfinanceFetcher")
# efinance 的历史 K 线接口在港股代码上可能返回非预期市场数据,
# 明确跳过并交给 AkShare/Tushare/YFinance/Longbridge 等港股路径兜底。
if _is_hk_market(stock_code):
raise DataFetchError(f"EfinanceFetcher 不支持港股日线 {stock_code},请使用 AkshareFetcher 或其他港股数据源")
# 根据代码类型选择不同的获取方法
if _is_etf_code(stock_code):
return self._fetch_etf_data(stock_code, start_date, end_date)
else:
return self._fetch_stock_data(stock_code, start_date, end_date)
def _fetch_stock_data(self, stock_code: str, start_date: str, end_date: str) -> pd.DataFrame:
"""
获取普通 A 股历史数据
数据来源:ef.stock.get_quote_history()
API 参数说明:
- stock_codes: 股票代码
- beg: 开始日期,格式 'YYYYMMDD'
- end: 结束日期,格式 'YYYYMMDD'
- klt: 周期,101=日线View on GitHub (pinned to 5159bd72e8)
Solutions
- Use DataFetcherManager.get_daily_data for HK codes so the HK-capable chain handles them.
- When calling fetchers directly, skip EfinanceFetcher for _is_hk_market codes.
- Catch and treat as 'source skipped', continuing the failover chain — the message itself names the替代 sources.
Example fix
# before
fetcher = EfinanceFetcher()
df = fetcher.get_daily_data('hk00700', ...) # raises
# after
from data_provider.base import get_fetcher_manager
df = get_fetcher_manager().get_daily_data('hk00700', ...) Defensive patterns
Strategy: validation
Validate before calling
from data_provider.efinance_fetcher import _is_hk_market
if _is_hk_market(code):
df = manager.get_daily_data(code, ...) # HK-capable chain
else:
df = efinance_fetcher.get_daily_data(code, ...) Type guard
def is_hk_ticker(code: str) -> bool:
return _is_hk_market(code) Try / catch
try:
df = fetcher.get_daily_data(code, ...)
except DataFetchError as e:
if '不支持港股' in str(e):
continue # intentional skip for correctness Prevention
- Never send HK codes to efinance's K-line endpoint — it can silently return wrong-market data.
- Centralize market detection and reuse the same predicates the fetchers use.
- Alert if HK codes appear in the EfinanceFetcher call path; that's a routing bug.
When it happens
Trigger: Calling EfinanceFetcher directly with an HK code (e.g. 'hk00700' / '00700.HK' matched by _is_hk_market); via the manager this is pre-filtered by _filter_daily_fetchers_for_market(market='hk').
Common situations: Direct fetcher iteration over mixed A-share/HK watchlists; tests that probe every fetcher with every market's codes.
Related errors
- EfinanceFetcher 不支持美股 {stock_code},请使用 AkshareFetcher 或 Yfin
- Akshare 获取港股数据失败: {e}
- BaostockFetcher 不支持港股 {raw_code},请使用 AkshareFetcher
- BaostockFetcher 不支持港股 {stock_code},请使用 AkshareFetcher
- [{self.name}] 未获取到 {stock_code} 的数据
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/0ad2fd616668833a.
Report an issue: GitHub.