1. 课程导入与规则回测全景
在真实交易中,限价单挂出后并不总能立刻成交。价格可能长时间在挂单价之外徘徊,订单被动“躺”在盘口里,既占用资金,又错过行情。于是很多交易者会设定一条规则:限价单挂出后若超过某个时间仍未成交,就撤单并按新的参考价重新挂价。这条规则听起来简单,但它到底能不能改善成交率、会不会抬高成本、在震荡市和趋势市里表现是否一致,仅凭盘感无法回答。本课程要做的,就是把这条规则放进历史数据中,用回测的方式量化它的收益与代价。
先厘清四个核心概念。限价单是指定价格、只在该价格或更优价格成交的委托,买单挂价不高于市价、卖单挂价不低于市价,它保证价格但不保证成交。超时是订单从挂出到当前时刻的存活时长超过预设阈值,例如 30 秒、5 分钟或 1 个交易日,阈值本身是规则参数。改价规则规定超时后如何动作:撤单后按什么价格重挂、重挂几次、每次是否调整价差、达到最大改价次数后是否转为市价单或直接放弃。回测则是用历史行情逐笔重放订单生命周期,统计成交、成本与收益,从而评估规则优劣。
理解这条规则,关键是看清一张订单在时间轴上的状态流转。下图把限价单从提交到终结的完整生命周期画了出来,其中“超时判断”是整条链路的分叉点:未超时则继续等待,超时则进入改价分支,而改价分支又受最大改价次数约束,最终收敛到成交、放弃或转市价三种终态。
这张图揭示了回测实现的两个要点。其一,订单状态必须逐笔推进:每来一条行情,都要判断当前挂单能否成交;不能成交再看存活时长是否越过阈值;越过阈值再检查改价次数是否还有余量。其二,所有分支都要有明确终态,否则回测会在某些行情下“卡住”订单,导致统计失真。实际编码时,通常用一个订单对象维护 方向、数量、挂价、挂出时刻、改价次数 五个字段,主循环按时间戳顺序消费行情,遇到状态变化就更新字段并记录事件日志。
为了让规则可计算,需要把“改价”写成明确的公式。设初始挂价为 p₀,第 n 次改价后的挂价为 pₙ,参考价为当前盘口最优价 m(买方向取卖一价,卖方向取买一价),价差参数为 δ,则一种常见设定是:
买单:pₙ = min(m, p₀) − δ × n
卖单:pₙ = max(m, p₀) + δ × n
约束:n ≤ N_max,且 pₙ 不得越过涨跌停价
这里 δ 是“每次改价让出多少价格优势”,n 越大让价越多,成交概率上升但成交价变差。N_max 则限制让价总幅度,防止订单在单边行情中无限追价。回测时把 δ 与 N_max 作为可扫描参数,就能得到一张“成交率—平均成交价偏差”的权衡表,而不是凭感觉拍一个阈值。
举个教学示例(以下数值为合理假设,用于说明计算过程,非实测结果)。假设某标的买一价 10.00、卖一价 10.02,我们挂买单于 10.00,超时阈值 60 秒,δ = 0.01,N_max = 3。挂出后 60 秒内卖一价始终在 10.02 以上,订单未成交,触发第一次改价:参考价 m = 10.02,p₁ = min(10.02, 10.00) − 0.01 = 9.99。若再等 60 秒仍未成交,第二次改价 p₂ = min(m, 10.00) − 0.02,依此类推。回测统计时,这笔订单的“成交价偏差”就是最终成交价与初始挂价之差,“改价次数”记录实际发生的 n,“等待时长”累计各段存活时间。把这些单笔记录汇总,就得到规则层面的成交率与成本分布。