ZhuLinsen/daily_stock_analysis · error · DataFetchError
无法识别港股代码 {raw_code}
Error message
无法识别港股代码 {raw_code} What it means
DataFetchError raised in the HK branch of TushareFetcher code normalization when an HK-market code contains no digits after stripping non-digit characters (re.sub(r'\D', '', raw_code) is empty). The fetcher needs a numeric HK code to build the 5-digit .HK ts_code, so codes like 'hk', '.HK', or 'hk.XY' are rejected.
Source
Thrown at data_provider/tushare_fetcher.py:459
def _convert_hk_stock_code_for_tushare(self, stock_code: str) -> str:
"""
将用户输入转为 Tushare Pro 接口所需的 ts_code(含港股 nnnnn.HK)。
- 非港股:委托 _convert_stock_code(A 股 / ETF / 北交所等)。
- 港股:从 HK00700、00700、00700.HK 等形式归一为 5 位数字 + .HK。
"""
raw_code = stock_code.strip()
if _is_hk_market(raw_code):
if "." in raw_code:
ts_code = raw_code.upper()
if ts_code.endswith(".SS"):
return f"{ts_code[:-3]}.SH"
if ts_code.endswith(".HK"):
return ts_code
digits = re.sub(r"\D", "", raw_code)
if not digits:
raise DataFetchError(f"无法识别港股代码 {raw_code}")
code = digits[-5:].rjust(5, "0")
return f"{code}.HK"
return self._convert_stock_code(stock_code)
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=30),
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:
"""
从 Tushare 获取原始数据
根据代码类型选择不同接口:
- 普通股票:daily()
- ETF 基金:fund_daily()
View on GitHub (pinned to 5159bd72e8)
Solutions
- Fix the upstream code construction so HK codes always carry the numeric part (e.g. '00700', 'hk00700', '00700.HK').
- Validate user/watchlist input with a regex like ^\D*(\d{1,5})\D*$ before it reaches the fetcher.
- Reject or quarantine malformed codes at ingestion instead of letting them hit the provider layer.
Example fix
# before
raw = "hk." # matched as HK market, no digits -> DataFetchError
code = tushare_fetcher._convert_stock_code(raw)
# after
import re
m = re.search(r"(\d{1,6})", raw)
if m:
code = m.group(1)[-5:].rjust(5, "0") + ".HK" # safe to pass on
else:
raise ValueError(f"invalid HK code: {raw!r}") # fail at ingestion with clear input error Defensive patterns
Strategy: validation
Validate before calling
import re
def valid_hk_code(raw: str) -> bool:
"""HK codes must contain at least one digit to be normalizable."""
return bool(re.search(r"\d", raw))
if _is_hk_market(raw) and not valid_hk_code(raw):
raise ValueError(f"malformed HK code: {raw!r}") # reject at ingestion Type guard
import re
def has_hk_digits(code: str) -> bool:
"""True when an HK-market code carries a numeric part."""
return bool(re.search(r"\d", code)) Try / catch
try:
ts_code = tushare_fetcher._convert_stock_code(raw)
except DataFetchError as e:
if "无法识别港股代码" in str(e):
raise ValueError(f"bad HK code from upstream: {raw!r}") from e # surface as input error
raise Prevention
- Validate watchlist/bot input codes with a digit-containing regex before provider calls.
- Fix upstream code parsing that can emit prefix-only strings like 'hk.' or '.HK'.
- Reject malformed codes at ingestion with a clear message instead of deep provider errors.
When it happens
Trigger: Passing a code matched by _is_hk_market that has no digits at all, e.g. 'hk', 'HK.', '.hk', or codes whose only content is a market prefix/suffix.
Common situations: Upstream parsing splitting 'hk00700' into prefix and empty body; watchlist typos; programmatic construction of codes producing prefix-only strings; malformed user input in bot commands.
Related errors
- TUSHARE_HTTP_URL 必须以 http:// 或 https:// 开头,当前值为 {url!r}
- Backend executable not found: ${backendPath}
- Invalid share image record ID
- Desktop backend URL is unavailable
- Desktop backend origin is invalid
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/c852b61566b30e1d.
Report an issue: GitHub.