先给结论:涨停价不是"昨收乘以 10%"这么简单——它是前收盘价 ×(1±涨跌幅比例),四舍五入到分。这一分钱的舍入误差、加上"昨收必须是交易所口径的不复权价格"这个前提,正是大多数打板回测与实盘对不上的两个根源。算涨停价,永远用不复权数据;判断买不买得到,永远要看封单和可成交性,而不是只看价格到了没到。
沪深交易所交易规则明确:计算结果四舍五入至 0.01 元。看两个例子,体会舍入如何改变结果:
注意:因为舍入的存在,涨停日的"实际涨幅"几乎从来不是精确的 10%——它在 10% 上下浮动,方向由昨收的小数部分决定。这正是"打板党"口中"涨停价差一分钱"的来源:同一价位,算对了就是排板成功,算错了就是买在不可能成交的位置。
| 情形 | 前收盘价取什么 |
|---|---|
| 正常交易日 | 上一交易日的收盘价(交易所口径真实价格,即不复权) |
| 除权除息日 | 除权除息参考价(交易所按分红送股方案计算公布,不是原始昨收) |
| 停牌复牌日 | 停牌前最后一个交易日的收盘价 |
| 板块 | 代码特征 | 日常涨跌幅 | 新股上市初期 | ST 股 |
|---|---|---|---|---|
| 沪深主板 | 60 / 00 开头 | ±10% | 前 5 日无限制,第 6 日起 ±10% | ±5% |
| 创业板 | 30 开头 | ±20% | 前 5 日无限制,第 6 日起 ±20% | ±20%(不适用 5%) |
| 科创板 | 68 开头 | ±20% | 前 5 日无限制,第 6 日起 ±20% | ±20%(不适用 5%) |
| 北交所 | 8 / 4 / 92 开头 | ±30% | 首日无限制,次日起 ±30% | ±30% |
两个新规要点(2023 年 4 月全面注册制落地后):
算准涨停价只完成了一半。另一半是:价格到了涨停,不代表你买得到。
Q1:涨停价计算用四舍五入还是直接截断?
四舍五入到分(0.01 元)。例如昨收 9.87 元,9.87 × 1.1 = 10.857,四舍五入后涨停价是 10.86 元。
Q2:除权除息日当天的涨停价怎么算?
用交易所公布的除权除息参考价作为前收盘价计算,而不是上一交易日的原始收盘价。
Q3:ST 股票的涨跌幅限制是多少?
沪深主板 ST/*ST 为 ±5%;创业板、科创板的 ST 股不适用 5%,仍是 ±20%;北交所 ±30%。
Q4:新股上市第一天有涨跌幅限制吗?
2023 年全面注册制后,沪深三个板块新股前 5 个交易日均无涨跌幅限制,第 6 日起主板 ±10%、创业板/科创板 ±20%。旧规则的首日 44% 已废除。
Q5:为什么用前复权数据算出的涨停价和实际盘口不一样?
涨停价只能用真实昨收(不复权)计算,复权昨收不是交易所口径的真实价格,算出的涨停价在盘口不存在。
Q6:一字涨停板在回测里能买入吗?
不能。一字板全天封死、封单巨大,实际无法成交。回测应标记为不可成交,非一字板可用涨停价成交量占比近似判断可成交性。
Q7:怎么用接口数据自己计算涨停价?
取不复权日线(如迪雅数据 A股历史交易数据接口,默认即不复权),用前一交易日 close 作为真实昨收,按板块确定比例后相乘、四舍五入到分。
adjust 参数即默认不复权),取前一交易日 close 作为昨收round(yesterday_close * (1 + limit), 2) 即涨停价,注意 Python 的 round() 是银行家舍入,精确实现应改用 Decimal 的 ROUND_HALF_UP盘中封板与打开的时序还原,可配合 A股分时交易数据接口 使用。
round(11.275, 2) 可能得到 11.27 而不是 11.28——因为浮点表示误差加上银行家舍入规则。交易所口径是四舍五入(ROUND_HALF_UP),用 Decimal(str(x)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) 才是对齐盘口的实现。回测里几百只股票累积下来的舍入偏差,足以让打板策略的成交记录系统性失真。