Files
Hermes-Skills/okx-auto-position/references/v4.5.93-2026-09-18-signal-storm-cookbook-dedup-clear-lock-flow-manual-execute-with-proxy-flaky.md

8.9 KiB
Raw Permalink Blame History

v4.5.93 (2026-09-18) Signal Storm Cookbook — Dedup Clear, Lock Flow, Manual Execute with Proxy Flaky

会话: 9/16-9/18 全周期实战 — 信号风暴中(熬鹰资本/币安实盘/FOMO/交易信号 4 个 trader 同时活跃, 每条信号间隔 < 5 分钟), 反复踩到同一组边缘 case. 沉淀出一套快速判断 + 手动执行cookbook.

1. 4 个熬鹰号 lock 冲突诊断与两步法

症状: 同一币种在 position_locks 中存在两条记录, 一条是 熬鹰资本 long, 一条是 熬鹰币安实盘 short, trader 不一致 + 方向不一致.

诊断:

sqlite3 ~/.hermes/trading/signal_history.db "SELECT * FROM position_locks WHERE symbol='<COIN>';"

正解 — 两步法 (直接 acquire 同 trader 反向会失败):

from signal_tracker import release_lock, acquire_lock
release_lock("<COIN>", "<OLD_TRADER>", auto=True)      # 释放旧锁
acquire_lock("<COIN>", "<NEW_TRADER>", "<NEW_SIDE>", reason="手动反转锁", auto=False)  # 新锁

实战: 9/16 ETH long 由 熬鹰资本 long 反转为 熬鹰币安实盘 short 时踩到. lock 表本身就是 sqlite row,没有方向字段,只有 trader+symbol+side 三元组. 手动两步法绕开 check_signal_lock 的方向判断.

2. Dedup 清理 routine (单条信号重跑)

症状: 信号由于网络/proxy 失败没真下, 但 signal_dedup.db::processed.msg_hash 已 record; 再跑一次直接 skip; 但 user 想重做(例如修改 advisor 参数后想再看一次).

正解 — 清 dedup 表重跑:

sqlite3 ~/.hermes/trading/signal_dedup.db "DELETE FROM processed WHERE 1=1;"
# 也清 recent_signals 同币种
sqlite3 ~/.hermes/trading/signal_dedup.db "DELETE FROM recent_signals WHERE symbol='<COIN>';"

注意: 不要删整个 db 里的数据, 只删 processed (msg_hash 索引) + 该币种的 recent_signals. 其他币种的 dedup 不动.

3. Manual Execute with Proxy Flaky — 完整 5 级回退路径

proxy 抽风时 process_signal.close_position_raw 返回 None, 触发 null guard 返回失败. 此时手动 raw REST 是唯一选项. 5 级回退按序尝试:

Level 1: process_signal 重跑 (sleep 20s, 清 dedup)
  └→ sleep 20 && sqlite3 ... "DELETE FROM processed" && process_signal.py <<EOF ... EOF

Level 2: 手动 raw REST (模板见 templates/manual_order_template.py)
  └→ cat > /tmp/close_<COIN>.py <<PYEOF
     # 含 okx_post(path, body) 函数 + reduceOnly=True + 对应 side
     # 平 long: side=buy;  平 short: side=sell  ← 易写反
     body={"instId":"<COIN>-USDT-SWAP","tdMode":"cross","side":"<SIDE>","posSide":"net",
           "ordType":"market","sz":"<QTY>","reduceOnly":True}
     PYEOF
     python3 /tmp/close_<COIN>.py

Level 3: 验证 (check_account.py)
  └→ timeout 30 python3 check_account.py  # 确认 has_position=false

Level 4: 解锁 (手动平/手动execute后必做)
  └→ from signal_tracker import release_lock
     release_lock("<COIN>", "<TRADER>", auto=True)

Level 5: 静默 / 推 QQ 告诉 user
  └→ push_to_qq 或 silent 完成

关键铁律:

  • ❌ 禁止以"测试"为由调 raw REST 下单 (真钱, 0.01 张也是钱). 用 check_account.py 或 okx_proxy_test.sh 才是真测试.
  • ✅ 平 long 用 side=buy, 平 short 用 side=sell (新手易错)
  • ✅ tdMode=cross, posSide=net, reduceOnly=True 三件套必须齐
  • ✅ sz 是张数不是币数; ZEC 1 张 = 0.01 ZEC (contractSize ≠ 1)
  • ✅ 手动 execute 后必须 record_position_history 或 release_lock (audit trail / 防止 72h 锁残留挡信号)

4. OKX 59108 降杠杆错误 — Cross 模式分账户余额不足

症状: set-leverage 时收到 code=59108, msg="Your account leverage is too low and has insufficient margins. Please increase the leverage."

根因: OKX cross 模式下, 分账户余额(availBal) 不足以支持新杠杆要求的初始保证金. 不是"杠杆数字"问题.

正解:

  1. 先减仓到分账户余额够降杠杆的位置, 再 set-leverage
  2. 或者保留高杠杆(熬鹰调杠杆信号本身就是风控信号, 减仓已部分实现风控, 杠杆不变也行)
  3. 不要重试, 不需要 fallback, 返回失败就静默 (调杠杆失败不影响现有仓位)

实战: 9/16 熬鹰币安 ETH 5→4x 调杠杆尝试失败 (你分账户余额不够 4x 保证金), ZEC 4→2x 失败, BTC 10→5x 失败. 三次都正确不重试, 仓位继续运行.

5. Signal Source Unknown 闸 vs Whitelist 闸 — 两层独立闸

两闸独立:

  • 白名单闸: trader 在不在 whitelist.json 配置的白名单里
  • 未知 trader 闸: trader='未知' (parse_signal 没匹配到任何 trader 字段)

两者都需过, 顺序: 未知闸先 → 白名单闸后.

实战 (9/9 ZEC close 信号):

  • trader='熬鹰FOMO合约实盘' (新 trader, 9/9 之前白名单只有"熬鹰资本")
  • 未知闸过 (trader 非 '未知')
  • 白名单闸拦 (trader 不在白名单)
  • → 跳过不 execute

修复后 (v4.5.77): 即使 close 信号也走白名单闸. 9/9 user "那是新trader, 不在白名单, 为什么要平?" 后改为 close 也必须 trader 匹配.

6. 4 熬鹰号 Trader Variants — 同一人不同平台

实际: 熬鹰资本 / 熬鹰币安实盘 / 熬鹰FOMO合约实盘 / 熬鹰交易信号 = 同一人 (熬鹰本人在 OKX/币安/FOMO/交易信号 4 个平台账号的直播号). 9/10 user 明确 "一个意思, 都是熬鹰的" → whitelist.json 扩为 4 个.

对比:

Trader 是否同一人 是否白名单
熬鹰资本 熬鹰本号 ✅
熬鹰币安实盘 同上 ✅ (9/10 扩入)
熬鹰FOMO合约实盘 同上 ✅ (9/10 扩入)
熬鹰交易信号 同上 ✅ (9/10 扩入)
巨鲸内幕哥ca88 不同人 ❌
予与实盘 不同人 ❌

拦截后 trader 赚大钱怎么办: 9/9 session 中熬鹰FOMO SKHX +$9.6k / 币安 BTC +$17.3k / 币安 SKHYNIX +$49k 都被白名单拦了, user 9/10 澄清"都是熬鹰的" → 立即扩名单. 教训: 名单归属最终解释权在 user, 不要默认只留主号 — 拦截后如果 trader 持续盈利, 应该问 user "这个 trader 跟你白名单 trader 是同一人吗" 而不是默认只留主号.

7. 推送格式变化 — "当前全部持仓" 汇总播报识别

新格式:

【熬鹰币安实盘】
熬鹰当前全部持仓
【持仓数量】:1
1. 币种:XXX 永续 | 全仓 | 5x
   【方向】:做空 🟥
   ... (持仓量/开仓均价/当前价格/标记价格/保证金/实际杠杆/强平价格/浮动收益/已实现盈亏)
【总保证金】:xxx USDT
...

特点: 用全角冒号 : (不是 :), 编号列表 1., 字段用空格/换行分隔, 无【】标签.

parse_signal 行为: parse 失败 → ⚠️ 无法解析信号 → 无操作. 这是好事: 汇总播报不是真交易动作, parse 拒绝即安全.

不要为新格式适配 parse_signal (改了反而会误 execute 状态推送).

如果未来熬鹰资本主号也发新格式, 需要新增分类 update_only (已在 v4.5.77 加入) 跳过即可, 不必重新适配.

8. 单币 70% 上限 skip 路径

症状: advisor 报 0.85 张, 但 process_signal 在 execute 前 hard pre-trade check (v4.5.89+ 之后) 检测到加仓会让该币占用超 70%, 返回 ⏭️ 单币超限跳过 | <COIN> | $X > $Y.

实战 (9/16-9/18 BTC 风暴): 熬鹰BTC short 一连串加仓信号 (6.23→16.79→22.03→27.27→30.61), 你BTC short 2.58张已经接近 65% 占用, 后续加仓信号全部 skip. 正确行为: skip 即可, 不要手动加仓 — 加仓可能超 70% 触发单币爆仓.

诊断: process_signal.py 输出的 ⏭️ 单币超限跳过 | <COIN> | $X > $Y 中 $X 是该币种建议占用, $Y 是当前 max cap (total × 70%).

9. 不要让用户提醒"先查再说" — 这个违规出现了 3+ 次

踩坑: 多次让 user 提醒 agent 查持仓/查锁 (而不是自己先查), user 原话:

  • "你要去查啊, 问我, 还要你干吗" (2026-09-01)
  • "内存放不下的时候呢?" 衍生 (2026-09-16)
  • 9/17 session 内让 user 问"你持仓呢?我等下"

正解: 任何状态查询 (持仓/余额/锁/业绩/价格) 必须先 check_account.py 再回答, 严禁反问"你持仓是什么?". 加到 memory (已存) + skill 的每个跟单相关入口.

10. 一句话口诀

Qdrant 第一但 Qdrant 不信 (历史线索) · live check_account 是唯一真值 (latency +3s, 必查) advisor 报数 ≠ execute 实际 (1.5x~4200x 偏差) · 推送成功 ≠ 订单落地 (manual verify 必做) decreased leverage OKX 59108 = cross 模式分账户余额不足 · 先减仓或不变, 不重试 手动 execute 必 release_lock · 手动 execute 必 record_position_history 任何 trader 拦截后大赚 → 问 user 是不是同一人 · 拦截名单归属最终解释权在 user 白名单配置驱动 (whitelist.json) · 绝不硬编码 trader/币种/阈值/比例