13 KiB
v4.5.68 (2026-08-30) Phantom Execute 加剧 + Cross 模式降杠杆被拒 + 调杠杆信号 "3→4" 解读
详细复现: 本次 session
三件新事件 (本次 session 续 v4.5.66 / v4.5.67)
1. Phantom Execute 加剧 — 几乎每个熬鹰信号都幽灵成交
症状: process_signal 报 ⏭️ 跳过: 信号源未知 | <X> <side> 或 ⏭️ 跳过: 性价比低 | <X> <side>,但 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 个):
- trader='未知' 闸没拦 execute 路径:
process_signal()在classify_signal()后加了闸,但 advisor 的 execute 路径 (okx_position_advisor.py --execute) 是独立脚本,直接读信号文本 + 直接调 ccxt.create_order, 完全不经过 process_signal 主流程 - advisor 的
contracts字段不可信: advisor JSON 返回的contracts是基于可用 USDT ×45% / 每张保证金 计算,但实际 ccxt 下单时用了不同的 ctVal / 最小变动单位计算器 - "性价比低"判断在 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 "实际未成交"
# 实战模板
python3 process_signal.py "signal"
sleep 5
python3 check_account.py <X>-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.
复现命令:
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
代码已对:
new_lev = int(fields.get('leverage') or '10')
# leverage 字段在 `【币种】: <X>|永续|<LEV>x` 取到, 取 LEV = 2
用户误读防范:
- ❌ "5→2 我手动调到 5x" (我本次 session 干过这傻事)
- ✅ 永远取
永续|<LEV>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 完整形式。
正确:
from signal_tracker import acquire_lock
ok, msg = acquire_lock("MSTR", "熬鹰资本", "short", reason="手动加锁", auto=False)
# ✓ 无后缀
ok, msg = acquire_lock("MSTR-USDT-SWAP", "熬鹰资本", "short", ...)
# ✗ 永远锁不上
验证:
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 末段):
# /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 实战遇到):
- POST body 必须
body=bodykeyword arg (v4.5.64 已修, 但每次新写脚本要警惕) - reduceOnly 平仓:
sz必须严格等于持仓张数, 否则 OKX 报 51169 - proxy 必须保留: 私有 API 直连会被 OKX 拒绝
- 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 不重叠。