# v4.5.68 (2026-08-30) Phantom Execute 加剧 + Cross 模式降杠杆被拒 + 调杠杆信号 "3→4" 解读 **详细复现**: 本次 session ## 三件新事件 (本次 session 续 v4.5.66 / v4.5.67) ### 1. Phantom Execute 加剧 — 几乎每个熬鹰信号都幽灵成交 **症状**: `process_signal` 报 `⏭️ 跳过: 信号源未知 | ` 或 `⏭️ 跳过: 性价比低 | `,但 5 秒后 `check_account.py` 显示实际仓位出现。 **本次复现的幽灵 execute**: | 信号 | advisor 报 | 实际成交 | |---|---|---| | SKHYNIX short 2x | "跳过 信号源未知" | 0.145 张@2x ✓ | | BTC long 5x | "跳过 信号源未知" | 0.63 张@5x ✓ | | HYPE long 2x | "跳过 信号源未知" | 26 张@2x ✓ | | HYPE long 2x (信号 2) | "1张 性价比一般" | 25 张@2x ✓ (vs advisor 25 张 OK, 但 signal 2 是 1 张信号) | | TRUMP long 1x | "137张 性价比高" | **586 张@1x** ✗ (4.3x 超额) | | SKHYNIX long 1x (去低判断后) | "0.065张 性价比低" | 0.098 张@1x ✓ | | SKHYNIX long 2x 加仓 | "0.039张 性价比低" | **0.407 张@2x** ✗ | **根因 (叠加 3 个)**: 1. **trader='未知' 闸没拦 execute 路径**: `process_signal()` 在 `classify_signal()` 后加了闸,但 advisor 的 execute 路径 (`okx_position_advisor.py --execute`) 是独立脚本,**直接读信号文本 + 直接调 ccxt.create_order**, 完全不经过 process_signal 主流程 2. **advisor 的 `contracts` 字段不可信**: advisor JSON 返回的 `contracts` 是基于可用 USDT ×45% / 每张保证金 计算,但实际 ccxt 下单时用了不同的 ctVal / 最小变动单位计算器 3. **"性价比低"判断在 advisor 内层**: v4.5.66 移除外层判断,但 advisor JSON 仍带 `rating_text: 性价比低` 标签, 用户看到后误以为没跟单 **实测新发现**: 即使 process_signal 主流程加了 trader='未知'闸 + 白名单闸 + 调杠杆闸,**advisor 的独立 execute 路径** 仍会成交。这是 v4.5.54 / v4.5.57 的延伸, 但 v4.5.66 没堵上。 **修复方向 (下次必修)**: - [ ] `okx_position_advisor.py` 加 trader 闸 + trader 白名单 (跟 process_signal 同步) - [ ] advisor execute 后**强制**调 `check_account.py` 反查实际仓位, 反查为空时**推 QQ 失败** - [ ] advisor JSON 的 `contracts` 字段改名为 `suggested_contracts`, 加 `actual_contracts` 字段(后置填充) - [ ] advisor 的 `rating_text: 性价比低` 字段移除 (用户已说"把性价比去掉") **临时 workaround (本次 session 实战)**: 执行任何 advisor 后 → **强制 sleep 5s + check_account.py 反查** → 有新增就记录, 无新增就推 QQ "实际未成交" ```bash # 实战模板 python3 process_signal.py "signal" sleep 5 python3 check_account.py -USDT-SWAP # 对比 advisor JSON.contracts vs check_account.contracts ``` ### 2. Cross 模式降杠杆被 OKX 拒绝 (Your account leverage is too low and has insufficient margins) **症状**: SKHYNIX long 0.098 张@5x 持仓 → 熬鹰信号 `修改了杠杆 5→2` → 调 set-leverage API → OKX 返回 `code: 59108, msg: Your account leverage is too low and has insufficient margins. Please increase the leverage.` **复现命令**: ```python body = {'instId': 'SKHYNIX-USDT-SWAP', 'lever': '2', 'mgnMode': 'cross'} resp = _okx_raw_request('POST', '/api/v5/account/set-leverage', body=body) # → {"code":"59108","msg":"Your account leverage is too low and has insufficient margins..."} ``` **根因**: OKX cross 模式下, 杠杆下调会要求"按新杠杆计算所需初始保证金 ≥ 当前可用 USDT"。SKHYNIX 0.098 张@2x 需要 ≈$60 保证金, 但用户 USDT 主要压在 ETH/TRUMP 持仓上, SKHYNIX 分账户可用余额 < $60。 **OKX API 文档事实** (硬): - 升杠杆: 总是允许 (只要新杠杆不超过币种上限) - **降杠杆**: 必须满足 `新杠杆所需初始保证金 ≤ 当前可用 USDT + 已冻结保证金`, 否则拒 - 用户**当前持仓杠杆 ≥ 信号目标** → 降杠杆被拒 - 用户**当前持仓杠杆 < 信号目标** → 升杠杆, 正常 **修复方向**: - [ ] `adjust_leverage_raw` 失败时区分**升 / 降**: - 升杠杆失败 → 重试 (proxy 抽风) - 降杠杆失败 (59108) → **不重试**, 推 QQ "OKX 拒绝降杠杆, 账户余额不足" + 触发"用户偏好"问询"要不要平仓释放 USDT 后再降" - [ ] 文档加 pitfall: "降杠杆在 cross 模式需要 USDT 支持, 升杠杆不需要" **实战应对 (本次 session)**: - 用户问 "正常操作是怎么降?" → 我列了 3 路径 (加仓满足/逐仓模式/平仓-降-重开) - 用户没让我强制平, 信号继续 (熬鹰后续还会发 modify 信号) - 实战教训: 调杠杆信号在 cross 模式下**经常失败**, 不要默认每次都能跟 ### 3. 调杠杆信号 `A→B` 解读规则 (v4.5.68 强化 v4.5.65) **信号**: `🔧 注意,大佬修改了杠杆 5→2 【币种】: SKHYNIX-USDT|永续|2x` **正确解读**: - `5→2` = 当前 5x → 改成 2x (目标值 2) - 信号文本 `永续|2x` 字段是**目标值**, 不是"现在杠杆 2x" - `process_signal.parse_signal()` 取 `leverage` 字段 → `2` **代码已对**: ```python new_lev = int(fields.get('leverage') or '10') # leverage 字段在 `【币种】: |永续|x` 取到, 取 LEV = 2 ``` **用户误读防范**: - ❌ "5→2 我手动调到 5x" (我本次 session 干过这傻事) - ✅ 永远取 `永续|x` 的 LEV = 信号目标值 - 验证: 信号文本里 `永续|2x` → 调 set-leverage lever=2 ### 4. signal_tracker.acquire_lock 的 symbol 参数必须无后缀 **实战发现**: 用户手动 execute MSTR short 4.01 张@5x 后, 我手动跑 `acquire_lock("MSTR-USDT-SWAP", ...)`, 结果 position_locks 出现 2 条: ``` MSTR|熬鹰资本|short|...|新信号自动锁|1 MSTR-USDT-SWAP|熬鹰资本|short|...|手动加锁|0 ``` **根因**: `process_signal.parse_signal()` 提取 `symbol` 字段时**不带 `-USDT-SWAP` 后缀**, 而手动锁习惯性用 instId 完整形式。 **正确**: ```python from signal_tracker import acquire_lock ok, msg = acquire_lock("MSTR", "熬鹰资本", "short", reason="手动加锁", auto=False) # ✓ 无后缀 ok, msg = acquire_lock("MSTR-USDT-SWAP", "熬鹰资本", "short", ...) # ✗ 永远锁不上 ``` **验证**: ```bash sqlite3 ~/.hermes/trading/signal_history.db "SELECT * FROM position_locks;" # 应只见无后缀 symbol (MSTR / TRUMP / SKHYNIX / ETH / BTC) ``` **跟 v4.5.63 的关系**: v4.5.63 已记过这个坑, v4.5.68 实战再次踩到 (MSTR 锁不上 → 用户问 "交易员锁了吗, 我是转发的消息, 也要锁的") **修复方向**: - [ ] `acquire_lock` 函数加注释强调"symbol 必须无 -USDT-SWAP 后缀" - [ ] 或 `acquire_lock` 内部自动剥离后缀 (defensive) ### 5. trader='未知' 闸的"幽灵 execute" vs 主流程"静默 skip" 并存 **会话时间线**: | 时间 | 信号 | process_signal 报 | 实际成交 | |---|---|---|---| | T1 | SKHYNIX short 2x | "跳过 信号源未知" | 0.145 张@2x (幽灵) | | T2 | BTC long 5x | "跳过 信号源未知" | 0.63 张@5x (幽灵) | | T3 | HYPE long 2x (1) | "跳过 信号源未知" | 26 张@2x (幽灵) | | T4 | HYPE long 2x (2) | "1张 性价比一般" | 25 张@2x (幽灵) | | T5 | 白名单闸加好 | "跳过 trader [未知] 不在白名单" | (不再幽灵) | | T6 | TRUMP long 1x | "137张 性价比高" | 586 张@1x (超额幽灵) | | T7 | SKHYNIX long 1x | "0.065张 性价比低" (v4.5.66 后) | 0.098 张@1x | | T8 | SKHYNIX long 2x 加仓 | "0.039张 性价比低" | 0.407 张@2x (超额幽灵) | **关键洞察**: - T1~T4 在白名单闸前 → 闸没生效, advisor 独立 execute 路径成交 - T5 加白名单闸后 → advisor 路径**也**没被拦住 (advisor 不读 process_signal 的闸) - T6~T8 都是在白名单生效后 → 仍有幽灵 execute **结论**: **process_signal 主流程闸 ≠ advisor execute 闸**, 这是两个独立路径, 都要加固。 ### 6. `scripts/manual_order.py` 已有, 本次 session 实战使用 **实战模板** (本次 session 末段): ```python # /tmp/open_mstr2.py import json, time, hmac, hashlib, base64, requests def okx_post(path, body, t=15): creds = open('/home/openclaw/.bashrc').read() k = s = pw = None for l in creds.splitlines(): if l.startswith('export OKX_API_KEY='): k = l.split('=', 1)[1].strip().strip('"') elif l.startswith('export OKX_SECRET='): s = l.split('=', 1)[1].strip().strip('"') elif l.startswith('export OKX_PASSPHRASE='): pw = l.split('=', 1)[1].strip().strip('"') ts = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()) method = 'POST' body_str = json.dumps(body) pre = ts + method + path + body_str sig = base64.b64encode(hmac.new(s.encode(), pre.encode(), hashlib.sha256).digest()).decode() h = {'OK-ACCESS-KEY': k, 'OK-ACCESS-SIGN': sig, 'OK-ACCESS-TIMESTAMP': ts, 'OK-ACCESS-PASSPHRASE': pw, 'Content-Type': 'application/json'} r = requests.post('https://www.okx.com' + path, headers=h, data=body_str, timeout=t, proxies={'http': 'http://127.0.0.1:7890', 'https': 'http://127.0.0.1:7890'}) return r.json() # 5x MSTR short market order body = {'instId': 'MSTR-USDT-SWAP', 'tdMode': 'cross', 'side': 'sell', 'posSide': 'net', 'ordType': 'market', 'sz': '1'} print(okx_post('/api/v5/trade/order', body)) ``` **已知陷阱 (本次 session 实战遇到)**: 1. **POST body 必须 `body=body` keyword arg** (v4.5.64 已修, 但每次新写脚本要警惕) 2. **reduceOnly 平仓**: `sz` 必须严格等于持仓张数, 否则 OKX 报 51169 3. **proxy 必须保留**: 私有 API 直连会被 OKX 拒绝 4. **acquire_lock 必须手动**: 用户偏好不改代码 (v4.5.63) ### 7. 用户偏好 (本次 session 末段新增) - **"调杠杆失败这个不能改吗"** (用户原话, 2026-08-26) → 我列了 3 路径, 用户未选, 默认 **不强制平仓, 等下一个调杠杆信号自然解决** - **"正常操作是怎么降"** (用户原话, 2026-08-26) → 用户在寻求知识, 不在要我执行 ## 实战时间线 (本次 session) | 时刻 | 事件 | |---|---| | 2026-08-26 01:00 | 熬鹰 ETH 平仓 → close_position_raw 返回 None → process_signal 崩溃 → 加 null guard | | 2026-08-26 01:30 | 熬鹰 ETH 新开仓 → advisor 报 1.4 张 → execute 1.4 张@3x (OK) | | 2026-08-26 02:00 | 用户问"信号只到了 4" → 我误把 ETH 调到 5x → 手动改回 4x | | 2026-08-26 03:00 | 熬鹰 HYPE 平仓 → 手动 execute (proxy 抽风) | | 2026-08-26 04:00 | 熬鹰 TRUMP 新开仓 → advisor 137 张 → execute **586 张@1x** (幽灵, 4.3x 超额) | | 2026-08-26 05:00 | 熬鹰 TRUMP 调杠杆 1→2x → 自动跟 → USDT 可用恢复 $2 → $81 | | 2026-08-26 06:00 | 熬鹰 TRUMP 平仓 → 手动 execute (proxy 抽风) | | 2026-08-26 07:00 | 熬鹰 SKHYNIX 新开仓 1x → "性价比低" 跳过 (v4.5.66 前) | | 2026-08-26 08:00 | 用户 "把性价比去掉, 不要了" → 移除"性价比低"判断 | | 2026-08-26 09:00 | 熬鹰 SKHYNIX 1x → execute 0.098 张 (OK) | | 2026-08-26 10:00 | 熬鹰 SKHYNIX 调杠杆 1→5x → execute set-leverage OK | | 2026-08-26 11:00 | 熬鹰 SKHYNIX 调杠杆 5→2x → OKX 59108 拒绝 (cross 模式余额不足) | | 2026-08-26 12:00 | 熬鹰 SKHYNIX 加仓 2x → advisor 0.039 → execute 0.407 张@2x (10x 超额幽灵) | ## 累计已知 execute 失败/幽灵 清单 (v4.5.68 更新) | 币种 | 模式 | 现象 | |---|---|---| | SPCX-USDT-SWAP | silent fail | advisor 报"已推送", 实际无合约, 不下单 | | 1000PEPE / PEPE-USDT-SWAP | symbol normalize | 必须 PEPE-USDT-SWAP, advisor 有路径问题 | | MU-USDT-SWAP | 幽灵 | advisor 报 X 张, execute X+1 张 | | XAU-USDT-SWAP | 幽灵 | advisor 报 X 张, execute X+N | | HYPE-USDT-SWAP | 幽灵 (本次) | advisor 报 1 张, execute 25 张 | | TRUMP-USDT-SWAP | 幽灵 (本次) | advisor 报 137 张, execute 586 张 | | SKHYNIX-USDT-SWAP | 幽灵 (本次) | advisor 报 0.039 张, execute 0.407 张 | | NEIRO-USDT-SWAP | silent fail | OKX 无合约 | | ZAMA-USDT-SWAP | silent fail | OKX 无合约 | **通用规律**: **所有合约都可能被幽灵 execute**, 没有"安全"币种。每次 execute 后**必须反查**。 ## 部署清单 (下次 session 第一件事) - [ ] `okx_position_advisor.py` 加 trader 闸 + 白名单 + trader='未知' 闸 (跟 process_signal 同步) - [ ] advisor execute 后**强制** `check_account.py` 反查, 反查为空时推 QQ 失败 - [ ] advisor JSON 加 `actual_contracts` 字段, 由 check_account 后置填充 - [ ] `adjust_leverage_raw` 失败时区分升/降, 降杠杆 59108 推 QQ 用户问询 - [ ] `acquire_lock` 函数加注释 "symbol 必须无 -USDT-SWAP 后缀" - [ ] 已知 silent_fail / 幽灵 execute 币种清单 (上表) 入 reference - [ ] X/Twitter 链接处理模板入 SKILL.md (v4.5.65 已记, 复用) ## 关联版本 ``` v4.5.21 加"性价比低"判断 (兜底) ↓ v4.5.37 ~ v4.5.62 沿用 + silent_order 标识 ↓ v4.5.65 silent_order 完整化 ↓ v4.5.66 去掉"性价比低"判断, 跟所有熬鹰信号 (用户偏好反转) ↓ v4.5.67 用户口语"调杠杆" = 加仓 (不是 OKX set_leverage) ↓ v4.5.68 幽灵 execute 加剧 + cross 模式降杠杆被拒 + 调杠杆信号 "3→4" 解读 ``` 每次踩坑都在 OKX 跟单这条线上, 跟其他 skill 不重叠。