248 lines
16 KiB
Markdown
248 lines
16 KiB
Markdown
---
|
||
name: okx-auto-position
|
||
description: '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`):
|
||
```python
|
||
'leverage': r'【杠杆】\s*[::]?\s*(\d+)', # 只匹配独立标签
|
||
```
|
||
|
||
**实战代价**: ONDO 实际 1.95x, advisor 默认 10x = 你的风险敞口是熬鹰的 5.13 倍。你满仓 ONDO 时, 12% 跌幅爆仓, 熬鹰 88% 跌幅才爆。
|
||
|
||
**修复** (2026-09-26 已 patch):
|
||
```python
|
||
'leverage': r'(?:【杠杆】\s*[::]?\s*(\d+)|(?:永续|全仓)\s*\|\s*全仓\s*\|\s*(\d+)\s*[xX]?)',
|
||
```
|
||
+ 提取逻辑改 `v = m.group(1) or m.group(2) or ''`, 优先取独立标签组, fallback 行内组。
|
||
|
||
**验证**:
|
||
```python
|
||
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
|
||
|
||
## 调用入口
|
||
|
||
```bash
|
||
# 主入口 (用户发信号后)
|
||
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 种) |