2. 限价单超时改价规则拆解

上一节我们明确了回测目标:验证“限价单挂单超时后改价”能否在成交率与滑点之间取得更优平衡。但业务方给出的往往只是一句模糊描述——“挂太久没成交就改一下价格”。这句话无法直接回测,因为它缺少可判定的条件、可计算的触发逻辑、可约束的幅度与频率。本节的任务,就是把这句话拆解成一份可回测的规则说明书:每个字段都有明确取值、单位和判定方式,回测引擎读到它就能逐笔复现改价行为。

一、超时判定:先定义“超时”的参照系

超时判定看似简单,实则最容易埋坑。核心问题是:从什么时刻开始计时、以什么状态为计时前提、在什么时点检查。我们约定参照系如下:以订单进入交易所可撮合状态的时刻为计时起点(记为 t₀),而非策略发出信号的时刻;以“订单仍处于未成交挂单状态”为计时前提;以固定周期(例如每 500ms 或每根 1 分钟 K 线收盘)为检查时点。这样定义后,超时条件可写成:

超时判定:
  elapsed = now - t0
  若 elapsed >= timeout_threshold 且 order.status == "挂单中"
  则 标记该订单为“超时候选”,进入改价触发判断

这里有两个必须写进说明书的细节。第一,timeout_threshold 是参数而非常量,回测中要能扫描不同取值(如 30s、60s、120s)。第二,部分成交的订单是否算“挂单中”?我们的约定是:只要剩余数量大于零且未撤单,就继续计时,但改价时只对剩余数量生效。若不明确这一点,回测中会出现“已成交部分被重复改价”的虚假结果。

二、改价触发逻辑:超时之后还要满足什么

超时只是“候选”,真正触发改价还需要一个方向性判断,否则盲目改价可能把订单推向更差的位置。我们采用“盘口偏移”作为触发条件:比较订单限价与当前对手方最优价的差距,只有当差距超过设定阈值时才改价。以买单为例,触发逻辑为:

买单改价触发:
  gap = order.price - best_ask
  若 超时候选 且 gap >= trigger_gap
  则 触发改价,新价格 = best_ask + price_offset

其中 trigger_gap 表示“我的买价高出卖一多少才值得追”,price_offset 表示改价后相对盘口的让价幅度。卖单方向对称处理:gap = best_bid - order.price,新价格 = best_bid - price_offset。这样设计的好处是,超时但盘口已经靠近订单价格的场景不会触发无谓改价,避免频繁扰动。

限价单超时改价规则判定链(以买单为例) t₀:进入可撮合状态 开始累计 elapsed elapsed ≥ timeout_threshold 且剩余数量 > 0 继续挂单等待 不触发改价 是 gap = price − best_ask gap ≥ trigger_gap ? 盘口已靠近 维持原价 是 新价格 = best_ask + price_offset 撤旧单 → 发新单(剩余数量) 频率约束(前置闸门) 改价次数 < max_repricing 距上次改价 ≥ min_interval 任一不满足则跳过本次改价 注:卖单方向对称,gap = best_bid − price,新价格 = best_bid − price_offset。

三、改价幅度与频率约束:防止规则“失控”

如果只写“超时就改到盘口”,回测中很容易出现两类失真:一是改价幅度过大,单笔滑点吃掉全部收益;二是改价过于频繁,在震荡行情中反复撤单、反复成交,手续费与冲击成本被严重低估。因此说明书必须包含幅度与频率两组约束。

幅度约束由 price_offset 控制,它决定新价格相对盘口的让价。取值过小(如 0)会导致新单立刻变成新的“盘口外”订单,很快再次超时;取值过大则相当于主动吃单,滑点上升。回测中应把 price_offset 与最小价格变动单位 tick_size 对齐,例如 price_offset = k × tick_size,k 取 0、1、2 分别对应“贴盘口”“让一档”“让两档”。

频率约束包含两个参数:单笔订单最大改价次数 max_repricing,以及两次改价之间的最小间隔 min_interval。前者防止同一订单被无限追逐,后者防止在极短时间窗口内反复撤发。二者作为“前置闸门”,在触发逻辑通过后、执行改价前进行校验,任一不满足则跳过本次改价并保留原单。

四、规则说明书:可直接交给回测引擎的字段表

把上述拆解固化为字段,就得到一份可执行的规则说明书。下表是示例参数,实际回测时应作为待扫描变量而非固定值。

字段含义示例取值判定/作用
timeout_threshold超时阈值60selapsed ≥ 该值进入候选
trigger_gap盘口偏移触发阈值2 × tick_sizegap ≥ 该值才改价
price_offset改价让价幅度1 × tick_size新价 = 盘口 ± 该值
max_repricing单笔最大改价次数3达到后不再改价
min_interval改价最小间隔30s未满间隔则跳过
partial_fill_policy部分成交处理仅对剩余量改价避免重复改价
拆解完成后的自检标准:把这份说明书交给另一个人,他能否在不询问你的情况下,仅凭字段和判定式复现每一笔改价?如果能,说明规则已具备可回测性;如果仍有“看情况”的模糊地带,就说明还有条件未被参数化。

需要强调的是,以上参数均为教学示例,不代表任何实测最优值。真正的取值应在回测中通过网格或分层扫描确定,并同时观察成交率、平均滑点、改价次数分布与手续费占比四个指标,避免只盯单一收益数字。规则说明书的价值不在于给出“正确答案”,而在于让每一次参数变化都能被清晰归因。