36 lines
1.3 KiB
Python
36 lines
1.3 KiB
Python
"""A 股代码归一化。支持 6 位纯数字或带交易所后缀(000001 / 000001.SZ)。"""
|
||
from __future__ import annotations
|
||
|
||
# 场内 ETF 代码前缀(与股票区间不重叠):沪 51/56/58 开头、深 159 开头。
|
||
# 50/57/16 开头是 LOF,不在此列。
|
||
_ETF_PREFIXES = ("51", "56", "58", "159")
|
||
|
||
|
||
def plain_code(code: str) -> str:
|
||
"""000001.SZ -> 000001"""
|
||
return code.strip().upper().split(".")[0]
|
||
|
||
|
||
def is_etf_symbol(code: str) -> bool:
|
||
"""按 6 位纯代码前缀判断是否场内 ETF(fetcher 据此路由到东财数据源)。"""
|
||
c = plain_code(code)
|
||
return len(c) == 6 and c.startswith(_ETF_PREFIXES)
|
||
|
||
|
||
def to_ts_code(code: str) -> str:
|
||
"""转 Tushare ts_code(带交易所后缀)。"""
|
||
c = code.strip().upper()
|
||
if "." in c:
|
||
return c
|
||
c = plain_code(c)
|
||
# 沪市:60xxxx 主板、68xxxx 科创、9xxxxx B 股、5xxxxx 基金(51/56/58 场内 ETF)
|
||
if c.startswith(("60", "68", "9", "51", "56", "58")):
|
||
return c + ".SH"
|
||
# 深市:00xxxx 主板/中小、30xxxx 创业、20xxxx B 股、159xxx 场内 ETF
|
||
if c.startswith(("00", "30", "20", "159")):
|
||
return c + ".SZ"
|
||
# 北交所:8xxxxx / 4xxxxx
|
||
if c.startswith(("8", "4")):
|
||
return c + ".BJ"
|
||
return c + ".SZ"
|