诚实的回测:过拟合、未来函数和幸存者偏差
你有一条向右上方走的资金曲线。夏普比率超过 2,一个你能忍受的最大回撤,几百笔交易。它花了一个周末去调参,而这个结果感觉是挣来的。
它多半一文不值,理由是机械的,跟能力上的任何欠缺无关。回测不检验一套策略,它衡量的是一条规则把一份你已经看过的数据描述得有多好。这是两个不同的主张,而第二个支撑不起任何关于钱的结论。如果你有一套自己引以为傲的策略,请带着那套策略读完下面的部分。
过拟合不是马虎,它是一个计数问题
标准的说法是,过拟合发生在你加了太多参数的时候。这是其中一部分。更大的一部分是你看了多少次。
你对同一份数据集跑的每一次测试都是一次试验。改一个回看窗口再跑:一次试验。加一道筛子再跑:一次试验。因为第一个品种结果令人失望而换一个品种:一次试验。在同一段历史上做了 200 次试验之后,看起来最好的那个结果,正是仅凭噪音就该出现的结果,不管存不存在任何优势。
在 5% 的显著性阈值下,200 次独立试验会凭偶然产生大约 10 个虚假的“显著”结果。然后你挑出最好的那一个,而这恰恰是一道保证你挑中一个假阳性的筛选程序。
试验次数几乎从来不出现在任何人的报告里,而它本该是第一个被报出来的数字。把你测过的每一个配置都记下来,包括那些放弃掉的,并且把最终结果当成从整个搜索里抽出的一个样本。
而且这个计数比你自己的实验大得多。如果你在标普上测一个均线交叉,你不是第一个。成千上万的人在同一段历史上测过这个想法的各种变体,而失败的那些从来没被发表。你继承了一场不是你跑的搜索。
未来函数藏在普通的代码里
未来函数指的是在时刻 t 使用了在时刻 t 还拿不到的信息。它一句话就能说清,却被不停地违反。
把收盘价同时当作信号和成交价。你的规则在今天收盘触发,而你按今天的收盘价成交。在实盘里,收盘价没发生之前你不可能知道它。在流动性好的日线上这道缝很小,在任何日内或者流动性薄的东西上它极其巨大。
被修正过的数据。经济数据会被修订。一个数据库如果把最终修正值放在原始发布日期上,就让你的规则用上了一个好几个星期之后才存在的数字。
在整段序列上计算的指标。任何跨越整段历史来做的归一化、排名或者 z 分数,都会把未来的信息注入到每一根早期的 K 线里。
症状是一条平滑得可疑的资金曲线,配上高胜率和很浅的回撤。这个形状通常意味着系统是被人递了答案,而不是在做预测。
幸存者偏差是你数据的属性,不是你代码的属性
如果你的样本池是今天这份品种清单,那你已经把所有死掉的东西排除在外了。退市的股票、失败的代币、崩掉的交易所、停止交易的交易对。它们中的每一个在当时都在可投资的范围里,而在你的测试里全部缺席。
在加密里这件事很严重。拥有完整多年价格历史的代币集合,是一个被严重筛选过的样本,也就是活下来的那些。一套只在幸存者身上测过的策略看起来很稳健,因为破产已经被从样本里拿掉了。
成本不是一个舍入误差
摩擦成本被放在最后加,甚至干脆不加,而它们改变结论的程度比任何参数都大。要算上你实际付出的点差而不是报价中值,算上随波动率和规模放大的滑点,还有佣金、以及持仓上的资金费率或者隔夜利息。
一套在零成本下活下来、在真实成本下死掉的系统,从来就不是一套系统。它是一段对中间价的描述。把你假设的摩擦成本翻倍,看看还剩下什么。如果优势消失了,那它一开始就在点差里面。
一次诚实的测试长什么样
在开始之前就把数据切开,而且不要碰那份留出来的。在一段上开发,然后在一段你从未查看过的数据上跑一次。就一次。如果你在看到那个结果之后又回去调整,这份留出集就被污染了,你也不再拥有一份留出集。
优先用滚动前推。在一个窗口上拟合,在下一个窗口上交易,然后往前滚。它近似了你真正会怎么操作,也会暴露那些只在一种格局下有效的策略。
报告试验次数、摩擦成本和参数敏感度。一个能扛住每个参数变动 10% 的结果,比一个扛不住的更好结果更有价值。
然后仍然要预期实盘表现会更差。即便方法论干净,一定程度的退化也是正常的,因为市场会变,也因为你没办法完全消除你自己的筛选。
这就是为什么向前的记录比回测重要。Indikora 用 SHA-256 对每一个公布的信号做哈希并与前一个链接在一起,所以这份公开的成绩记录没办法被编辑或者倒填日期,而且它公布概率校准,当它说 60% 的时候,你可以去查这件事后来有多大比例是对的。这两件事在回测里都不可能做到,因为回测按定义是在事情发生之后写的。
你花一个周末调出来的那套策略也许仍然没问题。但你现在还不知道,而诚实的立场是在给它上任何仓位之前,先把这句话说出口。
回测衡量的是一条规则把过去描述得有多好,只有在你从未碰过的数据上跑出来的样本外结果,才说得上一点关于未来的事。
自测
写下你在定下当前这套规则之前测过多少个配置,以及你假设的摩擦成本,并把这条记录一直附在这套策略上,让未来的结果都对着它来评判。
交易日志Indikora 提供免费模拟器、K线回放,以及读取你自己交易记录的行为教练。
打开应用