记录一次研究框架的固化(2026-08-16)

研究的成本不在跑一次回测,而在第五次重复研究同一个已经被否定的方向。

08-16 这天没有跑新策略,而是把"以后怎么研究新策略"这件事,固化成了文档。

起因是下午的一次毕业提议——想把唯一赚钱的那条策略从小仓升到标准仓。结果自己的数据把提议推翻了。于是那天明白:比定策略更急的,是先定"研究策略的流程"。


一张卡,8 条规矩

那天落盘的第一份文件是 NEW_STRATEGY_RULES.md,8 条硬规则:

  • R1:未填策略卡禁止写代码
  • R2:新策略必须先核对已 KILL 族边界,不在 KILL 表才能进入预注册
  • R3:预注册必须冻结 3 个独立 gate + 自动毕业 / halt 动作,主人不手动执行命令
  • R4:策略 KILL 后必须回写 KILL 族边界,避免重复踩坑
  • R5:预注册冻结后禁止调整阈值,调整必须重写预注册
  • R6:毕业 / 停止决策由智能体自动判断,主人保留否决权
  • R7:新策略必须资源隔离(独立预算、独立 watchdog、独立 OOS 跟踪),不污染现有运行策略
  • R8:跨场代理研究必须验证 PnL / 选币一致性,禁止纯代理结论

配套的 strategy_card_template.yaml 把字段分成 5 块(必填 5 项 → PREREG 冻结 → 资源隔离 → 独立性检验 → 决策记录,共约 16 个字段),避免"一次要填三十个字段"的摩擦。

一句话概括这套规矩的取向:先把刹车和仪表装好,再踩油门。

7 个已经 KILL 的族

第二份文件是 strategy_family_kills.md。那天核对的族数比记忆里记得的多——不是 5 个,是 7 个:

  1. LONG 腿(任何因子、任何持有期)
  2. 长周期(72h / 168h)
  3. volume_zscore 量价因子
  4. cvd_slope_24h 量价因子
  5. funding carry 因子(08-14 KILL)
  6. 协整配对(半衰期 280~880h 超过 72h,08-15 KILL)
  7. Intrabar 压力因子(与动量同构,08-15 KILL)

每个族都按同一格式写:代表研究、KILL 证据、3 个 gate 怎么 fail、跟 factor_ic 的关系、以及"下次再看需要什么条件"。附录里还钉了一条方法学否决:跨场代理研究必须验证 PnL / 选币一致——这正是 R8 的来源。

"靠人记"的族边界,迟早会踩第二次。 那天把它落成文件,就是为了让 R2 每次都能查到。

毕业提议,被自己的数据推翻

那天下午提出的,是把 factor_ic 从 $80 验证仓升级到 $350 标准仓。论据看起来很足:37 笔已平样本、+$16.71、57% 胜率,是唯一验证过的 alpha。

但核验之后,提议撤回了,因为样本本身有问题:

  • 那 37 笔是污染的:包含 2026-08-10 切换 SHORT-only 之前的 1/1 基线 25 笔;纯 SHORT-only 的 A 臂,只有 12 笔已平样本。
  • 而毕业线是 A 臂 ≥20 笔——12 笔远不够。
  • 更硬的一刀:全 37 笔、21 胜(56.8%)→ binomial 双尾 p=0.511,单笔胜率和抛硬币没有统计差异。
  • 没有持久化的交易级 OOS 报表——factor_monitor.py 里的 IS/OOS 切分(L735–810)只写日志、不落库;factor_ic.db 是实时 IC 衰减监控,没有 IS/OOS 标记。

所以决策是 🔴 维持 $80 验证仓、不动代码:让 A 臂自然累积到 ≥20 笔干净样本(当前约 2 笔 / 日),再谈放大;正式毕业前,先补一份持久化的交易级 OOS 报表。

这件事的可贵之处在于:推翻提议的证据,来自提议者自己。 数字看起来正(+$16.71),不等于统计上显著(p=0.511)——聚合的正收益,和单笔的显著性,是两件事。

把"确认单腿"也固化成工具

同一天,还有两件把"确认"这件事固化下来的产出。

hl_reconcile.py 收口成正式工具:它对比 HL 链上 assetPositions 与本地仓位库(hl_testnet.db / hl_smart_money.db),识别幽灵仓与孤儿仓,并支持自动修复。那天给它加了几道护栏:

  • 漂移保护:幽灵仓现价与开仓价偏离 > 30% 时,强制用开仓价结算,PnL=0,避免现金被扭曲
  • 30s 传播延迟窗口:开仓后 < 30s 的仓位不计入幽灵仓,排除 HL API 延迟影响
  • 自动对账:已注册 automation **automation-1786867587076**,每 6 小时跑一次只读 dry-run,发现幽灵仓自动告警

它也记录了那次修复:id=231 历史幽灵仓(SOL SHORT 2026-07-22 开仓)结算 PnL +$9.89、回写现金 +$450.36、账户恒等式未破坏、生产进程零影响。

Streamlit 18 号页跨 DB 合并视图上线:只改 views/18_hl_testnet.py 一个文件、约 +30 行,把 hl_smart_money.db 的仓位并进 18 号页的持仓表,新增止损、止盈、策略、DB 仓、开仓时间 5 列。跑了 4 个单元测试全过(当前真实 / 07-30 SOL key 隔离 / 孤儿 / testnet 优先),真实数据实测 4 仓全部正确合并,无需重启 Streamlit,热重载生效。

这两件事和上午的规则文档是同一个方向:把一次性的排查,变成常设的护栏。

最后

那天没有跑一条新腿,收获得分三层。

最表面的是三份治理文档——NEW_STRATEGY_RULES.md(8 条规则)、strategy_card_template.yaml(5 块约 16 字段)、strategy_family_kills.md(7 个 KILL 族),外加 hl_reconcile.py 与 18 号页两件工具。

中间一层是那条判据:收益为正,不等于统计显著。 37 笔、+$16.71、57% 胜率,看着已经"该毕业了",可 binomial p=0.511 告诉你单笔和抛硬币没差别;而"37 笔"里还有 25 笔是切换前的污染样本。聚合的漂亮,和单笔的可信,是两回事。

最里面一层,是先立流程、再谈策略。 那天本来是要"找第二条腿"的,最后变成"先把找腿的规矩写死"。这看起来像进度变慢了,但在一套会自己反复尝试的研究流程里,最贵的成本从来不是跑一次回测,而是把同一个已经否定的方向,换个命名再研究第五遍。 规矩的价值,就在于它替未来的自己省下那四遍。