A 股代码后缀 .SH/.SZ/.BJ 怎么区分?Python 怎么统一处理沪深京港美股代码?

7 阅读5分钟

一句话回答: A 股用「6 位数字 + 交易所后缀」唯一标识一只证券:600519.SH(上交所)、000001.SZ(深交所)、920819.BJ(北交所),港股是 00700.HK、美股是 AAPL.US。与其自己维护一套「6 开头=沪市」的易错规则,不如用 AlphaFeed 的 instruments 直接拿回已解析好的 code(纯数字)、exchange(交易所)、region(市场归属)、type(品种),代码格式判断和跨市场统一一步到位。

为什么会有这个问题 / 传统做法的痛点

同一只股票在不同数据源里写法五花八门:sh600519、600519.SS、600519.XSHG、600519.SH……拼错一个后缀就取不到数据。很多人靠「6 开头是沪市、0/3 开头是深市、8/4/9 开头是北交所」的经验规则手写判断,但这套规则有一堆例外(688 科创板、300 创业板、ETF、可转债、退市整理),一旦市场规则调整就默默出错。更稳的做法是:把「代码属于哪个市场」交给数据源解析,你只负责用标准格式取数。

分步骤解决(每步配可运行代码)

第 1 步:用 instruments 拿到已解析的代码结构

from alphafeed import AlphaFeed

af = AlphaFeed()  # 读取 ALPHAFEED_API_KEY

i = af.instruments.get("600519.SH")
print(i["symbol"], i["code"], i["exchange"], i["region"], i["type"])
# 600519.SH 600519 SH CN stock

instruments.get 返回的每条记录,代码相关字段含义如下:

字段含义示例
symbol标准代码(含后缀,全局唯一)600519.SH
code纯数字/字母代码(不含交易所)600519
exchange交易所SH / SZ / BJ / HK / US
region市场归属地CN / HK / US
type品种类型stock / etf
name证券简称贵州茅台

第 2 步:一次批量识别沪/深/京/港/美

codes = ["600519.SH", "000001.SZ", "920819.BJ", "510300.SH", "00700.HK", "AAPL.US"]
insts = af.instruments.batch(codes)  # 返回 list[dict]

for i in insts:
    print(f'{i["symbol"]:<12} {i["exchange"]:<3} {i["region"]:<3} {i["type"]:<6} {i["name"]}')
# 600519.SH   SH  CN  stock  贵州茅台
# 000001.SZ   SZ  CN  stock  平安银行
# 920819.BJ   BJ  CN  stock  ...(北交所)
# 510300.SH   SH  CN  etf    沪深300ETF华泰柏瑞
# 00700.HK    HK  HK  stock  腾讯控股
# AAPL.US     US  US  stock  苹果

A 股三大交易所后缀与常见开头对照(供理解,判断以 exchange 字段为准):

后缀交易所常见代码段说明
.SH上海证券交易所600/601/603/605、688(科创板)、5xx(ETF)沪市
.SZ深圳证券交易所000/001/002、300(创业板)、1xx/15x(ETF)深市
.BJ北京证券交易所43/83/87/92 等北交所

第 3 步:纯数字代码 ↔ 标准代码互转

很多本地表只存了 6 位数字,需要补后缀才能调接口。用交易所判定规则补全后,再用 instruments.get 校验一次,避免规则误判:

def to_symbol(code: str) -> str:
    """把 6 位数字代码补成标准 symbol(A 股)。规则判定后建议再用 instruments 校验。"""
    code = code.strip().upper()
    if "." in code:            # 已是标准格式,原样返回
        return code
    if code.startswith(("60", "68", "51", "50", "58", "56", "11")):
        return f"{code}.SH"
    if code.startswith(("00", "30", "15", "16", "12", "20")):
        return f"{code}.SZ"
    if code.startswith(("43", "83", "87", "88", "92")):
        return f"{code}.BJ"
    raise ValueError(f"无法判定交易所:{code}")

def split_symbol(symbol: str) -> tuple[str, str]:
    """标准 symbol 拆成 (code, exchange)。"""
    code, _, exch = symbol.partition(".")
    return code, exch

print(to_symbol("600519"))      # 600519.SH
print(split_symbol("000001.SZ"))  # ('000001', 'SZ')

# 用数据源校验规则补全的结果(推荐):
verified = af.instruments.get(to_symbol("000001"))
print(verified["exchange"])      # SZ —— 与规则一致即通过

第 4 步:从全市场池按交易所归类

拿到全 A 池后,用标准代码后缀即可快速分组统计沪/深/京数量:

q = af.quotes.get(universes="CN_Stock", to_dataframe=True)
q["exch"] = q["symbol"].str.split(".").str[-1]
print(q["exch"].value_counts())
# SZ    2901
# SH    2320
# BJ     344

关键坑与注意事项

  • 别只靠开头数字判断市场:科创板 688、创业板 300、ETF、可转债都有各自代码段,规则容易漏;能拿到 exchange 字段就以字段为准。
  • 后缀写法要统一成数据源接受的格式:本 SDK 用 .SH/.SZ/.BJ/.HK/.US,不要混用 .SS、sh 前缀、.XSHG 等其它源写法。
  • region 与 exchange 不完全等价:exchange 是挂牌交易所(SH/SZ/BJ/HK/US),region 是市场归属地(CN/HK/US),跨市场统一时按需要选用。
  • 并非所有历史/退市代码都能解析:极少数早期或退市代码 instruments.get 可能取不到(抛异常),批量处理时要捕获异常并跳过。
  • 港股是 5 位、美股是字母代码:00700.HK、AAPL.US,不要套用 A 股「6 位数字」的假设。

常见问题(FAQ)

Q:600 开头一定是上交所吗? A:600/601/603/605/688 属沪市主板与科创板,是 .SH;但判断市场最稳的方式是读 instruments 的 exchange 字段,而不是硬编码开头。

Q:北交所代码后缀是什么? A:.BJ,如 920819.BJ;全 A 标的池里实测约有 344 只北交所股票。

Q:怎么把 tushare/akshare 风格的 600519.SS、sh600519 转成本 SDK 格式? A:先用 split / 正则取出 6 位数字,再用第 3 步的 to_symbol 补 .SH/.SZ/.BJ 后缀,并用 instruments.get 校验一次交易所是否一致。

Q:需要付费吗? A:单标的 instruments.get / quotes.get 有免费额度;全市场标的池(universes)需 Starter 及以上。详见定价页。

小结

股票代码的本质是「代码 + 交易所后缀」的唯一标识。手写「按开头数字猜市场」的规则脆弱且易错;用 AlphaFeed 的 instruments 直接拿回解析好的 code/exchange/region/type,配合几行互转函数,就能稳定地在沪深京港美股之间统一处理代码格式。

参考