4个数字就能讲出一个令人不安的故事:滚动验证 Sharpe 为 1.4,历史交易 312 笔,模拟交易 46 笔,模拟交易与回测的成交价相差 18 个基点。Sharpe 抢了头条,但在模拟交易历史还不够长、无法评估表现之前,这 18 个基点或许更能解释策略为何感觉不一样。
滚动测试要回答的是:研究流程能否利用过去的数据选出策略,再用后续数据评估它。模拟交易要回答的是:一个正在运行的系统,使用当前的数据、时钟、下单逻辑和成交方式,表现是否与经过测试的流程一致。这两个问题相关,但前一个问题的答案并不能自动回答后一个。
滚动验证究竟能证明什么?
比如,你用 6 个月的数据训练或筛选策略,再用接下来的 1 个月评估。将窗口向前滚动并重复这个过程。如果每个月的测试数据都没有参与对应的策略筛选,这项测试就能提供证据,说明策略在一系列历史条件下的表现。
但这并不能证明模拟交易会重现相同的决策或成交。历史测试可能使用已收盘的 K 线、固定的费用表和简化的市价单模型;实时模拟交易流程则接收持续到达的数据,并通过另一套路径提交模拟订单。前者可以严谨可靠,后者却仍可能存在不匹配。
所以,模拟交易 46 笔、滚动验证样本 312 笔,这本身并不能说明策略有问题。要检查比较区间、信号频率、区间边界时的未平仓头寸,以及两边是否采用相同的交易笔数定义。6 周的模拟交易不可能在交易笔数上匹配 1 年的滚动测试。
为什么成交价差距如此值得关注?
在解读模拟交易的权益曲线之前,应该先拆解平均 18 个基点的差距。这个差距是以回测假定的成交价和模拟器成交价计算的,还是以决策时的中间价和模拟成交价计算的?两种算法衡量的并不是一回事。应分别记录决策价格、订单到达价格、模拟成交价、手续费和任何资金费用。
| 观察到的差异 | 首先检查 | 为何重要 |
|---|---|---|
| 模拟交易笔数更少 | 信号时间戳和资格规则 | 输入缺失或延迟会导致决策未能触发 |
| 交易相同,成交更差 | 订单类型、价差、冲击和费率等级 | 回测可能假设了成本更低的执行路径 |
| 持仓规模不同 | 现金、合约乘数和舍入方式 | 微小的单位差异会在多笔订单中累积 |
| 重启后出现偏差 | 恢复后的持仓和未成交订单 | 模拟交易流程恢复时的状态可能不同 |
例如,在下一根 K 线开盘价买入的回测,在流动性充足的品种上可能看起来与模拟市价单相差不大。但如果模拟订单在行情急剧波动后才到达,这段差距就既包含时机和市场波动的影响,也包含执行成本。把全部 18 个基点都称为“滑点”,会掩盖真正的原因。
如何将模拟交易与滚动验证测试进行比较?
先比较决策,再比较订单,最后比较成交。对于每个模拟交易决策,用相同的策略版本重放同一段输入历史,并比较策略在那个时点掌握的信息。可用于核对一致性的记录包括:
- 策略版本和参数,包括产生这些参数的筛选窗口。
- 输入值,同时记录事件时间和可用时间。
- 信号、目标持仓、当前持仓和拟提交的订单。
- 订单限制、手续费、资金费用和模拟成交详情。
- 执行前后的现金和持仓状态。
如果信号不同,检查数据时序和代码版本。如果信号一致但订单不同,检查仓位计算、交易场所规则和投资组合状态。如果订单一致但成交不同,检查执行假设。把这些层面分开核对,否则一个表现数字就会把你引向错误的排查方向。
什么时候出现的偏差才说明策略出了问题?
在确认整个流程一致后,再比较足够长的共同区间内的结果,并检查策略预期的行为。少量模拟交易就能很快暴露时间戳或订单路径问题,但不足以可靠地判断策略的平均收益是否发生变化。要得出这样的判断,需要足够多的观测,而所需数量取决于收益的噪声有多大、聚集程度有多高。
市场条件也可能变化。价差扩大或资金费用持续转为不利,都可能损害策略表现,即使每个决策都与预期一致。这反映的是真实交易条件变化,而不是验证流程出错。应将成本和敞口与收益一并记录,这样才能看清两者的区别。
滚动验证提供的是策略筛选流程在历史区间表现如何的证据;模拟交易提供的是运行中的系统在观测到的条件下表现如何的证据。当两者结果不一致时,先找出记录最早出现分歧的环节。出人意料的往往不是 Sharpe,而是一个细微的执行或数据差异,让两次实验回答了不同的问题。
← 全部文章


