双时钟回测:分钟级信号配 1 秒风险时钟
信号在已收分钟 K 线上触发;止损、止盈与移动止损在 1 秒收盘价上评估,并遵循严格的每秒事件顺序。验证显示:仅用分钟级评估风控,会让紧止损策略的结果失真 −55%,而宽止损配置几乎不受影响。
架构
高保真回测引擎对同一份基准数据运行两个时钟:
- **信号时钟。**Donchian 信号在已收的 1m/5m/15m/30m K 线上计算,全部由同一条 SPX 1 秒序列聚合而来。正在形成的 K 线永远不参与自己的通道计算。
- **风险时钟。**止损、止盈、移动止损、时间止损与 EOD 出场只在 1 秒收盘价上评估——绝不用 K 线内的 high/low 去“推断”路径顺序。
一个四状态机(FLAT → PENDING_ENTRY → OPEN → PENDING_EXIT → FLAT)用固定的每秒事件顺序把两个时钟接起来:先在该秒开盘成交挂单,再处理信号 K 线收盘,最后在该秒收盘检查风险触发。一条统一规则防止边界上的未来函数:任何一秒内,{出场成交, 接受新入场} 至多发生其一。
分钟级风控会错在哪里
验证用同样的策略、改为在 1 分钟 K 线上评估风控,覆盖 778 个交易日。对紧止损的 scalper 配置(1m 信号、5 点止损、3/5 点移动止损):
- **总盈亏误差 −55%:**1 秒真值为 17,262 笔、+5,732 点;最好的分钟模式只得到 14,643 笔、+2,584 点。
- **漏掉的移动止损出场 −44%:**真值 7,263 次 vs 分钟收盘价检测 4,071 次——在单根 K 线内完成“激活并触发”的序列完全不可见。
- **幻影止损 +3%:**用 K 线内 high/low 检测会触发 1 秒收盘路径从未触及的止损,然后在已经回弹的收盘价上“成交”。
同样的对比放到宽止损的 rider 配置(30m 信号、10 点移动止损)只偏差 +0.6%——当触发阈值远大于典型的 K 线内波动时,分钟 K 线是够用的。
让引擎保持诚实的规则
- 信号 K 线时间戳必须是 1 秒时间轴的精确子集(无漂移、无舍入)。
- 过滤器(VIX、日内波幅)在信号 K 线收盘时评估,绝不在执行秒上评估。
- EOD 出场是配置出来的(15:49:59 触发 → 15:50:00 成交),不是推导出来的。
- 11 个强制集成测试钉死这些语义,包括回放核心的 Python↔Rust 逐字节一致性。
教训
时钟精度必须匹配止损松紧。对一个 5 点的日内止损来说,分钟级回测不是“近似正确”——它是另一个策略。先决定风险时钟,再问你的数据撑不撑得起它。