记录一次策略的体检(2026-08-05)

一条策略的体质,不是它今天赚了多少,是它亏的时候怎么亏。

08-05 白天做了一次修复。修完一处,按惯例要给场上的策略重新量一遍收益——把"修之前"和"修之后"分开看,否则修了等于没修。

这次体检的对象是两条在跑的策略:24 小时持有周期的反转策略 factor_ic,和看资金面的 market_flow。下面这份,是那天的体检记录。


修复之后,先把基线钉住

修完一处代码,最危险的不是改错,是默认它就修好了。

所以每次修复之后我都要重做一遍收益体检。它有两个作用:一是确认修复本身没带来副作用,二是把新的 realized_pnl 固定下来,当作下一段比较的基线。

08-05 修复完成时,账户的 realized_pnl 停在 +$19.74。这个数字本身没有好坏,它只是一个起点——后面所有"修复后表现如何"的判断,都要拿它当尺子。这一点很关键:如果基线没钉住,后面看到的一切变化,都分不清是策略的功劳还是记账的噪声。

两条策略,两种体质

体检不能把它们塞进一张表里比绝对值,因为两条策略的仓位、逻辑、失效方式都不一样。

策略 逻辑 仓位
factor_ic 24 小时持有周期的反转 $80 验证仓
market_flow 市场流量 —

factor_ic 一直被压在 $80 的验证仓上——小仓验证,确认实盘边际之后,再谈要不要放大。这不是因为它弱,恰恰相反:是因为"要不要放大"这件事必须由数据说话,不能由手感说话。

market_flow 是另一条逻辑,仓位也不是同一个量级。所以这次体检只看一个窗口:修复后的 46 小时,两条策略各自的净收益。

46 小时给出的答案

策略 修复后 46 小时净收益
factor_ic +$4.33
market_flow −$10.29

一正一负,分得很清楚。

market_flow 的 −$10.29 里,包含一笔 ARB 交易,单笔亏损 −$517.64。看到这个数字,第一反应是"是不是记账出错了"。但把账对了一遍:现金对账差额 −$0.89,正好等于手续费,账目自洽。也就是说,这不是算法或记账的 bug,是 market_flow 在这段窗口里,真的把之前挣的吐了回去。

体检的价值就在这里:如果不单独把两条策略的窗口收益拆开,你会被账户的整体曲线骗过去——一条在慢慢赚、一条在慢慢亏,加在一起可能只是"不涨不跌"。拆开之后才知道,是一个在托着另一个。

19:35 那条太早的结论

体检当天,账面上还有一条容易被忽略的记录。

08-05 19:35,那条 48 小时归因 cron 跑了一次。 它当时只积累了 5.5 小时 的样本——连它自己窗口的八分之一都不到——就已经把 market_flow 标成了"加仓候选"。

这是自动化归因里最隐蔽的一类错误:cron 不会告诉你它样本不够,它只会给你一个结论。

5.5 小时里,市场流量恰好顺风,于是它看起来"该加仓";可 5.5 小时连一次完整的行情翻转都覆盖不到。等修复后 46 小时的完整样本回来,这个"加仓候选"的方向,和实际结果是相反的。同一条策略,5.5 小时说加,46 小时说不要。

所以那天我把这条也写进了记录:看到任何归因结论之前,先问一句"它背后有多少样本"。 结论谁都会给,问题是这个结论撑不撑得住。

最后

那天的收获得分三层。

最表面的是两个数字——factor_ic +$4.33,market_flow −$10.29,一个正一个负,干净分明。

中间一层是那条方法:修复之后必须先体检、再谈加仓;而且要当场把 realized_pnl 的基线钉死。基线不钉死,后面每一个"变好了"的判断都是站不住的。

最里面一层,是对样本量的敬畏。 5.5 小时的样本能吐出"加仓候选"这四个字——这件事本身比那两个收益数字更值得记。自动化会忠实地把结论送到你面前,但它不会替你考虑:这个结论的样本,够不够格。

一条策略的体质,从来不体现在某一天的盈亏里,而体现在——样本还不够的时候,你选不选择等。