记录一次影子策略真值重建与换仓(2026-07-28)
记录一次影子策略真值重建与换仓(2026-07-28)
“页面上的累计盈亏全是假的,真相只藏在每笔成交里。”
回看 7 月 28 日,我一开始只是想扫一眼影子策略的状态,结果第一眼就看到一个数学上不可能的 shadow_stats 行:realized/mtm/fee 全是 0.00,net_pnl 却不是零。这一天后面全耗在把真值从一笔一笔成交里刨出来。
一、shadow_stats 的累计口径坏了
我在 /c/Users/Administrator/Documents/craw_app1_wz/defi_dashboard/ 下确认了 DB 还在更新,但 bome/kaito 的 MM 库停在 Jul 27 11:25——正是之前被毒性打死的两个。真正的问题是后来盘 shadow_stats 时看到的:最新行 realized/mtm/fee = 0.00 但 net_pnl 非零。净 = realized + mtm − fee − funding,这组数字在数学上不可能同时成立。
排查后的结论是:我们为治 429 限流重启过 10 个进程,shadow_stats 里那些累计字段(realized_spread / net_pnl)写在进程内存里,重启即归零,但 shadow_fills 表保留每一笔成交。所以页面若读最新 stats,累计盈亏会和真值偏到 ±$59:比如 AIXBT 内侧可能显示 +$52.66,真值是 −$6.74;ACE 内侧显示 +$28.03,真值 +$61.85。
为了避免被内存数字忽悠,我重新写了 shadow_report.py,直接从 shadow_fills 逐笔重建。用没被重启过的 GRID 库做交叉验证:grid_bome 重建 +37.08 = 页面 +37.08,grid_gala 重建 −39.08 ≈ 页面 −39.07,吻合到分。这个重建口径是可信的。
二、重建后的真值:没有一个策略能稳健盈利
第一版重建还踩了两个坑。total_notional 一度把 qty 当 size_usd 求和,算出 3500 万的荒谬数字;后来发现 size_usd 才是第 6 列,改回来才对。另外 st 字典查 mid/inventory_usd 返回 0,也是行工厂没写干净。
修正后,真值很直接:在诚实的基础费率 +0.015%、无返佣下,当时组合净亏 −$746,成交额 $2.53M。 12 个策略里 8 个连正 spread 都没吃到,逆选(成交后价格反向跑)普遍为正。唯一在基础档还是正的是 mm_ace(+26)、grid_bome(+33)、grid_ace(+14),但成交额只有 19k–178k,属于一放大就死的那种。
三、停掉 7 个输家,保留 3 个赢家
既然基础档已经证伪,再留着就是每天烧真钱。当天停掉 7 个仍在跑的输家:
- 内侧做市:BTC、AIXBT、kBONK、MET、GALA
- 网格:KAITO、GALA
加上早前已停的 KAITO/BOME 内侧,累计 9 个输家下线。保留的 3 个赢家 mm_ace(+$26)、grid_bome(+$33)、grid_ace(+$14) 的历史 DB 续写,没丢数据。
四、换上一篮子新候选,结果 CASHCAT 启动就炸
重扫全部 232 个永续,严格过滤后只有 2 个合格,太窄。真正的杀手是毒性/逆选,扫描器量不出来,只能跑起来让市场告诉我们。于是按“宽价差低量 ↔ 高量快信号”光谱挑了 7 个新内侧做市候选,和 3 个赢家一起共 10 个进程。
第一次批量启动就出事:CASHCAT 在启动阶段报 ConnectionResetError,在 init_db 之前就 FATAL 退出。原因是 10 个进程同时锤 7890 代理,它的单次 L2 预检没有重试——主循环有重试,启动预检没有。我把两个脚本的启动 L2 预检都加了重试,单发重启 CASHCAT,之后 hl_shadow_mm_cashcat.db 在 13:34 出现了成交,确认活过来了。
最终 DB 核对:3 个赢家历史完好(mm_ace 2955 笔、grid_bome 392 笔、grid_ace 335 笔),7 个新候选都开始累积真实成交:PUMP(11)、kPEPE(8)、VVV(8)、FARTCOIN(7)、AAVE(6)、kSHIB(5)、CASHCAT(1)。没有空格,全部在交易。
五、8 小时后的终审:不是没试够,是结构无边缘
新候选跑了约 8 小时后,我又拉了一次全样本重建:
| 值 | |
|---|---|
| 累计成交 | 33,311 笔 |
| 累计成交额 | $2.86M |
| 净盈亏(返佣 −0.005%) | −$286.56 |
| 净盈亏(基础 +0.015%,无返佣) | −$858.54 |
| 已实现毛差(没算手续费就亏的) | −$396 |
也就是说 $2.86M 的模拟成交额,最严费率下亏 0.03%/成交额。 唯一“赢家” mm_ace 基础档也只 +$73,只跑 34 小时、单币、成交额 $216k;参考 kaito,成交额到 $780k 时基础档 −$280,放大就死。
为什么不是没试够?因为覆盖度已经够了,问题在前两条硬约束:第一,我们只在测“怎么挂单”,没有“赌什么”的信号,纯执行策略在比所有人慢、没有私有信息时创造不出边缘;第二,逆选普遍为正,说明是知情单专门来挑我们的流动性,我们就是被吃的那一方。
六、下一步:跑统计显著性检验
当天最后决定,别再拍脑袋看净额正负,直接做三件更硬的事:对 mm_ace 的正收益做 bootstrap 置信区间和 t 检验;把运行时间切成 4 块看边缘是否跨时间稳定;再对“扫了约 20 个币才挑出 1 个正的”做 best-of-N 零模型模拟。脚本还没写完,留在下一步。另外 view19 要尽早改成读 shadow_report.py 的重建口径,否则页面数字会一直误导自己。