Files
Hermes-Skills/okx-auto-position/SKILL.md
T

16 KiB
Raw Blame History

name, description
name description
okx-auto-position OKX自动仓位管理+信号推送v4.5.115: classify_signal 严格模式 (只识别 加仓/减仓/新开仓/平仓/调杠杆 5 类, 其余 unknown 零token跳过) + 1% min 减仓过滤 + 4个熬鹰号白名单(资本/币安实盘/FOMO/交易信号, 同一人多平台) + close也闸(防变体号误平) + adjust_leverage_raw body=body bug fix + 蚂蚁式减仓双层过滤 + 永不用真账户测 raw REST + TG forwarder chat_id 用 event.chat_id 不能 abs(chat.id) + "推送失败 ≠ execute失败" 必查 check_account 验证 + 换频道后必须端到端验证(规则+日志+实际信号流) + token 纪律: 同类操作合并只输出最终结果。详见references/v4.5.115 ~ v4.5.4.

okx-auto-position

OKX自动仓位管理+跟单信号处理+QQ推送 (v4.5.115)

核心规则 (与v4.5.115同步)

TG forwarder chat_id 提取 (line 76, v4.5.114) — 第一铁律

  • 必须用 event.chat_id (完整 TG channel id -100xxxxxxxx), 不能用 abs(chat.id)
  • event.chat.id (Channel 对象) = 正数 2651333064 (剥了 -100 前缀)
  • event.chat_id (telethon 完整 id) = -1002651333064
  • DB 存 Chat.telegram_chat_id == '-1002651333064' 字符串
  • 用 abs(chat.id)=2651333064 跟 DB 字符串对比 → 永远匹配不上, 频道切换后信号不转发, docker 日志只看到 "Got difference for channel ... updates" 0 后续处理
  • Chat 查询改成 telegram_chat_id.in_([str(chat_id), alt1, alt2]) 三种格式防御性查询, 防 chat_id 来源不一
  • 修复后必须 docker restart telegram-forwarder

推送失败 ≠ execute失败 (v4.5.115, 本session铁律)

  • process_signal.py 返回 ❌ 推送失败 不等于 没下成单
  • ⚠️ advisor错误 (symbol 不存在等) 也不等于 没下成单
  • 唯一验证 = 跑 check_account.py [SYMBOL-USDT-SWAP] 查实际持仓/账单/成交
  • 实战 (2026-09-26 ONDO加仓): process_signal 报 ❌ 推送失败,但 OKX 上 ONDO 已加仓 329 张@0.518 成功。靠 check_account 才发现已成交。
  • 结论: 看到 push_signal 不等于没成, 必查 check_account 再下结论, 不要立刻告诉用户"失败"
  • 自动化验证脚本: scripts/verify_execution_after_push_fail.py <SYMBOL> [min_ago] — 自动跑查持仓+近成交, 给出"execute 成功 / 真没成"结论

换频道端到端验证链 (v4.5.115, 本session)

当用户说"换到 @XXX 频道"或"现在用的是哪个频道"时, 必须完成4 步验证才能宣告切换成功:

  1. DB 配置: forward_rules.source_chat_id 改了? chats 表里新 chat_id 加了?
  2. Forwarder 监听器: docker logs telegram-forwarder 出现 [处理规则|新消息|命中黑名单] 日志? (只有 Got difference for channel XXX updates 不够, 说明 message_handler 没匹配上)
  3. 真信号触达: 频道有真实交易信号? 用 telethon iter_messages('username', limit=10) 验证 (容器内需 cp session /tmp/ 解锁)
  4. 执行闭环: 新信号→pipeline→OKX execute→check_account 显示仓位变动? 只改 db 不验证后续 = 假成功, 等到新信号来了才发现"漏发"就晚了 (本 session ONDO 漏发就是这个原因)。

classify_signal 严格模式 (line ~247) — ⚠️ 也漏合法"汇总里带新开仓价"的信号 (v4.5.116, 2026-09-26 实测)

  • '平仓' in text → close
  • '加仓' in text or '追仓' in text → add
  • '减仓' in text → reduce (必须显式含"减仓"两字)
  • '新开仓' in text or '注意,大佬开仓了' in text → open
  • '修改了杠杆' / '调整了杠杆' / '调杠杆' in text → adjust_leverage
  • 其余全部 → unknown (零token跳过, 不查持仓, 不调 advisor)

Strict 模式 trade-off: 严格模式拦截了所有"汇总播报带价格但无动作词"的信号 (例: "熬鹰当前全部持仓" 列表里刚好有 BTC 新开仓价 81471, 但 classify 拦了)。当用户问"新频道为啥没信号进来"时, 可能是严格模式漏了合法信号, 而不是频道配置问题。修复方向: 给"汇总播报"加 update_only 类 + 二次校验字段(若含"原仓位/开仓均价/标记价格/实际杠杆"等价格字段, 则 hint 实际开/加/减仓方向)。

白名单配置 (whitelist.json, 4 个熬鹰号同一人)

  • 熬鹰资本
  • 熬鹰币安实盘
  • 熬鹰FOMO合约实盘
  • 熬鹰交易信号

闸包括 open/add/reduce/close/adjust_leverage 5 类全部过白名单。

运维原则: 用户明确要求"换到 @XXX 频道, 其他配置不动" — 换频道 = 只改 forward_rules.source_chat_id, 不要碰白名单/黑名单/关键词/transit delay。

1% min 减仓过滤 (蚂蚁式减仓噪音)

减仓幅度 < 1% 跳过, 即使被识别为 reduce, advisor/推送都不触发。

蚂蚁式减仓双层过滤

  1. 第一层 (classify): 汇总播报/实时更新根本不进 reduce 分支
  2. 第二层 (1% min): 即便进了 reduce, 减仓 < 1% 也跳过

Token 纪律: 同类操作合并输出 (v4.5.115, 本session用户明确要求)

  • 同一交易员短时间内发 50+ 条"🐜 蚂蚁减仓" 噪声信号 (例: 熬鹰 ZAMA 连续 50+ 条 < 1% 减仓) 时, 不要每条都 no-op + 重复 "USDT $576" — 浪费大量 token 输出无意义结果
  • 正确: 第一条 "蚂蚁减仓已用 1% min 过滤跳过", 后续同类只输出 "无操作" 或合并到一条总览 "⚠️ 50 条蚂蚁减仓全 no-op, 已实现累计+$X"
  • 用户原话 (2026-09-26): "调整一下, 蚂蚁减仓尽量减少token的消耗"

合约面值 ctVal — 名义/保证金计算第一铁律 (v4.5.117, 2026-09-26 重大事故)

  • 任何 contracts→名义$ 换算前必查 GET /api/v5/public/instruments 的 ctVal (每张面值)
  • ONDO 1张=10 ONDO / ZEC 1张=0.01 / BTC 1张=0.01 / PEPE 1张=10000 — 不是1, 猜=事故
  • 本session按 1张=1 ONDO 算小10倍: 以为名义$198合规, 实际**$1,986超$140上限14倍**; 以为frozen $496是"显示延迟", 实际=真实保证金
  • frozenBal 异常大 ≠ 显示延迟, = 仓位超限。先查 ctVal 重算, 再怀疑交易所
  • 手动 raw REST 绕过 advisor, 也必须过单币上限: min(权益,$200)×70%, 最大张数 = 上限名义/(ctVal×markPx)
  • 修正顺序: 减仓到上限内 → 再调杠杆 → check_account 验证 frozen ≈ 名义/杠杆
  • 详见 references/v4.5.117-2026-09-26-ctval-contract-size-bug-and-200-cap-violation.md

adjust_leverage_raw 函数 (line ~523)

  • 关键 fix: _okx_raw_request('POST', '/api/v5/account/set-leverage', body=body), body 必须用关键字 body=body
  • cross 模式降杠杆会被拒 (59108), 需先减仓释放保证金

close 也闸

平仓信号不被"平仓兜底"绕过, 也要过白名单 trader 闸 (防变体号误平)。

advisor 报量偏差 bug (SNDK/MU/XAU/SPCX)

advisor 报 1 张, 实际可能 execute 几十张 (2344 / 2544 / 286 等)。trust actual 持仓, not advisor 报量。

杠杆字段正则只匹配独立【杠杆】标签 — 信号行内|全仓|Nx必须fallback识别 (v4.5.116, 2026-09-26 本session)

症状: 信号原文 【币种】:ONDOUSDT 永续 | 全仓 | 2x, 但 parse_signal 的 leverage 正则只匹配 【杠杆】N 标签, 匹配不到, 默认10x。

根因 (process_signal.py:79/111):

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

实战代价: ONDO 实际 1.95x, advisor 默认 10x = 你的风险敞口是熬鹰的 5.13 倍。你满仓 ONDO 时, 12% 跌幅爆仓, 熬鹰 88% 跌幅才爆。

修复 (2026-09-26 已 patch):

'leverage': r'(?:【杠杆】\s*[::]?\s*(\d+)|(?:永续|全仓)\s*\|\s*全仓\s*\|\s*(\d+)\s*[xX]?)',
  • 提取逻辑改 v = m.group(1) or m.group(2) or '', 优先取独立标签组, fallback 行内组。

验证:

text = '【币种】:ONDOUSDT 永续 | 全仓 | 2x\n【方向】:做多'
parse_signal(text)['leverage']  # 应为 '2', 不是 None/默认10

用户原话 (2026-09-26): "你刚才是加仓不是开仓, ONDO 一直是 2 倍, 你是不是改成 10 倍了" — 是默认 10x 的结果, 不是显式调杠杆, 但风险敞口5x于熬鹰等于无形调了杠杆。

总结: 信号解析杠杆字段必须两个 fallback — 独立 【杠杆】N 标签 + 行内 |永续|全仓|Nx。新格式信号优先用行内 fallback。

advisor 硬编码 1000PEPE BadSymbol bug

  • advisor 用 1000PEPE-USDT-SWAP 查 symbol, OKX 上不存在 (那是币安合约名), 对应是 PEPE-USDT-SWAP
  • BadSymbol 崩溃 → 整条信号失败, advisor 报 ⚠️ advisor错误
  • 手动 raw REST 时用 PEPE-USDT-SWAP; advisor 代码 bug 待修
  • 同类 1000SHIB/1000PEPE 等"1000x"币种都是 OKX 上没有前缀版本

双频道监听区分 (2026-09-24 已切换 source)

  • 用户最初给错指令/切换不彻底 → 当前源要"先查再说": forward_rules.source_chat_id + chats.telegram_chat_id 双重确认
  • 新源 @shipan_jiankong: chats.id=4, telegram_chat_id=-1002651333064, 标题"币圈实盘监控 | 熬鹰 风寻" (chats.id=4)
  • 旧源 @jiankongshipan: chats.id=1, telegram_chat_id=3805472665, 标题"实盘监控"
  • 切换 = UPDATE forward_rule.source_chat_id; 修 chat_id bug = docker restart telegram-forwarder

硬编码黑名单 USDT 误杀 (v4.5.115, 修复后)

  • forwarder user_handler.py 的 HARD_BLACKLIST_PATTERNS 含 r'(?i)usdt|cny|套现' + 裸 带单|指导|喊单|老师|VIP → 所有信号格式都带 USDT (BTCUSDT 永续), 误杀 100% 信号
  • 修复: r'(?i)(usdt|cny)(?!永续|usdt).{0,4}套现|套现' 只拦"套现", VIP|老师 收窄为 VIP群|付费指导
  • 症状: docker 日志 [用户] 消息命中硬编码黑名单, 跳过转发 但无 [新消息|处理规则] 后续

cross 降杠杆 59108 标准四步 (v4.5.118, 2026-09-25 ONDO实战)

  1. set-leverage 直调 → 59108 (预期失败)
  2. reduceOnly 市价减仓一部分 (释放保证金)
  3. 再 set-leverage 到目标杠杆 → code=0
  4. check_account 验证 lever 字段 + frozen ≈ 名义/杠杆 不要反复裸调 set-leverage, 也不要建议用户去 app 手动 — 脚本内闭环即可。

$200 上限口径 = 保证金 (v4.5.118, 2026-09-25 用户最终确认)

  • 用户原话: "你只管保证金在限制内就行了"
  • $200 = 单币保证金上限, 不是名义/张数口径; advisor config single_coin_ceiling_usdt=200 本就是此口径, 无需改
  • 首仓70%=$140, 加仓可满$200; 名义上限 = $200 × 杠杆
  • 验收: check_account 看 frozenBal (≈保证金) 是否 ≤ $200

信号链路断链排查顺序 (v4.5.118, 用户"信号怎么没进来"时)

  1. forwarder 日志有无 [处理规则|新消息] (只有 Got difference 不算)
  2. signal_queue.db 最新 id 有无入队
  3. process_signal 输出有无 advisor错误/无法解析
  4. OKX /api/v5/trade/fills-history 有无成交 逐级查, 不要只查一层就下结论; 若换源后 2~4 全断, 果断回切旧源 (forward_rules.source_chat_id 改回), 不要恋战。

转发时间模板 (v4.5.118)

time_template = ⏱转发时间: {time} — 该时间戳是 forwarder 收到消息的时刻, 不是原信号发布时刻; 用户要求此命名 (原"信号时间"语义混淆已改)。

永不用真账户测 raw REST

  • 测试时用 mock 或临时子账户
  • proxy 抽风时手动 execute 兜底 (sleep 15-30s 后 raw REST 重试)

工作流

  1. 用户从 TG 发来交易信号
  2. signal_queue.py enqueue '<消息原文>'
  3. cron 或 manual 调用 process_signal.py '<消息原文>'
  4. classify → 白名单闸 → advisor → execute_order 或 close
  5. tracker 记录 outcome (auto_executed / silent_no_pos / skipped_xxx)
  6. 推送失败 ≠ execute失败: QQ 推送失败时必跑 verify_execution_after_push_fail.py 或 check_account.py 确认是否已实际下成
  7. 同类操作合并输出: 蚂蚁减仓/连续加仓信号合并回复, 不要逐条 spam

调用入口

# 主入口 (用户发信号后)
python3 ~/.hermes/skills/trading/okx-auto-position/scripts/process_signal.py '<消息原文>'

# execute 验证 (推送失败/疑似无成交时必跑)
python3 ~/.hermes/skills/trading/okx-auto-position/scripts/check_account.py [SYMBOL-USDT-SWAP]

# 自动化验证: 推送失败 ≠ execute失败 (v4.5.115)
python3 ~/.hermes/skills/trading/okx-auto-position/scripts/verify_execution_after_push_fail.py <SYMBOL> [min_ago]

# 手动 execute (proxy 抽风后兜底, 或 advisor BadSymbol 绕过)
# 1. 先 check_account.py 查实际持仓/可用余额
# 2. raw REST 下 reduceOnly 单 (跟单信号) 或 limit 单 (调杠杆)
# 复制 templates/manual_order_template.py 到 /tmp/order_xxx.py, 修改 body 字段

# 锁管理
python3 ~/.hermes/skills/trading/okx-auto-position/scripts/signal_tracker.py

已知数据源 / 工具限制

  • screener_search 的 dividend/dpseps 字段返 None (不能筛 yield)
  • OKX 单次 reduce 报 "订单失败" 可能是已成交 (51400)
  • cross 模式 setLeverage 降杠杆必失败 (需先减仓)
  • advisor estimate 用 contractSize 误解 (ZEC 1张=0.01 ZEC, 推送必须展示名义$而非张数)
  • OKX 没有 1000PEPE (那是币安合约名), 对应是 PEPE-USDT-SWAP, advisor 用 1000PEPE-USDT-SWAP 会 BadSymbol 崩; 手动 raw REST 用 PEPE-USDT-SWAP
  • advisor 实际下单量 ≠ 报量 (1张 → 实际 2344/2544/286 张都可能)

平仓推送真实 pnl (2026-09-22)

_fetch_close_pnl_details(symbol_usdt) 函数从 /api/v5/account/bills 拿真实已实现盈亏:

  1. 拉近 7 天 type=2 bills (subType=1 = 含手续费已实现, subType=2 = 单笔成交)
  2. 找绝对值最大那笔 ts (subType=1 手续费绝对值<5 跳过)
  3. 累加 ±30 秒内 type=2 全部 balChg = OKX app 显示的真实数
  4. 填到 format_close_message() 推送里 "💰 实际盈亏: +$X.XX (OKX 实测)"

详见 references/okx-pnl-from-bills-api.md.

signal_queue.py mark_done 覆盖 bug (2026-09-22)

process_signal 失败时 returncode=0 → signal_queue.py retry 看到 returncode=0 就 mark_done → 失败信号被伪装成功.

修复: signal_queue.py retry 检查 stdout 含 "❌"/"⏭️"/"⚠️" 时 mark_failed (而非 mark_done). 平仓失败信号会被 retry 重试 5 分钟一次.

TG forwarder 容器内诊断模式 (v4.5.114)

  • 容器内无 sqlite3 CLI → 用 python3 -c "import sqlite3; ..." 读 /app/db/forward.db
  • session 被主进程锁 → cp /app/sessions/user.session /tmp/u.session 再用 telethon 连
  • 容器内 telethon 连 TG 必带 proxy=('socks5','127.0.0.1',7891), request_retries=1
  • 双防御: 修 chat_id = event.chat_id 同时改 Chat 查询 in_([str, alt, alt])
  • 诊断 4 步法 (见上方"换频道端到端验证链")

参考

详见 references/ 目录:

  • v4.5.118: ONDO杠杆降级实战(59108四步) + $200=保证金口径最终确认 + 频道回切jiankongshipan + 转发时间模板
  • v4.5.115: 推送失败 ≠ execute失败 + 换频道端到端验证链 + token 纪律 (本 session 实装)
  • v4.5.117: ctVal 合约面值事故 — 名义算小10倍超限 + frozen之谜 + 手动单也过$200上限
  • v4.5.114: TG forwarder chat_id 提取 bug + 频道切换
  • v4.5.113: classify 严格模式
  • v4.5.111: 1% min 减仓过滤 + 4 熬鹰号白名单
  • v4.5.110: ZAMA 蚂蚁减仓双层过滤
  • v4.5.103: 4 熬鹰号首次识别为同一人, 调杠杆自动跟进
  • v4.5.96: advisor reduce 三种结果 (0.001 张/方向 bug/隐性失败)
  • v4.5.91: advisor vs executed size divergence matrix
  • v4.5.83: whitelist 4 accounts + 新格式信号识别
  • v4.5.77: close 也闸修复
  • v4.5.71: whitelist.json 配置化 + query-first-no-asking 铁律
  • v4.5.68: phantom execute + cross leverage lower rejection
  • v4.5.64: adjust leverage 信号自动跟进
  • v4.5.39: silent execute fallback
  • references/forwarder-hard-blacklist-usdt-blocking-2026-09-22.md — 黑名单 USDT/CNY/带单/老师 误杀修复

新增 scripts (v4.5.115)

  • scripts/verify_execution_after_push_fail.py <SYMBOL> [min_ago] — process_signal 返回 "❌ 推送失败" 时,自动用 OKX REST 验证实际 execute 状态 (查持仓+近 N 分钟成交), 给出"execute 成功 / 真没成" 结论。比 check_account.py 更精准 (会显示"未 execute" vs "execute 成功")
  • templates/manual_order_template.py — 已存在, 手动 raw REST 下单模板 (开/平/调杠杆 5 种)