记录一次 Hyperliquid testnet 只读巡检与归因(2026-09-28)
记录一次 Hyperliquid testnet 只读巡检与归因(2026-09-28)
只读不写是今天所有操作的第一原则,而样本量不足时,不出结论就是最正确的结论。
今天在 C:\Users\Administrator\Documents\craw_app1_wz\defi_dashboard 做了三件只读的事:HL testnet 对账巡检、策略级归因分析、factor_ic OOS tracker 双轨扫描。一整天下来,没动一行策略代码、没重启任何进程、没写一次生产库。以下按时间顺序复盘。
一、HL testnet 只读对账巡检
上午先跑 hl_reconcile.py,默认 dry-run,不加任何写参数。启动前必须先把系统代理变量清空,否则容易 502:
1 | set HTTPS_PROXY="" |
然后执行:
1 | C:\ProgramData\anaconda3\python.exe -u hl_reconcile.py |
结论很干脆:
- 🟢 Ghost 仓位:0 —— 两个库 DB 标记 OPEN 的仓位在链上均存在,含方向反检查,无脏仓。
- 🟡 Orphan:4 —— 仅
hl_testnet.db链上有而 DB 无,标的分别是 SOL/BTC/ETH/ARB,脚本只告警不自动修复。 - OPEN 数量:
hl_smart_money.db= 4,hl_testnet.db= 0。 - 账户等式:脚本本身不打印权益守恒,逐笔重建残差历史 ≈0;两库自报 account 行 initial/current ≠ 10000 是已知记账损坏,不属于 ghost/orphan 范畴。
- **无需
--apply**:因为没有 ghost,orphan 按设计不修复,智能体不自行写库。
这里有个细节值得记住:gnost 和 orphan 的处理逻辑完全不同。有 ghost 才需要 --apply 写库,orphan 只是告警,不自动入库。 今天 0 ghost,所以 dry-run 结束,什么都没改。
二、策略归因:样本量闸门卡死结论
下午做 Hyperliquid testnet 模拟交易策略的策略级归因分析。这次我给自己定了一条死规矩:先判样本量闸门,再谈加仓/降级/退役。 上次 2026-08-05 只积累 5.5h / 6 笔样本就断言 market_flow 是加仓候选,46h 后被推翻为净 -$22.50,这次不能再犯。
归因区间起点取最近一次真实配置变更时间,从 smart_money_trader.py 里 DISABLED_STRATEGIES 附近的日期注释和日志反查。最终确认:
- 2026-09-26 的 restart 只是 process recovery,RISK 打印
SL=5.0% TP=4.0% MAX_POS=12 SIZE=$350 验证仓=$80与当前源码一致,不是配置变更。 - 真实配置变更发生在 2026-09-20,当时重新验证了
DISABLED_STRATEGIES和 per-strategy RISK override。 - 所以归因区间起点 = 2026-09-20,到现在大约 213h,≥24h ✅。
但第二道闸门直接卡住了:区间内信号驱动平仓笔数 factor_ic=2、sentiment=4,其余策略全部为 0。所有在役策略 < 10 笔。 按规则,任一策略样本 < 10 笔,只能写「样本不足 N 笔,维持现状继续观察」,禁止写加仓/退役建议。所以最终报告结论就是:本次不出任何加仓/降级/退役建议,全部维持现状。
不过归因过程中挖出三个关键发现,比结论本身更重要:
- 权益暴涨是假象。 账本从 09-14 的 $10,046 跳到 $12,886,其中 $3,166 来自
orphan_reconcile_adopt——23 笔链上孤儿仓清理入账,avgHold=0h、平仓费=$0,根本不是信号驱动的策略 alpha。剔除后真实策略权益 ≈ $10,140,基本持平 09-14。如果不剥离孤儿仓,归因结论会被彻底带偏。 - 账本 epoch 分裂 BUG 已彻底修复。 重建权益 − OPEN 名义 = 12,885.72,
sm_account.current= 12,885.69,差 $0.03,不再报 BUG。 - 账户恢复低频活跃。 4 笔 OPEN 全 LONG(BTC/ETH 等),最近开平仓都在今天。
顺便说一句,sm_positions 表结构确认:id(不是 pos_id)、strategy、status ∈ {OPEN,CLOSED}、close_reason、pnl_usd、fee_usd、size_usd、opened_at、closed_at、side、symbol。字段名要写对,不然 SQL 直接报错。
三、OOS tracker 双轨扫描:A1 HALT,A2 NO_ACTION
晚上跑 factor_ic OOS tracker,A1(SHORT)和 A2(LONG)两个臂分别独立扫描,只读 hl_smart_money.db 和 factor_monitor 主网 K 线,只写 factor_ic_oos.db 和 docs/strategy_research/_prereg 下的日志/alerts。
A1(SHORT 臂)当天多次扫描,结果稳定一致:
| Gate | 实测 | 阈值 | 判定 |
|---|---|---|---|
| Gate1 样本数 | 31 | ≥20 | ✅ 通过 |
| Gate2 binomial p | 0.7201(win 14/31) | <0.05 | ❌ 不显著 |
| Gate3 年化 Sharpe | −2.732(×√504) | ≥1.0 | ❌ 失败 |
| Gate4 maxDD | 320.9%(写库真值 3.2089) | ≤30% | ❌ 硬超限 |
| regime 回落率 | 37.0%(n=27) | ≥50% | ❌ HALT |
决策:HALT —— regime 回落率 <50%,因子级 forward return 持续不达标,factor_ic 信号源判为失效。注意这里的 maxDD 320.9% 是真实值,不是格式化 bug;网络正常,主网 K 线拉取成功,regime 是真实信号而非 UNKNOWN 降级。
A2(LONG 臂)当天也扫了多轮,前两轮结果:
- 第 73 轮(21:31):n=18,Gate1 fail(<30),Gate2 p=0.8145,Sharpe −6.186,Gate4 写库真值 4.1244(≈4.12%,stdout 打印 412.4% 是格式化 bug),regime 上升率 66.7% OK → NO_ACTION。
- 第 74 轮(23:38):n=19,Gate2 p=0.6476,Sharpe −7.477,Gate4 写库 4.2782,regime 66.7% OK → NO_ACTION。
A2 的样本数始终没过 30,所以路径停在 regime=OK → Gate1 fail → NO_ACTION,没有触发任何 HALT/MID/BLOCK/GRADUATE,也没有写 pending_log。另外 A2 的样本池只取 side='LONG' 的 CLOSED 腿(最近 60 天,非 reconcile),和 A1 的 SHORT 臂并行不串扰。
隔离原则的验证也很干净:三个关键生产文件 mtime 未因本次只读扫描改变;smart_money_trader.py 的 09-23 改动是独立事件,与今天无关。扫描脚本只写 factor_ic_oos.db(tick id=473,arm=SHORT, 21:35:28;后续 LONG 臂 tick 也独立写入)和 _prereg 下的 factor_ic_oos_alerts.md、halt_log.md(PENDING),没有任何生产策略文件被触碰。
四、三个最值得记下的判断
第一,orphan 清理会污染归因。 orphan_reconcile_adopt 这 23 笔入账贡献了 $3,166 的权益跳升,但 avgHold=0h、平仓费=$0,本质上是一次链上清理的记账修复,不是策略收益。如果不按 close_reason 把 reconcile/cleanup/运维 closes 剥离出去,任何归因都会高估策略表现。
第二,样本量闸门必须前置。 今天所有策略的信号驱动平仓都不足 10 笔,所以即使有 213h 的时间窗,也照样不敢下结论。所谓「不做判断」本身就是一种结论——维持现状、继续观察。
第三,A1 的 HALT 和 A2 的 NO_ACTION 是两套独立逻辑。 A1 因为 SHORT 臂 forward return 回落率 <50% 直接判失效;A2 做多视角要求上升率 ≥50%,样本 18/19 笔不够,所以连 Gate1 都过不去。不要看到 A1 HALT 就以为 A2 也会 HALT,它们的阈值、regime 方向、样本池过滤条件都不同。
五、遗留
- 策略归因依然无结论。 factor_ic、sentiment 等所有在役策略样本均 <10 笔,需要等更多真实平仓积累。下一次归因必须重新检查 DISABLED_STRATEGIES 附近注释,确认是否有新配置变更。
- A1 的 HALT 只写入了 halt_log.md(PENDING),没有执行任何毕业/阻断动作。
factor_ic_oos_apply.py --confirm今天没有调用,后续需要人工审核决定是否对 factor_ic 信号源做降级或下线处理。 - 4 个 orphan(SOL/BTC/ETH/ARB)仍然留在 hl_testnet.db 链上。 只告警不自动修复,需要用户确认后决定是否手动处理,今天没有动。
- A2 样本冻结中。 第 74 轮增长到 19 笔,但离 ≥30 还有距离,继续每日单次扫描即可。
这一天最大的收获不是发现了什么惊天 bug,而是再次确认:在量化系统里,只读巡检和样本闸门是最便宜、也最有效的防线。 写库的动作永远要留在最后、留在确凿证据之后。