Files
Hermes-Skills/okx-auto-position/references/v4.5.116-2026-09-26-leverage-parse-bug-and-channel-revert-flow.md
T

7.9 KiB
Raw Blame History

v4.5.116 — Leverage 字段正则 fallback + 频道切换 4 步验证 + 用户情绪识别 (2026-09-26)

1. 杠杆字段解析 bug

症状: 信号原文 【币种】:ONDOUSDT 永续 | 全仓 | 2x 进 process_signal.py, advisor 默认报 10x leverage, 实际信号是 2x。

根因 (process_signal.py:79):

extractors = {
    'leverage': r'【杠杆】\s*[::]?\s*(\d+)',  # 只匹配独立【杠杆】标签
}

信号里杠杆在币种标签内 (ONDOUSDT 永续 | 全仓 | 2x), 没有独立 【杠杆】 标签, 正则匹配失败, 默认 10x。

代价: 你的仓位杠杆 = advisor 报量 × 默认 10x。如果熬鹰实际 1.95x, 你的风险敞口是他 5.13 倍。满仓时 12% 跌幅爆, 熬鹰 88% 跌幅才爆。

修复 (已 patch):

extractors = {
    # 独立【杠杆】标签 OR 行内|全仓|Nx 两种 fallback
    'leverage': r'(?:【杠杆】\s*[::]?\s*(\d+)|(?:永续|全仓)\s*\|\s*全仓\s*\|\s*(\d+)\s*[xX]?)',
}

# 提取时优先取 group(1), fallback group(2)
for key, pattern in extractors.items():
    m = re.search(pattern, text)
    if m:
        v = m.group(1) or m.group(2) or ''
        if v:
            fields[key] = v.replace(',', '') if key != 'unit' else v

测试用例:

# 旧格式 (有【杠杆】N)
text1 = '''【币种】BTCUSDT|永续|10x
【方向】做多
【杠杆】5
【仓位】1000'''
assert parse_signal(text1)['leverage'] == '5'  # ✓ group(1)

# 新格式 (币种标签内|全仓|2x, 无独立【杠杆】)
text2 = '''【币种】:ONDOUSDT 永续 | 全仓 | 2x
【方向】:做多 🟩'''
assert parse_signal(text2)['leverage'] == '2'  # ✓ group(2)

# 旧格式混合 (标签+行内)
text3 = '''【币种】BTCUSDT 永续 | 全仓 | 3x
【方向】做多
【杠杆】3'''
assert parse_signal(text3)['leverage'] == '3'  # group(1) 优先

触发场景: 任何"币种标签内|永续|全仓|Nx"格式信号 — 常见于 2026-08 后的新版熬鹰币安实盘/熬鹰FOMO合约实盘 模板。

用户原话 (2026-09-26): "ONDO 一直是 2 倍, 你是不是改成 10 倍了" — 是默认 10x 的结果, 不是显式调杠杆。但效果等价于"无形调了杠杆"。


2. 频道切换 4 步端到端验证链 — 用户情绪信号

用户原话 (按情绪递进):

  1. "需要把监听的频道更新一下" — 中性
  2. "换到新频道, 其他的配置不动" — 中性
  3. "现在用的是哪个频道" — 中性
  4. "C, 是一个群吗, 还是之前配置过 但启用的不对" — 轻微疑惑
  5. "现在交易信号都没转发了吗" — 轻微失落
  6. "那现在查信号为什么没进来啊, 转发器在正常工作的? 我对你十分失望" — 明确失望
  7. "现在把监听频道改回到 https://t.me/jiankongshipan" — 明确放弃新频道, 回切

关键教训: 用户说"我对你十分失望"时, 不要继续诊断新频道, 立即承认失败并执行"回切到旧频道"操作。Agent 不能无限制地诊断/优化 — 用户给的是"立即恢复"的命令。

反向验证 (anti-pattern): Agent 在用户失望后继续问"确认是新频道吗? 那查一下 OKX 实际是不是有信号流入?" — 这是继续在错误的频道上诊断, 不解决用户痛点。

正解: 用户说失望时, 立即回切并确认 — "已切回 jiankongshipan, 当前 source=1, 查 forwarder logs 看到 NewMessage 事件正常触发, 等下一条信号验证"。


3. 频道切换"伪成功"陷阱 — 用户没说"换好了",就还在诊断

症状: Agent 把 forward_rules.source_chat_id 改成新频道, docker restart 转发器, 然后告诉用户"已切换"。但实际上:

  1. forwarder 的 chat_id 提取还是用 abs(chat.id) — TG channel 是 -100xxx, abs 剥成 xxx, 跟 DB 存的 -100xxx 字符串匹配不上
  2. user_client 虽然订阅了 channel (Got difference for channel XXX updates), 但 NewMessage 事件不触发
  3. 用户发了一条"汇总播报"试探, 没看到转发
  4. 用户下一句:"现在交易信号都没转发了吗"

正解 — 4 步验证 (任何一步不通过, 都不能宣告成功):

  1. DB 配置: forward_rules.source_chat_id 改到新 chats.id, forwarder 重启
  2. 看 forwarder logs 出现 [处理规则|新消息|命中黑名单] 日志 — 仅有 Got difference for channel ... updates 不够, 说明 message_handler 没匹配上 (chat_id 提取 bug)
  3. 真信号触达: 用 telethon iter_messages('username', limit=10) 验证 (容器内需 cp session /tmp/ 解锁)
  4. 执行闭环: 用户转发一条真实信号到新频道, 看 QQ 推送 + OKX execute + check_account 仓位变动

只改 db 不验证后续 = 假成功, 等到新信号来了才发现"漏发"就晚了 (本 session ONDO 漏发就是这个原因)。


4. token 纪律补充: 蚂蚁式减仓双层过滤 + 用户情绪触发合并输出

用户原话 (按情绪递进):

  1. "调整一下, 只有加仓, 减仓, 开仓, 平仓这些字段的消息才处理" — 主动优化
  2. "蚂蚁减仓尽量减少token的消耗" — 明确 token 关注
  3. "我真服了" — 失望 (蚂蚁减仓 spam 不止, signal 也没进来)

结论: § 65 已部署 classify 严格模式 + 1% min 减仓过滤 + 同类输出合并, 2026-09-26 实测生效。本 session 蚂蚁减仓从 50+ 条 spam 收敛到"蚂蚁减仓no-op(0.X%<1%); USDT $576" 重复 1 行。但用户信号断了(forwarder chat_id bug), 这才是 1+2 实际 loss of progress。

执行优先级: token 优化只是减少噪音, 不解决"信号没进来"的核心问题。Agent 应该在用户说"信号没来"时优先诊断 forwarder 链路, 而不是继续优化 process_signal。


5. forwarder 模板名 disambiguation

用户原话 (2026-09-26): "转发器转发内容时, 你再加一条转发时间"

意图: 让转发消息能区分"原信号时间"vs"转发动作发生时间"。

当前状态:

  • forward_rules.time_template 默认 ⏱信号时间: {time} — 但代码层 {time} 实际是 hook 接收时刻 (转发时), 不是原信号时间
  • forward_rules.is_original_time 控制是否附加这条时间戳

修复 (用户选项 A 已执行 2026-09-26):

  • time_template 改名 ⏱转发时间: {time} (语义准确)
  • 用户接受 A 方案 (简洁), 不加额外"原信号时间"行

未做: 加forward_time_template双时间字段 (方案 B) — 需要改 forwarder 代码层, 改动大, 用户选择不改。


6. 调试顺序参考

当用户说"信号没来/没处理/没转发"时, 按这个顺序查:

  1. forwarder logs (docker logs telegram-forwarder --since 24h)

    • 有 [处理规则|新消息] 日志? → step 2
    • 只有 Got difference for channel ... updates? → chat_id 提取 bug (event.chat_id vs abs(chat.id))
    • 有 [黑名单] 日志? → 硬编码黑名单误杀 (USDT/老师/带单)
    • 完全没有消息日志? → user client 没真正 join channel 或 forwarder 完全停摆
  2. DB 配置 (docker exec telegram-forwarder python3 sqlite3 ...)

    • forward_rules.source_chat_id 是不是用户说的新频道?
    • chats.telegram_chat_id 是不是 -100xxxxxxxx 格式 (负数 + 100 前缀)?
    • forward_rules.enable_rule 是不是 1?
  3. 真信号触达 (telethon iter_messages)

    • 频道是不是真有最近 24h 信号? 是不是被管理员删了?
    • 信号的字段格式是新版(行内|全仓|Nx)还是旧版(独立【杠杆】N)?
  4. process_signal 链

    • classify 是不是 unknown? → 检查信号格式是否太严格
    • 白名单闸是不是拦了? → forward_rules 的 trader 白名单是不是过期
    • advisor 是不是 BadSymbol? → 1000xxx 币种 OKX 上不存在
    • 推送是不是失败? → 推送失败 ≠ execute 失败, 必查 check_account
  5. 用户情绪反应

    • 用户说"我对你失望/真服了" → 立即承认失败, 执行用户要的恢复命令 (回切/暂停诊断)
    • 不要在用户情绪爆发后继续在错误的频道上诊断