astock-agent/backend/app/data/code_utils.py
2026-05-14 17:02:13 +08:00

55 lines
1.5 KiB
Python

"""股票代码规范化工具。"""
from __future__ import annotations
import re
SUPPORTED_MARKETS = {"SH", "SZ", "BJ"}
def normalize_ts_code(value: str | None) -> str:
"""把常见 A 股代码输入规范成 Tushare 格式。
支持:
- 603779 -> 603779.SH
- 300750 -> 300750.SZ
- 430047 -> 430047.BJ
- sh600519 / sz000001 / bj430047
- 600519.sh -> 600519.SH
"""
text = str(value or "").strip().upper()
if not text:
return ""
compact_match = re.fullmatch(r"(SH|SZ|BJ)(\d{6})", text)
if compact_match:
market, code = compact_match.groups()
return f"{code}.{market}"
dotted_match = re.fullmatch(r"(\d{6})\.(SH|SZ|BJ)", text)
if dotted_match:
code, market = dotted_match.groups()
return f"{code}.{market}"
if re.fullmatch(r"\d{6}", text):
if text.startswith(("6", "9")):
return f"{text}.SH"
if text.startswith(("0", "2", "3")):
return f"{text}.SZ"
if text.startswith(("4", "8")):
return f"{text}.BJ"
return text
def split_ts_code(value: str | None) -> tuple[str, str]:
"""返回 (code, market),无法识别时抛出带上下文的 ValueError。"""
normalized = normalize_ts_code(value)
if "." not in normalized:
raise ValueError(f"无效股票代码格式: {value!r}")
code, market = normalized.split(".", 1)
if not re.fullmatch(r"\d{6}", code) or market not in SUPPORTED_MARKETS:
raise ValueError(f"无效股票代码格式: {value!r}")
return code, market