“回测赚钱,实盘却亏”是很多策略研究者都会遇到的落差。
但这句话里其实混着几个不同的问题:回测使用的信号,实盘是否能在同一时点看到?回测里的成交价,实盘是否真的能拿到?手续费、滑点、延迟和仓位变化有没有被算进去?人在波动中,是否真的按照原来的规则执行?
先把“回测赚钱、实盘亏”拆成三层
一套策略从历史数据走到真实执行,至少经过三层:
| 层次 | 回测里检查什么 | 实盘里容易发生什么 |
|---|---|---|
| 信号 | 条件何时成立 | 指标尚未收盘,或实际看到信号已经晚了一拍 |
| 成交 | 按什么价格、数量成交 | 滑点、排队、部分成交和跳空改变了成交结果 |
| 执行 | 规则如何被机械运行 | 人临时改规则、漏单、重复下单或仓位不一致 |
如果只看最后的盈亏,很难知道落差发生在哪一层。更有效的做法,是把每笔交易还原成一条时间线:信息出现 → 信号确认 → 订单发出 → 订单成交或取消 → 仓位变化。
5个最容易忽略的执行偏差
1. 信号时点不一致:收盘后才知道的事,被当成了当时的信号
回测最先要回答的问题不是“买点准不准”,而是:信号究竟在什么时候产生?
例如,策略使用一根 5 分钟 K 线的收盘值。只有等这根 K 线收盘,收盘价、最高价、最低价和基于它计算的指标才完整。如果回测在这根 K 线还没结束时,就使用了最终指标值,结果里就可能混入当时尚未出现的信息。
实盘中还会遇到另外一种时点差异:信号在收盘瞬间产生,但程序、网络或人工操作要到下一秒、下一根 K 线,甚至更晚才能发出订单。
检查时,把这三个时间分别记录下来:
- 指标使用的数据何时完成;
- 信号何时确认;
- 订单何时真正发出。
如果这三个时点在回测和实盘里没有对应关系,收益差异就不能简单归因于市场变化。
2. 成交价过于理想:回测知道的价格,实盘当时并不知道
用下一根 K 线的开盘价、收盘价、最高价或最低价模拟成交,看起来简单,但每种写法都带着假设。
下一根 K 线的最高价和最低价,要等整根 K 线走完后才知道。它们可以用来做事后分析,却不能直接代表订单发出瞬间的可成交价格。对于只有 OHLC 数据的回测,也不能完整还原买卖两侧报价、排队和成交顺序。
更稳妥的做法,是先明确“下一笔可观察价格”是什么:下一根 K 线开盘、某个时间延迟后的报价,还是一段价格区间。数据不支持精确判断时,应把它标成近似假设,并用多组假设做敏感性复核。
你要检查的不是哪一种价格最悲观,而是:这个价格在下单的那一刻是否可被观察、是否可被成交、是否能被重复复现。
3. 成本模型不完整:手续费只是成本的一部分
回测里常见的成本遗漏包括:手续费、买卖价差、滑点、最小交易单位和资金占用。策略单笔优势越薄,这些项目越可能改变交易是否值得执行。
滑点也不一定是固定数值。行情快速变化、流动性下降或订单规模变大时,实际成交价可能偏离信号价格更多。把每笔订单都加上一个固定滑点,可以作为起点,但不能自动说明真实执行已经被完整模拟。
至少准备几组成本假设,分别观察:
- 哪些交易在加入成本后消失;
- 结果对滑点变化是否敏感;
- 亏损主要集中在开仓、平仓还是跳空时段;
- 订单规模变化后,结论是否仍然成立。
如果换一组合理成本,结论就完全相反,那么研究结论应该写成“对成本假设敏感”,而不是只保留最好看的那一组参数。
4. 订单规则被简化:触及价格不等于一定成交
限价单回测中,一个常见简化是:只要 K 线触及限价,就认为订单全部成交。真实情况可能还要考虑触及的先后顺序、可用成交量、排队位置和部分成交。
止损单也有类似问题。价格跳过止损价时,实际成交价可能与预设止损价不同;如果回测总能在止损价精确成交,结果可能比真实执行更规整。
因此,订单状态至少要区分:
- 已发出但未成交;
- 部分成交;
- 全部成交;
- 被取消或过期;
- 触发后因价格跳跃而产生偏离。
这不是为了把模型做得无限复杂,而是为了避免把“价格曾经到过”误写成“订单已经成交”。
5. 规则执行不一致:回测执行的是规则,实盘执行的是人和系统
回测可以毫不犹豫地执行每一次信号,但真实环境里会出现等待、犹豫、临时修改、漏单和重复操作。
常见差异包括:
- 回测每次都使用相同仓位,实盘却因为余额或风险限制改变数量;
- 回测没有人工确认,实盘遇到波动时临时跳过信号;
- 回测可以立即平仓,实盘却受到网络、权限或交易时段限制;
- 回测只出现一次信号,实盘重复触发后产生多笔订单;
- 回测把规则版本固定,实盘过程中却不断修改条件。
这些都不是“心理问题”四个字可以概括的。它们应该被记录成可检查的执行事件:当时的规则版本、目标仓位、实际仓位、信号时间、订单时间、订单状态和人工干预原因。
一张执行偏差检查表
| 检查项 | 需要回答的问题 | 发现问题后先做什么 |
|---|---|---|
| 信号时间 | 指标和信号何时完成? | 统一收盘确认和下单时点 |
| 可见信息 | 当时是否已经知道这项数据? | 移除未来数据,重新回测 |
| 成交价格 | 价格在当时是否可观察、可成交? | 改用下一可用时点或区间假设 |
| 成本与滑点 | 成本变化会让哪些交易消失? | 做多组成本敏感性复核 |
| 订单状态 | 触价是否被误认为成交? | 区分未成交、部分成交和全成 |
| 仓位与数量 | 回测目标仓位和实际仓位一致吗? | 记录余额、最小单位和风险限制 |
| 人工干预 | 哪些交易没有按规则执行? | 单独统计干预,不要混进规则结果 |
一个可以先执行的15分钟复盘流程
如果你已经发现回测与实盘出现差异,可以先做一次小范围审计:
第一步:冻结版本
保存当时的策略规则、参数、数据区间、交易成本和代码或配置版本。不要一边查问题一边继续改规则,否则很快无法判断差异来自哪里。
第二步:挑出几笔代表性交易
不必一开始就复查所有交易。先挑出一笔回测盈利、实盘亏损的交易,再挑出一笔两边结果接近的交易,按同一时间线逐项对比。
第三步:只看当时能看到的信息
把后续 K 线隐藏起来,从信号前一根 K 线开始推进。记录当时是否真的满足条件,信号何时确认,下一步可用的成交价格是什么。
第四步:做三组敏感性复核
至少改变一次成交延迟、一次滑点或成本、一次成交比例,然后观察结论是否仍然成立。如果结论只在单一假设下成立,就要把这项不确定性写进研究记录。
第五步:把结论分成三类
- 规则问题:信号定义不清,或含有未来信息;
- 执行问题:成交、延迟、成本或仓位没有对齐;
- 数据问题:行情、复权、交易时段或缺失数据存在差异。
分类之后,才知道下一步是改规则、改执行模型,还是先修数据。
什么时候应该做历史回放?
当你发现回测曲线过于顺滑、换一组成本结果就完全不同,或者总能在图表上解释出“本来应该买、应该卖”的位置时,适合把策略放回历史时间顺序中复查。
历史回放不是为了预测下一根 K 线,也不是把亏损交易重新解释成机会。它的价值在于:把后续走势暂时藏起来,重新检查当时的信息、判断、订单和执行过程。
这也连接到上一篇文章讨论的区别:回测检验规则,历史回放检查过程,K 线训练练习当下选择。 K线训练、历史回放和策略回测有什么区别?一篇讲清楚
山尖策略适合放在哪一步?
山尖策略适合用在“规则写清楚之后、研究结论下定之前”这一步:先输入一句交易想法,生成策略预览,再把规则放进历史行情里复盘和训练。
重点不是寻找一条保证未来盈利的规则,而是把信号时点、执行假设、判断节点和研究记录放到同一条可回查的路径里。这样当回测和实盘出现差异时,你能先定位差异发生在哪一层。
常见问题
回测赚钱、实盘亏损,就一定是策略失效吗?
不一定。先区分规则、数据和执行三个层面,再检查信号时点、成交价格、成本、订单状态和实际仓位是否一致。只有在关键假设对齐后,才适合讨论规则本身是否失效。
回测里加入滑点后,结果就一定接近实盘吗?
不一定。滑点只是执行模型的一部分,还可能涉及买卖价差、延迟、部分成交、订单规模、交易时段和跳空。固定滑点可以作为起点,但需要配合多组假设复核。
为什么下一根 K 线最高价不能直接当成交价?
因为最高价要等整根 K 线结束后才知道,订单发出时无法提前观察到。它可以用于事后分析,但不能自动代表当时可成交的价格。
只有 K 线数据,没有盘口数据,还能做回测吗?
可以,但需要明确它是近似模型,并诚实记录成交、成本和滑点假设。对于对成交顺序特别敏感的结论,应降低确定性,并做多套执行假设复核。
历史回放能证明策略未来会赚钱吗?
不能。历史回放用于检查信息时点、判断过程和执行纪律,不能保证未来收益,也不能替代对数据、规则和风险的持续研究。