# OKX process_signal.py 杠杆丢失 Bug - 实战复现 **Captured**: 2026-07-13 **Skill version**: okx-auto-position v4.5.2+ **Severity**: Critical (风险放大 2-5 倍,爆仓概率翻倍) ## Symptom `process_signal.py` 收到的信号里 `leverage` 字段(如 2x / 5x),advisor.execute 实际下单时**始终是 10x**——process_signal.py 把信号的 leverage 字段丢了,直接传默认值 10 给 advisor。 ## Confirmed Cases (3 次) ### Case 1: 风寻 SKHY short (2026-07-08) - 信号: 528.16 SKHY short @5x @161.90, +1.68% PnL - 实际 execute: SKHY short 2.89张 @**10x** @avgPx 161.01 - 强平价: 192.86 (vs 信号 5x 应该 ~165,实际 10x 推到 192) - 浮盈: +$1.88 (跟单成功,但杠杆翻倍 = 风险翻倍) ### Case 2: 风寻 SKHY short (2026-07-13) - 信号: 3973.30 SKHY short @**2x** @157.30, +0.64% PnL - 实际 execute: SKHY short 3.18张 @**10x** @avgPx 157.02 - 强平价: 187.95 (信号 2x 应该 ~157+(157/2)*0.01 = 157.78,实际 10x 推到 188) - 浮盈: +$1.88 ### Case 3: 熬鹰 MU short (2026-07-13) - 信号: 664.37 MU short @**2x** @937.62, -0.01% PnL - 实际 execute: MU short 0.52张 @**10x** @avgPx 940.40 - 强平价: 1136.92 (信号 2x 应该 ~940+(940/2)*0.01 = 944.70,实际 10x 推到 1137) - 浮亏: -$0.28 ### Case 4: 熬鹰 BTC long 20x (2026-07-21) - 信号: 49.958 BTC long @20x @65547.73 - 实际 execute: 0.01 张 BTC long @10x @65407.6 (用 OKX 私有 API setLeverage 强制设 20x, 仍被覆盖成 10x) - 浮亏: -0.01 USDT (立刻平了) - **教训**: setLeverage 私有 API 不生效, 下单时仍用 10x (process_signal 内部写死) - **新加 bug**: OKX 最小下单单位 min_sz 触发 → 我传 0.014 张, 实际成交 0.01 张 (0.01 是 min_sz) - 双重 bug: leverage 5→10 + min_sz 截断。**两个都没在 process_signal 修过** ## 规律 - 信号 5x → 实际 10x (2 倍) - 信号 2x → 实际 10x (5 倍) - **execute 一律用默认值 10x,从不读信号里的 leverage** ## Root Cause (推测) `process_signal.py` 调用 advisor 时,`leverage` 字段可能是: 1. 没传 → advisor 默认 10 2. 传了但被覆盖成 str(10) 3. parse_signal 的 leverage 字段解析错误(数字 + 'x' 后缀没去掉) ## Agent 侧强制校验流程 ```python import json, time, hmac, hashlib, base64, requests def okx_get(p, params=None, t=15): # ... 标准 raw REST GET 签名 ... pass # 1. execute 之后立即反查 signal_leverage = 5 # 信号原文 pos = okx_get('/api/v5/account/positions', {'instId': 'SKHY-USDT-SWAP'}) for p in pos.get('data', []): actual_leverage = int(p.get('lever', 10)) if actual_leverage != signal_leverage: # 杠杆不对!manual close + 重开 # 1. close current position close_body = { 'instId': 'SKHY-USDT-SWAP', 'tdMode': 'cross', 'side': 'buy' if float(p['pos']) < 0 else 'sell', 'posSide': 'net', 'ordType': 'market', 'sz': str(abs(float(p['pos']))), 'reduceOnly': True, } okx_post('/api/v5/trade/order', close_body) # 2. reopen with correct leverage open_body = { 'instId': 'SKHY-USDT-SWAP', 'tdMode': 'cross', 'side': 'sell' if signal_side == 'short' else 'buy', 'posSide': 'net', 'ordType': 'market', 'sz': str(contracts), 'lever': str(signal_leverage), # 显式传 leverage } okx_post('/api/v5/trade/order', open_body) ``` ## 永久修复 (待改 process_signal.py) ```python # process_signal.py parse_signal() 函数 def parse_signal(text): # ... lev_match = re.search(r'【杠杆】\s*[::]?\s*(\d+)\s*[xX]', text) if lev_match: fields['leverage'] = int(lev_match.group(1)) # 验证范围 if not 1 <= fields['leverage'] <= 50: fields['leverage'] = 10 # fallback return fields # 然后调 advisor 时: cmd = ['python3', 'okx_position_advisor.py', '--symbol', symbol, '--side', side, '--leverage', str(fields['leverage'])] # 不用默认 10 ``` ## 已知受害币种 - SKHY (2 次) - MU (1 次) - 任何信号标 2x / 5x 的小币种永续合约都需校验 ## 实战价值 - 5x → 10x:风险 2 倍,强平价远 50% - 2x → 10x:风险 5 倍,强平价远 100%+ - 10x 杠杆下,1% 价格波动 = 10% 保证金波动,极容易爆 ## 相关 SKILL.md 章节 - "v4.5.2 process_signal 杠杆丢失 bug" - 主入口 - "v4.5.0 平仓信号自动跟单" - 检测时需查 lever 字段 ## Agent 行为铁律 (2026-07-17 用户原话) ### 1. 跟单不许反问 - **信号来了立刻 advisor → 下单** - 不问 yes/no/几张 - 用户说"按信号来"=立即执行,不讨论 - (累计 3 次用户指出 2026-07-17 违反此规则) ### 2. 下单后立即验证 (不要把 advisor 推荐当事实) - 下单后**立刻** `fetch_positions()` 查**真实**:lever, margin, notional, entryPrice - advisor 推荐值 ≠ 实际成交值 - 实战教训(2026-07-17): 用户说"5x 杠杆", advisor 算 5x, 实际下单 10x (process_signal.py bug) - 实际占 $26.92, 报告时错说 $53,**用户立即指出"又是猜的"** - 教训:**下单后必须 fetch_positions 验证 3 件事** - actual_leverage == requested - actual_margin == expected - actual_side == expected ## references index 更新 此 reference 是 OKX advisor 杠杆 + 下单事实校验的权威来源。任何新错误 / 修复补这里, MEMORY 只存指针。