如何用 Python 计算 A 股涨停价/跌停价与最小变动价位?(含创业板科创板20%)
如何用 Python 计算 A 股涨停价/跌停价与最小变动价位?(含创业板科创板20%)
一句话回答: A 股涨跌停价是”昨收盘 × (1 ± 涨跌幅比例),再按最小变动价位四舍五入”,主板 10%、创业板/科创板 20%、ST 股 5%。你不必自己套规则——用 AlphaFeed 的 instruments 接口直接取每只票的 limit_up、limit_down、tick_size,官方口径、免算错。
为什么会有这个问题 / 传统做法的痛点
自己算涨跌停价看似简单,坑却不少:
- 比例不统一:主板 10%、创业板(300 开头)/科创板(688 开头)20%、ST 股 5%、北交所 30%,硬编码规则容易漏;
- 四舍五入:涨跌停价要按最小变动价位(
tick_size,A 股通常 0.01 元)取整,1285.13×1.1=1413.643要处理成1413.64; - 新股/首日:上市首日、复牌等特殊情形规则不同。
AlphaFeed 直接把交易所口径的 limit_up/limit_down 放进 instruments.ext,省去所有规则维护。
分步骤解决(每步配可运行代码)
第 1 步:直接取官方涨跌停价与最小变动价位
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
symbols = ["600519.SH", "000001.SZ", "300750.SZ"]
insts = af.instruments.batch(symbols) # list[dict]
q = af.quotes.get(symbols=symbols, to_dataframe=True)
prev = dict(zip(q["symbol"], q["prev_close"])) # 昨收
rows = []
for it in insts:
ext = it.get("ext", {}) or {}
rows.append({
"symbol": it["symbol"], "name": it.get("name", ""),
"prev_close": prev.get(it["symbol"]),
"limit_up": ext.get("limit_up"),
"limit_down": ext.get("limit_down"),
"tick_size": ext.get("tick_size"),
})
print(pd.DataFrame(rows).to_string(index=False))
实测输出(真实数据):
| symbol | name | prev_close | limit_up | limit_down | tick_size |
|---|---|---|---|---|---|
| 600519.SH | 贵州茅台 | 1285.13 | 1413.64 | 1156.62 | 0.01 |
| 000001.SZ | 平安银行 | 11.85 | 13.04 | 10.67 | 0.01 |
| 300750.SZ | 宁德时代 | 338.06 | 405.67 | 270.45 | 0.01 |
一眼可见规则:茅台/平安银行是主板 ±10%(1285.13×1.1=1413.64),宁德时代是创业板 ±20%(338.06×1.2=405.67)。instruments 已按板块给出正确比例,无需你判断。
instruments.ext 价格相关字段:
| 字段 | 含义 | 备注 |
|---|---|---|
limit_up | 当日涨停价 | 交易所口径,已四舍五入到 tick |
limit_down | 当日跌停价 | 同上 |
tick_size | 最小变动价位 | A 股通常 0.01 元 |
total_shares / float_shares | 总/流通股本 | 市值计算用 |
listing_date | 上市日期 | 判断次新/首日 |
第 2 步:判断当前价距涨/跌停还有多远(封板空间)
def limit_room(symbol):
it = af.instruments.get(symbol)
ext = it.get("ext", {}) or {}
q = af.quotes.get(symbols=[symbol], to_dataframe=True).iloc[0]
last = float(q["last_price"])
up, down = float(ext["limit_up"]), float(ext["limit_down"])
return {
"last": last,
"to_limit_up_pct": round((up / last - 1) * 100, 2), # 距涨停还有几 %
"to_limit_down_pct": round((down / last - 1) * 100, 2),
}
print(limit_room("600519.SH"))
第 3 步:如需自己验证比例(可选)
def infer_ratio(prev_close, limit_up):
return round(limit_up / prev_close - 1, 2) # 0.10 / 0.20 / 0.05 ...
# 用官方 limit_up 反推比例,核对板块规则,不建议用它替代官方 limit_up
关键坑与注意事项
- 优先用官方
limit_up/limit_down:不要自己硬编码比例再乘。板块规则会变(如注册制、北交所 30%),官方字段最稳。 - 四舍五入到 tick:若确需手算,务必按
tick_size取整(round(price/tick)*tick),否则会和交易所差一分钱。 - ST/*ST 是 5%:这类股票比例不同,官方字段会自动反映,手算规则最容易在这里错。
- 上市首日 / 复牌 / 新股:涨跌停规则特殊(首日通常放宽或无限制),以官方字段为准。
- 昨收 vs 前收盘:涨跌停基于”前收盘价”,除权日的前收盘是除权参考价,别用未复权收盘价直接算。
常见问题(FAQ)
Q:为什么我按”昨收×1.1”算出来和软件差一分钱?
A:没做最小变动价位四舍五入。交易所会把结果按 tick_size(0.01)四舍五入,直接用官方 limit_up 就不会有这个问题。
Q:创业板、科创板、北交所比例分别是多少?
A:创业板(300)/科创板(688)是 20%,北交所 30%,主板 10%,ST 股 5%。但请直接读 instruments.ext.limit_up/limit_down,不用自己记。
Q:能批量取全市场的涨跌停价吗?
A:可以,用 instruments.batch 传标的列表;配合 quotes.get(universes="CN_Stock") 拿全市场标的再分批查询。
Q:需要付费吗? A:少量标的的 instruments/quotes 在免费额度内即可试;全市场池需 Starter 及以上,详见 AlphaFeed 定价页。
小结
涨跌停价的本质是”昨收 × 比例,按 tick 取整”,但比例因板块/ST 而异、还要处理四舍五入,自己维护规则容易错。AlphaFeed 的 instruments.ext 直接给出交易所口径的 limit_up/limit_down/tick_size,让你几行就拿到正确结果,把精力留给策略而不是规则。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。