山尖策略 · 历史复盘与交易训练

为什么回测赚钱,实盘却亏?先检查这5个执行偏差

回测和实盘结果不一致时,先别急着改参数。把信号、成交和执行过程逐项对齐,才能知道差异究竟发生在哪里。

“回测赚钱,实盘却亏”是很多策略研究者都会遇到的落差。

但这句话里其实混着几个不同的问题:回测使用的信号,实盘是否能在同一时点看到?回测里的成交价,实盘是否真的能拿到?手续费、滑点、延迟和仓位变化有没有被算进去?人在波动中,是否真的按照原来的规则执行?

回测和实盘结果不一致,不一定说明策略失效;先检查研究假设和执行过程是否一致。 如果假设没有对齐,继续优化参数通常只会把问题藏得更深。

先把“回测赚钱、实盘亏”拆成三层

一套策略从历史数据走到真实执行,至少经过三层:

层次回测里检查什么实盘里容易发生什么
信号条件何时成立指标尚未收盘,或实际看到信号已经晚了一拍
成交按什么价格、数量成交滑点、排队、部分成交和跳空改变了成交结果
执行规则如何被机械运行人临时改规则、漏单、重复下单或仓位不一致

如果只看最后的盈亏,很难知道落差发生在哪一层。更有效的做法,是把每笔交易还原成一条时间线:信息出现 → 信号确认 → 订单发出 → 订单成交或取消 → 仓位变化。

5个最容易忽略的执行偏差

1. 信号时点不一致:收盘后才知道的事,被当成了当时的信号

回测最先要回答的问题不是“买点准不准”,而是:信号究竟在什么时候产生?

例如,策略使用一根 5 分钟 K 线的收盘值。只有等这根 K 线收盘,收盘价、最高价、最低价和基于它计算的指标才完整。如果回测在这根 K 线还没结束时,就使用了最终指标值,结果里就可能混入当时尚未出现的信息。

实盘中还会遇到另外一种时点差异:信号在收盘瞬间产生,但程序、网络或人工操作要到下一秒、下一根 K 线,甚至更晚才能发出订单。

检查时,把这三个时间分别记录下来:

  1. 指标使用的数据何时完成;
  2. 信号何时确认;
  3. 订单何时真正发出。

如果这三个时点在回测和实盘里没有对应关系,收益差异就不能简单归因于市场变化。

2. 成交价过于理想:回测知道的价格,实盘当时并不知道

用下一根 K 线的开盘价、收盘价、最高价或最低价模拟成交,看起来简单,但每种写法都带着假设。

下一根 K 线的最高价和最低价,要等整根 K 线走完后才知道。它们可以用来做事后分析,却不能直接代表订单发出瞬间的可成交价格。对于只有 OHLC 数据的回测,也不能完整还原买卖两侧报价、排队和成交顺序。

更稳妥的做法,是先明确“下一笔可观察价格”是什么:下一根 K 线开盘、某个时间延迟后的报价,还是一段价格区间。数据不支持精确判断时,应把它标成近似假设,并用多组假设做敏感性复核。

你要检查的不是哪一种价格最悲观,而是:这个价格在下单的那一刻是否可被观察、是否可被成交、是否能被重复复现。

3. 成本模型不完整:手续费只是成本的一部分

回测里常见的成本遗漏包括:手续费、买卖价差、滑点、最小交易单位和资金占用。策略单笔优势越薄,这些项目越可能改变交易是否值得执行。

滑点也不一定是固定数值。行情快速变化、流动性下降或订单规模变大时,实际成交价可能偏离信号价格更多。把每笔订单都加上一个固定滑点,可以作为起点,但不能自动说明真实执行已经被完整模拟。

至少准备几组成本假设,分别观察:

如果换一组合理成本,结论就完全相反,那么研究结论应该写成“对成本假设敏感”,而不是只保留最好看的那一组参数。

4. 订单规则被简化:触及价格不等于一定成交

限价单回测中,一个常见简化是:只要 K 线触及限价,就认为订单全部成交。真实情况可能还要考虑触及的先后顺序、可用成交量、排队位置和部分成交。

止损单也有类似问题。价格跳过止损价时,实际成交价可能与预设止损价不同;如果回测总能在止损价精确成交,结果可能比真实执行更规整。

因此,订单状态至少要区分:

这不是为了把模型做得无限复杂,而是为了避免把“价格曾经到过”误写成“订单已经成交”。

5. 规则执行不一致:回测执行的是规则,实盘执行的是人和系统

回测可以毫不犹豫地执行每一次信号,但真实环境里会出现等待、犹豫、临时修改、漏单和重复操作。

常见差异包括:

这些都不是“心理问题”四个字可以概括的。它们应该被记录成可检查的执行事件:当时的规则版本、目标仓位、实际仓位、信号时间、订单时间、订单状态和人工干预原因。

一张执行偏差检查表

检查项需要回答的问题发现问题后先做什么
信号时间指标和信号何时完成?统一收盘确认和下单时点
可见信息当时是否已经知道这项数据?移除未来数据,重新回测
成交价格价格在当时是否可观察、可成交?改用下一可用时点或区间假设
成本与滑点成本变化会让哪些交易消失?做多组成本敏感性复核
订单状态触价是否被误认为成交?区分未成交、部分成交和全成
仓位与数量回测目标仓位和实际仓位一致吗?记录余额、最小单位和风险限制
人工干预哪些交易没有按规则执行?单独统计干预,不要混进规则结果

一个可以先执行的15分钟复盘流程

如果你已经发现回测与实盘出现差异,可以先做一次小范围审计:

第一步:冻结版本

保存当时的策略规则、参数、数据区间、交易成本和代码或配置版本。不要一边查问题一边继续改规则,否则很快无法判断差异来自哪里。

第二步:挑出几笔代表性交易

不必一开始就复查所有交易。先挑出一笔回测盈利、实盘亏损的交易,再挑出一笔两边结果接近的交易,按同一时间线逐项对比。

第三步:只看当时能看到的信息

把后续 K 线隐藏起来,从信号前一根 K 线开始推进。记录当时是否真的满足条件,信号何时确认,下一步可用的成交价格是什么。

第四步:做三组敏感性复核

至少改变一次成交延迟、一次滑点或成本、一次成交比例,然后观察结论是否仍然成立。如果结论只在单一假设下成立,就要把这项不确定性写进研究记录。

第五步:把结论分成三类

分类之后,才知道下一步是改规则、改执行模型,还是先修数据。

什么时候应该做历史回放?

当你发现回测曲线过于顺滑、换一组成本结果就完全不同,或者总能在图表上解释出“本来应该买、应该卖”的位置时,适合把策略放回历史时间顺序中复查。

历史回放不是为了预测下一根 K 线,也不是把亏损交易重新解释成机会。它的价值在于:把后续走势暂时藏起来,重新检查当时的信息、判断、订单和执行过程。

这也连接到上一篇文章讨论的区别:回测检验规则,历史回放检查过程,K 线训练练习当下选择。 K线训练、历史回放和策略回测有什么区别?一篇讲清楚

山尖策略适合放在哪一步?

山尖策略适合用在“规则写清楚之后、研究结论下定之前”这一步:先输入一句交易想法,生成策略预览,再把规则放进历史行情里复盘和训练。

重点不是寻找一条保证未来盈利的规则,而是把信号时点、执行假设、判断节点和研究记录放到同一条可回查的路径里。这样当回测和实盘出现差异时,你能先定位差异发生在哪一层。

常见问题

回测赚钱、实盘亏损,就一定是策略失效吗?

不一定。先区分规则、数据和执行三个层面,再检查信号时点、成交价格、成本、订单状态和实际仓位是否一致。只有在关键假设对齐后,才适合讨论规则本身是否失效。

回测里加入滑点后,结果就一定接近实盘吗?

不一定。滑点只是执行模型的一部分,还可能涉及买卖价差、延迟、部分成交、订单规模、交易时段和跳空。固定滑点可以作为起点,但需要配合多组假设复核。

为什么下一根 K 线最高价不能直接当成交价?

因为最高价要等整根 K 线结束后才知道,订单发出时无法提前观察到。它可以用于事后分析,但不能自动代表当时可成交的价格。

只有 K 线数据,没有盘口数据,还能做回测吗?

可以,但需要明确它是近似模型,并诚实记录成交、成本和滑点假设。对于对成交顺序特别敏感的结论,应降低确定性,并做多套执行假设复核。

历史回放能证明策略未来会赚钱吗?

不能。历史回放用于检查信息时点、判断过程和执行纪律,不能保证未来收益,也不能替代对数据、规则和风险的持续研究。