回测最容易骗人的地方,不是指标。
是名单。
你以为自己在问:“这个策略在过去一段时间表现如何?”
但如果标的名单不对,实际问出来的问题可能是:“这个策略在一批事后看起来还不错的标的上表现如何?”
这两个问题差别很大。
实盘交易不是面对一个抽象市场。
系统在每个时刻能交易什么,取决于当时的筛选规则、数据状态、交易所状态、流动性、风控限制,以及程序实际保存下来的 universe。
很多回测会默认跳过这一层。
拿一段历史 K 线,拿当前可交易标的列表,套上策略逻辑,跑出收益曲线。这个流程看起来很自然,因为代码能跑,图也能画出来。
但它隐含了一个很强的假设:今天这份标的列表,也代表过去那个时间点系统能看到的标的。
这个假设通常不成立。
一只标的今天还在列表里,可能是因为它后来活下来了、涨上来了、成交量变好了。一只标的今天不在列表里,可能是因为它后来跌没了、下架了、流动性变差了,或者只是后来不符合筛选条件了。
如果回测时只使用今天的名单,历史就被重新筛选了一遍。
这就是幸存者偏差。
很多人提到幸存者偏差,会下意识认为它一定让回测收益变好。
不一定。
在股票市场里,长期留下来的公司往往更强,剔除退市公司后,回测结果容易变得更好。这是最典型的情况。
但在短线或加密市场里,情况更复杂。
有些后来消失的标的,在当时可能有极强的波动和流动性,正是短线策略最容易赚钱或最容易亏钱的地方。把它们删掉,不一定让收益更好,也可能让风险看起来更低,或者让策略错过当时真正的交易机会。
所以问题不只是“收益有没有被高估”。
更根本的问题是:回测对象已经不是当时那个市场。
只要对象变了,后面的收益、回撤、胜率、交易次数,都只能算在另一个问题上。
这也是为什么我现在更关心 universe 的时间一致性,而不是只关心回测程序能不能跑起来。
听起来最理想的回测,是拥有全市场完整历史数据。
这当然好。
但对一个实盘系统来说,还有一个更具体的问题:线上系统当时到底选择了哪些标的?
全市场历史回答的是“理论上可以交易什么”。
真实 universe 回答的是“我的系统当时实际会看什么”。
这两个答案都重要,但它们不是同一个东西。
如果我想评估一个策略思想在整个市场上的普适性,全市场历史更有用。
如果我想评估一次策略改动对当前系统有没有帮助,真实 universe 更有用。
因为实盘不会在全市场里手动挑最适合的标的。实盘只会按照系统当时的筛选结果运行。
策略改动最终也是作用在这个筛选结果上。
所以对我来说,真实 universe snapshot 的意义不是让回测更华丽,而是让回测问题更诚实。
它把问题从:
“这个策略在历史上表现怎么样?”
改成:
“如果当时系统就是这样运行,这个改动会让结果变好吗?”
后者更窄,但更有用。
做这件事还有一个坑。
你把历史 universe 保存下来了,不代表回测真的用了它。
程序里很容易出现这种情况:
这类错误很隐蔽。
因为结果仍然会正常产出。没有异常,没有崩溃,甚至指标看起来还挺合理。
但你验证的已经不是历史场景。
所以回测需要一个明确的验收点:它必须告诉你本轮 universe 的来源是什么。
不是“我有没有复制历史数据”。
而是“本次计算实际使用的 universe source 是不是历史记录”。
这类检查看起来很琐碎,但它比多跑十个指标更重要。
因为如果样本源错了,指标越多,只是错得越精细。
我现在对回测的要求变得更朴素:
尽量像当时。
不是尽量复杂,也不是尽量全。
当时系统用什么 universe,就用什么 universe。
当时系统按什么时间粒度看数据,就按什么时间粒度。
当时系统有什么风控和仓位限制,就保留这些限制。
当时系统不会知道后面哪只标的会爆发,回测也不应该知道。
这个原则看起来简单,但实际很容易被破坏。
比如一次策略优化里,为了方便调试,你临时扩大了标的池。又比如为了让样本更多,你把 current latest universe 作为 fallback。再比如为了避免空结果,你在历史缺失时自动退回当前配置。
这些 fallback 在普通业务系统里可能是容错。
在回测里,它们可能是污染。
因为交易回测的目标不是“尽量跑出结果”,而是“尽量回答正确的问题”。
如果回答不了,应该明确失败,而不是悄悄换一个问题继续回答。
手工做策略时,很多东西其实在脑子里。
你知道自己当时看的是哪几只票,知道某个机会为什么没做,知道某个标的当时流动性很差。即便复盘不严格,人的记忆也会补上一些上下文。
系统化以后,这些上下文会消失。
程序只认数据。
如果没有把当时的 universe 存下来,过几天再回头看,就只能猜。
工具越自动化,越不能依赖“我大概记得”。
因为自动化系统会把很多微小决策放大:一个筛选条件、一个 fallback、一个默认值,都会影响后面的交易路径。
所以真实 universe snapshot 本质上不是一个回测功能。
它是记忆。
它让系统记住自己当时看见的市场,而不是让今天的你替昨天的系统重新选择一次市场。
回测不是把策略放进历史行情里跑一遍。
更准确地说,回测是在重建一个过去的决策环境。
行情只是环境的一部分。
标的名单也是环境的一部分。
执行约束也是环境的一部分。
如果 universe 错了,回测就不是轻微失真,而是问题本身变了。
所以我现在更愿意先把这类基础问题做扎实:保存当时的 universe,确认回放真的使用它,在结果里暴露 source,而不是只看最后的收益曲线。
收益曲线很直观。
但在它出现之前,先要确认一件更基础的事:
你回测的,到底是不是当时那个市场。
本文创建日期: 2026-06-14
最后更新日期: 2026-06-14