ZhuLinsen/daily_stock_analysis · error · DataFetchError
无法确定 ETF {stock_code} 的 Eastmoney 市场前缀
Error message
无法确定 ETF {stock_code} 的 Eastmoney 市场前缀 What it means
Raised by _build_eastmoney_etf_secid when the code passes _is_etf_code but starts with neither _ETF_SH_PREFIXES nor _ETF_SZ_PREFIXES, so the Eastmoney market digit ('1.' for SH, '0.' for SZ) cannot be chosen. Means the ETF classifier and the prefix whitelist disagree.
Source
Thrown at data_provider/efinance_fetcher.py:178
Args:
stock_code: 股票/基金代码
Returns:
True 表示是 ETF 代码,False 表示是普通股票代码
"""
return _is_a_share_etf_code(stock_code)
def _build_eastmoney_etf_secid(stock_code: str) -> str:
"""Build Eastmoney secid for A-share ETF historical K-line queries."""
code = normalize_stock_code(stock_code)
if not _is_etf_code(code):
raise DataFetchError(f"无法识别 ETF 代码 {stock_code}")
if code.startswith(_ETF_SH_PREFIXES):
return f"1.{code}"
if code.startswith(_ETF_SZ_PREFIXES):
return f"0.{code}"
raise DataFetchError(f"无法确定 ETF {stock_code} 的 Eastmoney 市场前缀")
def _is_us_code(stock_code: str) -> bool:
"""
判断代码是否为美股
美股代码规则:
- 1-5个大写字母,如 'AAPL', 'TSLA'
- 可能包含 '.',如 'BRK.B'
"""
code = stock_code.strip().upper()
return bool(re.match(r'^[A-Z]{1,5}(\.[A-Z])?$', code))
def _ef_call_with_timeout(func, *args, timeout=None, **kwargs):
"""Run an efinance library call in a thread with a timeout.
efinance internally uses requests/urllib3 with no timeout, so whenView on GitHub (pinned to 5159bd72e8)
Solutions
- Confirm the code's actual exchange (SSE vs SZSE) from the fund's official page, then check it against _ETF_SH_PREFIXES/_ETF_SZ_PREFIXES in efinance_fetcher.py.
- Add the missing prefix to the correct tuple (with a regression test using the real code).
- If the code is not A-share, route it to the correct market fetcher instead of EfinanceFetcher's ETF path.
Example fix
# before
_ETF_SH_PREFIXES = ('51', '56', '58')
# after (new SSE ETF series)
_ETF_SH_PREFIXES = ('51', '56', '58', '60') Defensive patterns
Strategy: validation
Validate before calling
from data_provider.efinance_fetcher import _ETF_SH_PREFIXES, _ETF_SZ_PREFIXES
code = normalize_stock_code(code)
if not (code.startswith(_ETF_SH_PREFIXES) or code.startswith(_ETF_SZ_PREFIXES)):
raise ValueError(f'{code}: unknown ETF market prefix — extend prefix lists') Type guard
def has_known_etf_prefix(code: str) -> bool:
c = normalize_stock_code(code)
return c.startswith(_ETF_SH_PREFIXES) or c.startswith(_ETF_SZ_PREFIXES) Prevention
- Keep _ETF_SH_PREFIXES/_ETF_SZ_PREFIXES in one place and test against real listed ETF codes.
- When an exchange announces a new ETF series, add the prefix with a regression test.
- Log unknown prefixes with the raw code so gaps surface in operations.
When it happens
Trigger: An A-share ETF code whose first digits fall outside the known SH/SZ ETF prefix ranges reaches the secid builder — new exchange prefix, LOF (16 is SZ so fine, but e.g. 50xxxx SH LOF variants), or an outdated prefix list.
Common situations: Exchange lists a new ETF series with an unseen prefix; the repo's prefix constants lag behind the market; user-supplied code from another market slipped through classification.
Related errors
- 无法识别 ETF 代码 {stock_code}
- efinance 获取 ETF 数据失败: {failure_message}
- Akshare 可能被限流: {e}
- Akshare 获取 ETF 数据失败: {e}
- [AlphaVantage] API key not configured
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/9f5536ea0c88de0b.
Report an issue: GitHub.