5.7 KiB
5.7 KiB
v4.5.64 (2026-08-26) 调杠杆信号必须自动跟进 + raw REST 参数顺序陷阱
本次 session 在 v4.5.63 (手动锁 + symbol 一致性 + ETH ghost close) 基础上的新教训
教训 1: 调杠杆信号不在 advisor 的"性价比低"覆盖范围
用户质问: "这个怎么没有跟调杠杆?"
症状: 熬鹰发出 🔧 注意, 大佬修改了杠杆 3→4x 信号, process_signal 分类为新开仓 ('open'), 进 advisor → advisor 看 avgPx × 当前价格 × 杠杆 → 报"1.4张 性价比低" 或 "0.01张 性价比低" → 跳过。结果: 用户的 ETH long 1.4张@3x 没自动调到 4x。
根因:
classify_signal()没有adjust_leverage类型, 信号被默认归为'open'- advisor 只计算 open/add/reduce 的仓位, 不处理 set-leverage
- 白名单闸 (
'open', 'add', 'reduce') 也不会拦到调杠杆, 但调杠杆信号照样进 advisor → 报"性价比低" → 跳过
修复 (已合入 scripts/process_signal.py):
classify_signal()加adjust_leverage类型识别:
# 加仓信号
if '加仓' in text or '追仓' in text:
return 'add'
# 调杠杆信号 (2026-08-26: 必须跟, 不算性价比低 — 熬鹰调整杠杆是策略节奏)
if '修改了杠杆' in text or '调整了杠杆' in text or '调杠杆' in text:
return 'adjust_leverage'
# 默认为新开仓
return 'open'
- 白名单闸加
adjust_leverage:
if _sig_type_for_gate in ('open', 'add', 'reduce', 'adjust_leverage') and trader not in _TRADER_WHITELIST:
return f"⏭️ 跳过: trader [{trader}] 不在白名单 | {symbol} {side}"
- process_signal() 主流程加独立分支 (在 close 信号之后, 2分钟窗口 dedup 之前):
# 调杠杆信号 (2026-08-26: 熬鹰调整杠杆要跟, 不走 advisor, 直接 set-leverage)
if signal_type == 'adjust_leverage':
dedup_conn = init_dedup_db()
if is_duplicate(dedup_conn, text, symbol, trader):
dedup_conn.close()
return "⏭️ 重复信号,跳过"
record_signal(dedup_conn, text, symbol, trader)
dedup_conn.close()
symbol_usdt = fields['symbol']
new_lev = int(fields.get('leverage') or '10')
lev_result = adjust_leverage_raw(symbol_usdt, new_lev)
if lev_result and lev_result.get('ok'):
msg = f"⚙️ **杠杆已调整** | {symbol_usdt} → {new_lev}x"
push_to_qq(msg)
return f"✅ 调杠杆: {symbol_usdt} → {new_lev}x"
else:
err = lev_result.get('error', '未知')
return f"❌ 调杠杆失败: {err} | {symbol_usdt}"
为什么不走 advisor?
- advisor 只算 open/add/reduce 仓位, 不算 set-leverage
- 走 advisor 会被
性价比低闸拦掉 - 调杠杆本质是单参数调用 (POST /api/v5/account/set-leverage), 不需要 advisor 的仓位计算
教训 2: _okx_raw_request 参数顺序陷阱 (POST body 必须 keyword arg)
症状: 调用 adjust_leverage_raw 第一次报 '❌ 调杠杆失败: Incorrect json data format'
根因:
def _okx_raw_request(method, path, params=None, body=None, timeout=15):
...
签名是 (method, path, params, body, timeout), 第 3 位是 params, 第 4 位才是 body。
错误写法 (第 3 位传 body, 被当成 params):
resp = _okx_raw_request('POST', '/api/v5/account/set-leverage', body)
# 实际上 body 被当 params={...} 传了 → OKX 服务端签名校验失败
正确写法:
resp = _okx_raw_request('POST', '/api/v5/account/set-leverage', body=body)
SOP (硬规则, v4.5.64 起执行):
- 任何
_okx_raw_requestPOST 调用 → body 必须 keyword arg (body=...) - 这是 v4.5.63 ETH ghost close 调查时埋下的同源 bug (虽然当时没暴露, 因为 close 路径用的是 GET)
- v4.5.62 手动 execute 模板 (manual_order.py) 也可能踩这个坑 → 下次 session 第一件事检查 manual_order.py 的 okx_post 函数
验证:
# 调杠杆信号后, check_account.py 应该看到新的 lever 字段
python3 ~/.hermes/skills/trading/okx-auto-position/scripts/check_account.py <INST_ID>
# 检查 "lever" 字段 = 目标倍数
实战时间线 (本次 session)
- 用户 ETH long 1.4张@3x 已开仓 (v4.5.63 残留)
- 熬鹰 ETH 调杠杆 3→5x 信号进来 → process_signal 走 advisor → 报"性价比低" → 跳过
- 用户质问: "这个怎么没有跟调杠杆?"
- 我手动 raw REST set-leverage 4x → USDT 占用从 $87.72 → $70.12 (降, 因为杠杆升)
- 用户: "要 [改代码]"
- 我加
adjust_leverage_raw+adjust_leverage类型 + 主流程分支 - 测试调杠杆信号 → 先报
'❌ Incorrect json data format'→ 找到参数顺序 bug - 修复后:
✅ 调杠杆: ETH → 5x(从 4x 升 5x)
最终持仓:
- ETH long 1.4张@5x (avgPx 2486.74, 浮盈+$2.45, 占用 $70.12)
- USDT 可用 $87.99 / 权益 $158.10
- ETH 锁 ✅ 熬鹰资本 long (手动锁)
- MSTR short 4.01张@5x (avgPx 126.04, 浮亏-$0.21, 占用 $101.12)
部署清单 (下次 session 第一件事)
manual_order.py的 okx_post 函数: 确认所有 POST 都用 keyword argbody=body, 不能位置传 body- process_signal 加
adjust_leverage_raw调用也走 dedup (已实现) - 测试: 调杠杆信号进来 → 自动 set-leverage + 推 QQ
- 调杠杆失败时: 区分"无持仓可调" (要查持仓) vs "API 报错" (重试)
- 白名单闸的 signal_type 集合统一抽到顶层常量 (现在散落在多处)
跨 session 索引
- v4.5.38: 实时数据查询硬规则
- v4.5.53: trader='未知' 闸
- v4.5.61: trader 白名单 (只跟熬鹰)
- v4.5.62: dedup 手动清 + 手动加仓模板
- v4.5.63: 手动锁 + symbol 一致性
- v4.5.64 (本次): 调杠杆信号自动跟进 + _okx_raw_request 参数顺序陷阱