v4.5.38: 实时数据查询硬规则(回复前必查)+ check_account.py封装
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# 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
|
||||
|
||||
## 规律
|
||||
|
||||
- 信号 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 字段
|
||||
Reference in New Issue
Block a user