那一夜,我的回测对我撒了谎

某天夜里,一次回测告诉我:我把一笔不起眼的初始本金变成了 2792 万亿韩元——比这颗星球上大多数经济体的年产出还要多。我盯着它看。有那么几分钟,我内心某个安静而贪婪的部分,开始去寻找它可能是真的理由。

它不是真的。它是一个 bug。而这个 bug 最终带来的教益,比任何盈利策略都更深刻,因为它关乎回测之所以存在的唯一使命:尊重现实。

那个本该吓到我的数字

我当时在做参数搜索——成千上万种配置,每一种都在历史数据上重放一遍,再按最终结果排名。绝大多数返回的都很平庸。有一个返回的是疯狂。

对你有利的疯狂,是一个系统能产出的最危险的输出,因为它披着成功的面孔降临。一次亏损的运行会逼你去调试。一次”奏效”的运行会让你去庆祝。审视是不对称的,而且方向恰恰错得彻底:我们盘问那些自己不喜欢的结果,却对自己喜欢的一路放行。我差点就把这个放行了。

我必须学会的那种直觉——以惨痛的方式学会的——恰恰相反。结果越是惊艳,就越能确定有什么东西坏掉了。市场不会把一个小国的 GDP 交到一个初次上手的搭建者手里。如果你的模拟说它会,那是模拟在撒谎,而你唯一的工作就是找出它是怎么撒的。

错误之一:每一次都押上整个账户

第一个缺陷出在仓位大小上。每一笔交易的规模基本上都是整个账户,而利润则直接复利滚进下一注。一旦你这么做,你就不再是在为交易建模,而是在为一个几何级数建模。一段足够长的、哪怕只是略微有利的结果——又或者只是恰好足够频繁地往对的方向断裂的纯噪声——不会增长,而会引爆。数学一路狂奔,把现实甩在身后,再也不回头。

这正是一个完全复利的回测最诱人之处:它不需要一个好策略就能产出一个漂亮的数字。它只需要足够多的交易,外加一个足够慷慨、肯让这一注一直骑下去的模拟器。复利把一丝微弱而毫无意义的统计倾向,变成一条指数曲线,而一条横跨成千上万次交易的指数曲线,会产出一个看似命中注定、实则毫无意义的数字。那个天文数字并不是某种优势的证据。它是把整个账户的暴露施加在随机性之上的证据。

错误之二:一个死不掉的模拟器

第二个缺陷更糟,因为它是哲学层面的。我的回测器没有吸收壁——没有那么一个点,让账户干脆就此死亡。所以当一连串糟糕的交易把余额砸下去 99.99% 时,模拟并没有停下。它把那具尸体留在桌上,任由它继续交易。而从那个近乎归零的余额起,一段好运”复活”了账户,又把它抬回到一个荒唐的高度。

在真实账户里,那种复苏是不可能的。零就是零。一个被清算的余额不会有第二幕——你出局了,永久地,未来任何盈利的连胜都无法穿越时间回来救你。我的代码放任一个破产的账户继续交易,悄悄删掉了交易中最重要的那条规则:毁灭是终局。下游的一切——整个幻象——都顺理成章地源自这一条缺失的约束。这个模拟建模的不是一个幸存下来的策略。它建模的是一个被允许死去、然后又被禁止保持死亡状态的策略。

优化器在猎杀我的盲点

接下来这一点是我花了最久才理解的:参数搜索并不是偶然撞上那个荒唐配置的。它是主动去寻找它的。

一次横跨成千上万种配置的搜索不是一个中立的观察者。它是一个对手,会针对你交给它的任何指标进行优化。如果你的指标是”最终余额”,而你的模拟器有一处软肋——一个让不切实际的事情被悄悄放行的地方——搜索就会找到那个软肋,并把全身的重量压上去。它不会奖励最好的策略。它奖励的是最高效地利用你的模拟与现实之间那道裂缝的那个配置。

所以那个万亿韩元的结果,并不是一个随机浮现的倒霉 bug。它是把一个强大的优化器对准一个能被骗过的模拟器之后,可以预见的后果。你在回测里留下的每一个弱点,在搜索之下,都会变成一个策略。优化器是一台机器,专门用来发现你忘了去强制执行的那些假设。

那个破绽

把这些错误拼到一起,你就得到一台制造奇迹的机器。它能熬过任何事,所以它什么都能熬过;它押上一切,所以当它幸存时,它幸存得无比庞大;而一次搜索正在悄悄调校它,让它把这两件事都做到极致。那个输出不是某个策略的表现。它是 bug 本身的形状,用极其庞大的数字画了出来。

这就是为什么”生存优先”不是一句口号。一个不可能破产的回测,只要给它足够多的配置去搜索,总会最终浮现出一个看起来像天才的配置——不是因为那个配置好,而是因为搜索在耐心地开采你模拟器的盲点。那个唬人的数字是症状。那个缺失的破产才是病根。

那个无趣的修复

修复很不光鲜。仓位大小变成了账户的一个小小的固定比例,而不是整个账户,这样一来盈利就无法滚成荒唐的雪球,亏损也无法变成孤注一掷。模拟器有了一个真正的毁灭条件:跌破一个最低生存余额,这次运行就结束,标记为死亡,到此为止。它还有了一个最小订单大小,这样那些小到在真实市场里根本不存在的交易,就无法悄悄给一个垂死的账户续命。

这些都算不上什么聪明的点子。它们里头没有洞见,没有优势。它们只是模拟终于肯服从那些现实从不松动的约束——不会饶过你的成本、并非无限的流动性,以及一个你回不来的零。建立一个诚实回测的大部分工作恰恰就是这个:不是让它更聪明,而是拒绝让它作弊。一个诚实回测的首要职责不是给你看利润。而是有能力给你看毁灭。

我为什么不再相信好消息

接下来是让人难受的部分。那个 bug 很简单。难的是,我差点就没去看——因为那个数字对我有利,而我想要它是真的。一个与你相左的结果会被盘问。一个奉承你的结果会被相信。

这种不对称,正是这项工作里大多数自欺所栖身之处。问题不在于人们找不到自己的 bug;而在于一旦某个 bug 开始给他们发钱,他们就停止去找了。市场最终会为你从未核查过的每一个舒服的假设收取全价——但回测会乐呵呵地让你把那个假设揣上好几个月,因为它在构造上,就是那个出错不必付代价的唯一地方。

它真正改变了什么

所以我从一笔虚假的万亿韩元里留下的纪律,几乎和仓位大小毫无关系。它改变了我信任的次序。一个好看的结果如今是有罪推定,未经证明清白之前都算有罪:在我问”它是怎么做到这个的?“之前,我先问”这里有什么坏掉了?“——而且我会刻意地,赶在市场动手之前自己去把它弄坏。只有经受住这种敌意对待还活下来的结果,我才允许自己去相信,而它们的数量远比我希望的要少得多。

一个不可能输光一切的回测器不是乐观。它是在撒谎。而它能撒的最危险的谎,正是那个你本就盼着听到的谎。

— 无信号,无收益,非投资建议。