Files
Hermes-Skills/okx-auto-position/references/spcx-silent-fail-repro.md
T

113 lines
4.5 KiB
Markdown

# SPCX-USDT-SWAP Silent-Execute-Failure Repro
**Captured**: 2026-07-13
**Skill version**: okx-auto-position v4.5.4
**Severity**: High (advisor reports success, but no order fills)
## Symptom
`okx_position_advisor.py --symbol SPCX --side {short,long} --leverage 5 --execute --json` returns a full success-shaped JSON with `contracts`, `margin`, `tp_price`, `sl_price`, `cost_check.auto_execute=true` etc. However:
1. `GET /api/v5/account/positions?instId=SPCX-USDT-SWAP` returns empty list
2. `GET /api/v5/account/balance` `details[ccy=USDT].frozenBal` unchanged
3. No order_id anywhere in advisor stdout
4. process_signal pushes "✅ 已推送 | SPCX short 5x | 1.45张 | 性价比高" — but position is actually 0
## Reproduction (3 cases confirmed)
### Case 3 (2026-07-13): MU short 新开仓静默失败
- Signal: 熬鹰 MU short 334.95张 @10x @937.67, -0.15% PnL
- Advisor: 0.51张 @10x, margin=$48.78
- execute: JSON returned normally
- Verify (5s after): positions=MU-USDT-SWAP not in list, frozenBal=0
- Status: ❌ silent failure (3rd coin confirmed)
### Key finding: MU 加仓可成功但新开仓失败
- 紧跟 MU 新开仓静默失败之后,**MU 加仓信号触发 execute 成功**: 0.52张 @10x, avgPx 940.40, 真实持仓确认
- 推测: ccxt 对 "首次建仓" vs "加仓" 走不同下单路径,首次建仓时可能在 ctVal/minSz 处理上漏掉
- **MU 实战规则**: 新开仓(existing_pos=0) → 必须 raw REST 手动下单; 加仓(existing_pos>0) → 可信 advisor
### Case 1: SPCX short
- Signal: 熬鹰 SPCX short 17350张 @5x @148.59, +1.52% PnL
- Advisor: 1.45张, margin=$43.15, tp=$133.86, sl=$153.85, liq=$175.57
- execute: JSON returned normally
- Verify (3s after): positions=SPCX-USDT-SWAP not in list, frozenBal=0
- Status: ❌ silent failure
### Case 2: SPCX long
- Signal: 熬鹰 SPCX long 4514张 @2x @139.21, +0.28% PnL
- Advisor: 3.5张, margin=$48.78
- execute: JSON returned normally
- Verify (5s after): positions=SPCX-USDT-SWAP not in list, frozenBal=0
- Status: ❌ silent failure (second time same coin, same symptom)
## Root cause (hypothesized)
OKX's SPCX-USDT-SWAP contract likely has unusual min-size/step-size/lot-size rules that ccxt's `create_market_sell_order` doesn't auto-handle. The advisor's execute path silently catches the error and returns the recommendation JSON anyway (without an `order_id` field).
## Detection snippet
```python
import json,time,hmac,hashlib,base64,requests
def okx_get(p, params=None, t=15):
# ... standard raw REST GET with OKX_ACCESS_SIGN ...
return requests.get(...).json()
# 1. Run execute
import subprocess
r = subprocess.run(['python3', 'okx_position_advisor.py', '--symbol', 'SPCX',
'--side', 'short', '--leverage', '5', '--execute', '--json'],
capture_output=True, text=True, timeout=60)
exec_json = json.loads(r.stdout)
# 2. Verify within 3 seconds
time.sleep(3)
pos = okx_get('/api/v5/account/positions', {'instId': 'SPCX-USDT-SWAP'})
positions = [p for p in pos.get('data', []) if float(p.get('pos', 0) or 0) != 0]
bal = okx_get('/api/v5/account/balance')
frozen = next((float(d['frozenBal']) for d in bal['data'][0]['details'] if d['ccy'] == 'USDT'), 0)
if not positions and frozen == 0:
# SILENT FAILURE
# Manual raw REST retry
body = {
'instId': 'SPCX-USDT-SWAP',
'tdMode': 'cross',
'side': 'sell' if 'short' in exec_json.get('side', '') else 'buy',
'posSide': 'net',
'ordType': 'market',
'sz': str(exec_json['contracts']),
}
result = okx_post('/api/v5/trade/order', body)
print(json.dumps(result, indent=2))
```
## Manual fallback (when detected)
```python
body = {
'instId': 'SPCX-USDT-SWAP',
'tdMode': 'cross',
'side': 'sell', # short
'posSide': 'net',
'ordType': 'market',
'sz': '1.45', # from advisor contracts
# reduceOnly=False (initial open)
}
# POST /api/v5/trade/order
```
## When to extend this list
Add a new entry whenever a coin shows the same silent-fail pattern:
- Other small-cap contracts: SKHY, SNDK, MU USDC-margined variants
- After 2+ confirmed silent failures, treat coin as "manual-only" and skip advisor's --execute path entirely
- Instead: raw REST direct placement, skip advisor recommendation block
## Related pitfalls in SKILL.md
- "v4.5.0 新坑 process_signal/advisor `--execute` 不返回 `order_id`" — covers detection
- "v4.5.2 CCXT vs Raw REST 可靠性差距" — covers ccxt SSL/timeouts but NOT this silent-fail case
- "v4.5.4 SPCX-USDT-SWAP 自动下单静默失败" — main entry in SKILL.md