ZhuLinsen/daily_stock_analysis · warning · DataFetchError
AkshareFetcher 不支持美股 {stock_code},请使用 YfinanceFetcher 获取正确的复
Error message
AkshareFetcher 不支持美股 {stock_code},请使用 YfinanceFetcher 获取正确的复权价格 What it means
DataFetchError raised deliberately by AkshareFetcher when asked for a US stock: akshare's stock_us_daily has a known adjusted-price defect (akshare Issue #311), so the fetcher refuses US codes and instructs the caller to use YfinanceFetcher instead. This is a routing guard, not an incidental failure.
Source
Thrown at data_provider/akshare_fetcher.py:486
根据代码类型自动选择 API:
- 美股:不支持,抛出异常由 YfinanceFetcher 处理(Issue #311)
- 港股:使用 ak.stock_hk_hist()
- ETF 基金:使用 ak.fund_etf_hist_em()
- 普通 A 股:使用 ak.stock_zh_a_hist()
流程:
1. 判断代码类型(美股/港股/ETF/A股)
2. 设置随机 User-Agent
3. 执行速率限制(随机休眠)
4. 调用对应的 akshare API
5. 处理返回数据
"""
# 根据代码类型选择不同的获取方法
if _is_us_code(stock_code):
# 美股:akshare 的 stock_us_daily 接口复权存在已知问题(参见 Issue #311)
# 交由 YfinanceFetcher 处理,确保复权价格一致
raise DataFetchError(
f"AkshareFetcher 不支持美股 {stock_code},请使用 YfinanceFetcher 获取正确的复权价格"
)
elif _is_hk_code(stock_code):
return self._fetch_hk_data(stock_code, start_date, end_date)
elif _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 股历史数据
策略:
1. 优先尝试东方财富接口 (ak.stock_zh_a_hist)
2. 失败后尝试新浪财经接口 (ak.stock_zh_a_daily)
3. 最后尝试腾讯财经接口 (ak.stock_zh_a_hist_tx)
"""View on GitHub (pinned to 5159bd72e8)
Solutions
- Use YfinanceFetcher for US stocks — it returns correctly adjusted prices.
- If you use the repo's data provider facade, ensure codes are routed by market (A/HK/ETF -> akshare, US -> yfinance).
- Catch DataFetchError with this message as a signal to reroute rather than retry.
- Do not attempt to bypass by stripping the US check — the underlying akshare data is known-bad for this case.
Example fix
# before
fetcher = AkshareFetcher()
df = fetcher.fetch_stock_data('AAPL', '2024-01-01', '2024-12-31') # raises
# after
from data_provider.yfinance_fetcher import YfinanceFetcher
df = YfinanceFetcher().fetch_stock_data('AAPL', '2024-01-01', '2024-12-31') Defensive patterns
Strategy: validation
Validate before calling
def pick_fetcher(stock_code: str):
import re
if re.fullmatch(r'[A-Z]{1,5}', stock_code.strip().upper()):
return YfinanceFetcher() # US codes -> yfinance
return AkshareFetcher() # A-share/HK/ETF -> akshare
fetcher = pick_fetcher('AAPL') Type guard
from data_provider.exceptions import DataFetchError
def is_us_unsupported_by_akshare(exc: Exception) -> bool:
return isinstance(exc, DataFetchError) and '请使用 YfinanceFetcher' in str(exc) Try / catch
try:
df = akshare_fetcher.fetch_stock_data(code, start, end)
except DataFetchError as e:
if '请使用 YfinanceFetcher' in str(e):
df = yfinance_fetcher.fetch_stock_data(code, start, end) # reroute, don't retry akshare
else:
raise Prevention
- Route fetchers by market classification before calling (US -> yfinance).
- Never bypass the US-code guard — akshare US adjusted prices are known-bad (akshare #311).
- Centralize market detection (_is_us_code/_is_hk_code/_is_etf_code) so all call sites share one routing rule.
When it happens
Trigger: Calling AkshareFetcher.fetch_stock_data (directly or via a data provider that doesn't route by market) with a US code such as 'AAPL', 'AMD', 'TSLA' — detected by _is_us_code(stock_code).
Common situations: Custom scripts or provider configurations that hardcode AkshareFetcher as the single source for all markets; new multi-market support added without per-market fetcher routing; accidentally passing a US ticker to an A-share pipeline.
Related errors
- Akshare 获取美股数据失败: {e}
- {call_name} 调用超过 {wait_seconds:g}s,已放弃等待
- {call_name} 调用进程未返回结果
- Akshare 所有渠道获取失败: {last_error}
- Akshare(EM) 可能被限流: {e}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/e8d96623878ccaf5.
Report an issue: GitHub.