跳到正文

研究指南

股票回测与实验

A股涨跌停回测诊断:为何要检查开盘成交价而非当天收盘

A股涨跌停成交核验,应使用开盘当时已经可得的信息判断候选成交:有效前收盘、带生效日期的证券规则、最小价格单位,以及应用已声明滑点后的价格。不能用当天最终收盘,反过来决定更早的开盘订单是否能够执行;否则即使条件本身正确,时间边界也已经错了。

本文实现一个保守开盘检查器和完整合成往返账户,不重建订单队列,也不证明被允许的候选价必然成交。CoTrading的历史涨跌停元数据、板块撮合和真实券商执行仍属规划或待核实。独立脚本只展示下面明确定义的检查政策,不能作为产品已经支持全部规则的证据。

规则必须附着于证券和生效区间

上交所2026年交易规则英文译本列出基于前收盘的价格限制、最小价位取整和包括科创板在内的不同安排。单个百分之十常量不能覆盖全部证券、历史日期、上市阶段或特殊状态,仅靠代码前缀也不能恢复完整历史规则。

上交所规则发布通知写明2026修订自7月6日生效,并提供实施安排。本例普通主板元数据明确有效于2026年7月6日至12月31日;查询更早日期返回规则未知,不把现在规则回填过去。实际历史研究必须另存当时版本和逐证券状态,不能只保留最新文件。

合成普通情形给出百分之十限制和0.01最小价位,另一个明确输入的科创板夹具给出百分之二十。它们只是受限例子,不是完整规则库。新上市阶段、风险警示、除权参考调整、无价格限制会话和工具例外,都需要自己的带日期元数据及验收,不能因为本例通过就推定全部可用。

元数据缺失或日期不在有效范围,返回unknown_rules;前收盘缺失返回unknown_previous_close。未知不等于允许成交。检查器不会从代码猜比例,不把当日收盘当缺失前收盘,也不为了让模拟继续而任意填一个默认值。规则证据不足时应保留缺口,不能把它隐藏成一笔看似正常的交易。

先算价格边界,再检查含滑点候选价

前收10、限制百分之十时,未取整上限11、下限9。脚本使用Decimal按给定tick四舍五入:先除以tick,按半入方式取最近整数,再乘回tick。这样把价格单位处理显式展开,而不是假定保留某个小数位数永远等于正确的最小价位操作。

Python Decimal文档说明本例使用的十进制输入与取整行为。价格从字符串构造,可避免二进制浮点近似干扰小账户手算,同时检查有限与正值。这不能替代交易所全部特殊取整规则;更复杂场景仍需相应市场规格,而不是看到Decimal就默认合规。

买入候选价为开盘乘一加滑点,卖出为开盘乘一减滑点。开盘、前收和tick必须有限且为正,限制比例严格介于零和一,滑点大于等于零且小于一,方向只允许buy或sell。非法数值报错,证据缺失则保持独立未知状态,两者不能统一当作无条件通过。

本例保守政策是:买价大于或等于上限时阻止,卖价小于或等于下限时阻止;其余标为permitted_by_guard,而不是已经成交。真实触及涨跌停时可能仍有对手方数量,带内候选也可能无法成交。这个名称明确只表示通过所选检查,仍需要真实市场和订单模型才能判断执行。

两个收盘方向相反的控制

第一个控制开盘11,正好在上限,后来收盘10.5。按本检查器,开盘买入仍被阻止。若使用后来“打开涨停”的收盘,就会用未来信息释放先前订单。当天后来离开限制,不能告诉这个只有开盘信息的夹具,在更早时刻究竟有多少可以成交的卖盘。

第二个控制开盘10.5,在带内,后来收盘11。检查器允许开盘候选。如果只看日收盘,则会因为最后涨停而错误拒绝此前订单。成对例子检验同一个时间错误的两个方向,说明读取未来信息不一定只让结果更乐观,也可能错误消除本来符合检查政策的交易。

当天后来收盘根本不是audit函数参数,只出现在反例注释记录里,让读者看清一个看似方便的替代判断为何不符合当前信息边界。更丰富的日内模拟可以在之后时间合法读取之后报价,但不能回头修改已经完成的开盘决策状态。读取范围必须跟执行时点一一对应。

最终候选越界不能只检查原始开盘

买入开盘10.99低于上限11,但滑点0.002以后候选为11.01198,因此被阻止。若只检查10.99,就会接受超出声明检查范围的模拟成交价。把候选截到11会引入另一种价格政策,而且在本例“等于上限也禁止”的保守规则下仍不通过,不能静默截断后称作原模型。

卖出控制从9.01开始,看似高于下限9,相同滑点后候选8.99198,仍被阻止;正好9的卖出同样阻止。方向不能忽略:所有订单只检查上限,会漏掉跌停退出问题,使按照声明规则本应保留的持仓凭空变成现金,并让亏损暴露提前消失。

前收10、开盘11.5时,普通百分之十元数据阻止买入,显式科创板百分之二十元数据则通过当前检查。这里改变的是适用规则,不是滑点,与前一组反例机制不同。板块和生效日期必须随订单传递,不能从哪个比例让结果更好就选哪个比例,更不能把示例当作所有科创板历史状态的自动识别。

用通过检查的路径闭合完整账户

账户初始现金两千、零持仓。买入候选10.5通过普通夹具检查,以该价购买一百股,费用一,总支出1051,现金剩949、库存一百、累计费用一。按进入价估值,开仓后权益1999,等于初始资本减已支付费用,不能在开仓瞬间凭空增加资金。

单独给定退出开盘10.8、参考前收10、滑点零,卖出候选通过。卖一百股,扣费净收1079,结束现金2028、零持仓、累计费用二。价格毛收益三十,扣费净现金收益二十八,现金桥为两千减1051加1079。例子同时核对进入现金与结束结果,使检查政策连接到实际库存账。

受阻控制不进入这个成功账户,拒绝标签解释对应请求为何不执行,往返路径则展示允许之后仍需数量、费用和现金核算。不能把本账户二十八的利润归给一个本来被阻止的开盘,也不能从两个合成价格制造历史回测统计。真实表现与机制验证必须有独立数据依据。

运行并保留尚未验证的执行问题

下载完整示例,使用Python 3.12或更新版本执行python R598.py,只需标准库。元数据和价格都是明确的合成夹具,规则区间以所引通知为依据。输出包含两条收盘反例、买卖滑点越界、下限卖出控制及最终账户,无须网络、行情权限或交易账户。

接入真实回测前,应归档逐证券价格带、参考价调整、生效区间和执行时间,另核对T+1库存、合法会话、资金与订单数量。保守价格检查可以阻止部分不合理模拟成交,但不能认证队列顺序、开盘分配、部分成交或全部历史规则。报告应保留这些未决项,不能把通过检查的状态翻译成必然真实成交。

资金变化前先保留检查证据

每次检查记录方向、前收参考、元数据有效期、取整边界、含滑点候选和状态,再决定是否改变库存。10.99买入被拒的直接理由是候选11.01198,后来收盘无关。保存这些中间值,未来修正规则时才能追到第一笔受影响订单,而不只看到最后收益变化;新版本允许也不能覆盖旧版本原先的拒绝理由。

同一个未知状态也不能自动解释成市场确实封板。例如缺前收是资料不足,已知边界而候选越界才是本检查器的拒绝,两者在审阅表应分栏。若将来接入真实涨跌停价而不自行计算,还需核其来源时间、除权处理和与证券状态的一致性。供给字段变多不能取消信息时间要求,当天结束后才计算的汇总标签仍不能直接用于早开盘。当前合成账户只在两个候选通过后记账,未建模拒绝后自动追单;若需要该行为,应另定何时重试、使用哪次报价和是否改变数量,再准备独立现金路径。

常见问题

触及限制是否证明现实绝对不能成交?

不能。本作者模型选择保守阻止该方向。真实是否成交需要日开盘价之外的市场和队列证据。

当天收盘能否决定此前开盘成交?

本契约不能。函数只用前收、开盘候选和已生效元数据,后来收盘仅是反例注释。

相关阅读