假 PnL 追踪到链上未知仓位,smart-money 保证金被占死(2026-09-22)
真正让 trader 停摆的不是某个策略赚不到钱,而是链上有一批它自己根本不知道的仓位,正死死占着保证金。 今天这份复盘,本质上是把 09-11 那笔 -$98.57 的 orphan_reconcile 假损失给翻了个底朝天——最后发现我们之前一直在跟自己的影子打架。
一、早上先查盘面:11 天没开新仓今天 09:58 我启动诊断的时候,第一反应是“别又是策略逻辑写挂了”。psutil 里能看到的一串进程全是 ALIVE:smart_money_trader 10s 主循环在 tick=140,smart_money_signal 每 15s 左右写一次日志,watchdog 09:54:36 刚跑完一轮,streamlit_dashboard 端口 8501 返回 HTTP 200。看起来系统全活。
再看 sm_account 表,09:47:40 的快照写着 current_usdc=10045.98,realized_pnl=+51.19,W/L=58/57。单看这个账面,trader 就是“没在交易”,不是死了。
但 ...
130秒规律暴露心跳守卫误判,交易worker反复重连(2026-09-10)
最危险的不是进程死了,而是它还活着,却已经很久没说过一句话
这天前后处理了几件看起来不相干的事:换掉一个 VLM 模型、给一个本地转发进程补 timeout、修交易 worker 的心跳、核正一份自动判定、读一份策略审计。等它们在记录里排到一起才发现,说的其实是同一件事——每一个长期运行的环节,都得持续向系统证明自己还活着。一旦它不再说话,系统不会立刻崩,它只会安静地做出一个错误的判断。
下面按当天实际处理的顺序记。
从一条 130 秒的规律开始监控里最先扎眼的是这个数:交易 worker 每隔约 130 秒就重连一次,节律几乎不抖。
反复核过之后,这个 130 秒不是巧合——它刚好等于连接守卫的超时阈值 + 平均一次重连所需的耗时。也就是说,重连不是网络断了,是被守卫"误判"成断了:它等了太久没等到该有的时间戳刷新,就按超时处理,断线,重连,然后 130 秒后再来一遍。日志里这种由"陈旧"引发的心跳超时,一次会话里数到了 3885 次。
顺着 _last_success_ts 往下挖连接守卫的判定本身很简单:当 _last_success_t ...
smart_money_trader 几千次心跳超时,每 130 秒重连暴露 120 秒阈值问题(2026-09-09)
心跳超时说的从来不是"连接断了",而是"没人告诉它还活着"
smart_money_trader 的日志里堆着几千次心跳超时。表面看是网络不稳,但一台机器如果真烂到每两分钟断一次,它早该被停掉了——交易进程却一直在跑,仓位也没乱。所以这次不猜,先把它拆开看。
这一天的活,从头到尾只有一件事:把"到底是谁在超时"查清楚。 修不修得好是第二步。
先看清风暴的形状先把原始日志预解析了一遍,而不是凭印象判断。
reconnect_preanalysis.json 记录的这场风暴,时间跨度是 2026-08-18T22:00:00 到 2026-09-05T13:57:21。进程侧的 _HEARTBEAT_TIMEOUT 是 120.0 秒,stall_profile.jsonl 里的分析确认了一件事:重连的节奏大约是 每 130 秒一次——正好对上"超时阈值 + 重连周期"。
预解析里还埋着一个更早的坑。第一次统计出来的心跳数是 4355,但这个数字是错的:它把 470 次 [SIGNAL] 守护进程的心跳超时, ...
OOS tracker 多轮扫描中 A2 样本冻结在 16,Hyperliquid 对账确认零幽灵仓(2026-09-06)
“在量化系统里,一整天零翻转、零幽灵仓,就是最好的巡检结果。”
今天从 00:55 的 A2 扫描开始,到上午的 Hyperliquid 对账结束,我基本都在做重复但必要的检查:两套 tracker 并行跑,一条短腿 HALT,一条长腿攒样本,最后再确认链上账本没有幽灵仓位。
一、A2 长腿:样本连续冻结在 16凌晨 00:55–00:56,A2 OOS tracker 第 28 次执行,命令是 factor_ic_oos_tracker_a2.py once,走 anaconda python,带 dangerouslyDisableSandbox:true 访问主网 K 线。这一轮结果非常干净:
Gate1 样本数:16,但 A2 阈值是 ≥30,所以直接 ❌;
Gate2 binomial p:1.0000(win 8/16),完全不显著;
Gate3 年化 Sharpe:-5.080,远低于 1.0;
Gate4 maxDD:412.4%,严重超限;
regime 上升率:75.0%(n=16),≥50% ✅ OK。
决策是 NO_ACTION——reg ...
重连逻辑误判网络抖动,trader 停摆 38 小时才定位 factor_ic 假 HALT(2026-08-29)
trader 不是代码坏了,是重连逻辑把网络抖动当成了死罪,而 factor_ic 的 HALT 只是监控标记,真正没停过交易。
今天从发现 hl_smart_money.db 的 mtime 停在 08-27 19:16 开始,一路查到 watchdog 反复拉起失败、readonly 假象、502 重连自杀,最后改掉 hl_connection.py 的 sys.exit(1),顺手把 factor_ic 的 HALT 登记落地。过程有点绕,记下来。
一、trader 停摆 38 小时:从 DB 时间戳发现不对劲早上第一眼看到 hl_smart_money.db 的 mtime 停在 08-27 19:16,距离当时约 1.5 天。trader 日志尾部显示“连续 11 次重连 502 失败 → 放弃退出”,但进程列表里却有几个 PID 存活。当时我还没分清哪个是真正的 trader,先做三件事:确认进程身份、核对日志时间线、看 DB 是否还在写。
核对结果:当前没有存活的 smart_money_trader.py 进程——只有 watchdog(78616) 和 signal( ...
OOS 连续 HALT 与账户残差排查,假漂移根因是口径错位(2026-08-27)
这一天的活儿,一半在证明系统没坏,另一半在说它其实坏在看不见的地方——automation 把三次失败吞得干干净净,直到我手动跑了一次 tracker 才见到真报错。
今天从一条刺眼的 17.51% 漂移开始,本来以为账户又出大问题,结果口径一换就是 0.08% 的正常波动。后面大半夜都在跟 OOS tracker 和账户对账较劲,中间还顺手发了一篇知乎文章。写到复盘的时候天都快亮了。
一、17.51% 是假警报,正确口径只有 0.08%凌晨刚开始跑 _verify_reset.py 做只读核验,一上来就看到漂移 17.51%,心里咯噔一下。结果细看才发现这是旧口径的假警报:脚本直接拿 accountValue 跟 current_usdc 比,但 current_usdc 是可用现金,不含锁仓保证金,两个根本不是同一个基准。
换成总值 vs 总值的口径后,sanity 检查就正常了:
DB 侧可用现金 751.72 + 在仓保证金 160.34 ≈ 912.06
链上 911.30
残差只有 **0.08%**,完全 OK
这个教训又重复了一遍:对账前先看字段定义,不然白白吓自己 ...
同一晚四个异常叠加,样本外停写三天根因在调度器与全局变量缺失(2026-08-23)
一晚上三条"死因",长得像同一个症状
有些夜里,你会以为在处理一个 bug,其实是四个。那天从 OOS 停写查起,查到最后发现:一条 3 天的数据空洞、一个设错位置的超时、一笔拖了 4.6 天才被硬止损的仓,还有一行缺了 global 的赋值。它们互不相干,却在同一晚一起发作。
一、停写三天的 OOS先看最表面的:factor_ic_oos.db.oos_ticks 从 08-20 18:08 之后就再没写入了,空了 3 天。
runtime_state 给出了另一半答案:next_run_at=None,last_run_at=1787220565(≈08-20 18:08)——调度器在那之后就没再排下一次运行。automation 配置本身还是 ACTIVE,状态显示正常,那只是假象。
代码侧的根因,是 compute_regime()(L177)里的 fetch_candles 没有任何 try/except:
沙箱/网络异常 → fetch_candles 抛异常 → 冒泡到 main()(无顶层捕获)→ 整个脚本崩溃;
Gate1- ...
A1交易栈静默四十小时,罪魁是计划任务启动命令拉不起Python(2026-08-18)
今天的教训:进程僵死往往不是代码崩了,而是那条 start /MIN cmd /c 启动命令在无桌面的计划任务会话里根本拉不起 python。
早上照例去核 A1 的 OOS 监控,本想确认下样本数够没够,结果顺着 tracker 那个一动不动的 tick,挖出一个交易栈整整静默了 40 小时的大坑。下面按我当天的排查顺序记下来。
一、核 A1:tracker 数字没错,但 tick 冻结暴露异常先找到项目真实路径 C:\Users\Administrator\Documents\craw_app1_wz\defi_dashboard,DB 都在。oos_ticks 从 08-17 的 5 行涨到了 20 行,说明自动化一直在跑。但 tracker 自报 gate1_n=17,我直接数 factor_ic SHORT closed 却有 29,第一反应是不是 tracker 有 bug。
按铁律「自报字段不可信,须逐笔重算」,我开始独立复算。结果跟 tracker 对不上:我数 OOS(closed≥08-10)是 18 笔 / maxDD 57.2% / p ...
hl_testnet.db 对账发现 25 天 SOL 空单与链上多单对不上(2026-08-15)
数据库里说开着一笔空单,链上却是多单——那一刻要确认的,是这一条腿到底是不是真的。
08-15 例行对账时,发现 hl_testnet.db 里躺着一条很老的 OPEN 记录。对账这件事平时看起来很枯燥,但它偶尔会拽出一笔"幽灵仓"——数据库以为还开着的仓位,链上其实早就不存在了。
一条 25 天的 SOL 空单最先跳出来的是这一条:
hl_testnet.db 有 1 个 OPEN 仓:SOL SHORT @ $77.246,开仓时间 2026-07-22,距今约 25 天。
25 天没动的仓位,本身就不正常。这极可能就是 07-30 那一波"半平仓" 遗留下来的——当时 BTC / ETH / SOL 处理过一轮,通过数据库看,只有 SOL 这一笔没清掉。
DB 和链上,一张一张对判断它是不是幽灵仓,做法只有一个:把数据库里的每一个 OPEN,和链上的实际仓位逐一对照。
DB OPEN(sm_positions)
链上真实
一致?
ETH LONG @1891.3, $80
ETH szi=0. ...
模拟盘策略首跑即崩,属性访问与字典返回不匹配(2026-07-10)
模拟盘最坑的地方,不是它亏了钱,而是它让你以为策略已经能跑了
这天打开 http://0.0.0.0:8501/,主流币模拟交易那条曲线几乎全是红的。接下来的几个小时基本都在同一个循环里转:发现一处数据不对,翻代码,改掉,重启,然后发现下一处不对。
下面按当时踩到的顺序记。
第一次运行就崩maincoin_paper.py 里 scan_signals() 返回的是 dict,但 run_tick() 全程用属性访问:sig.confidence、sig.signal.value。所以第一轮 mc_paper_loop 一起来就崩了。
改成 sig["confidence"]、sig["signal"],顺手删掉没用的 Signal import。这个 bug 的性质其实很典型——函数签名和调用方之间没有契约,写的时候两边各自都对,合起来就炸。
开仓时间和平仓时间一模一样翻交易记录时发现一件事:每一笔的 opened_at 和 closed_at 是同一秒,大量交易 duration=0s。
根因在 close_position 函数(第 19 ...