Files
Hermes-Skills/okx-auto-position/references/v4.5.42-insufficient-funds-explicit-notify.md
T

4.5 KiB
Raw Blame History

v4.5.42 (2026-08-05) 余额不足显式推送通知 + exit code != 0

⚠️ 用户原话 (2026-08-05 触发本次修复)

"这种余额不够的要通知啊,不然以为是Bug"

场景: 8/4 20:32 SNDK 加仓信号 (4 条 done), 用户 8/5 11:20 问"跟了吗", 答"已推(193.32→197.17张); 你无SNDK持仓; USDT $95.52", 用户反馈 "这个没有跟单成功吧"。

问题: process_signal.py 余额不足时只推 QQ 普通消息 + outcome='pushed_add_insufficient', 但 signal_queue.db 仍标 status='done', 用户看到 done 以为是真跟单。

🛠️ 已部署修复 (2026-08-05 commit f00b696)

1. 余额不足显式标识 (process_signal.py line 802-829)

elif signal_type == 'add':
    exec_result = execute_order(symbol, side, leverage, rec)
    if exec_result and 'error' not in exec_result and rec.get('contracts', 0) > 0:
        # 真下单成功 → 推执行结果 + outcome='auto_executed_add'
        ...
    else:
        # 余额不足/执行失败 → 显式前缀 + USDT 余额显示
        exec_err = (exec_result or {}).get('error', 'unknown')
        is_insufficient = '余额不足' in str(exec_err) or 'insufficient' in str(exec_err).lower()
        usdt_free = _get_usdt_free()  # 实时查 OKX
        if is_insufficient:
            msg = f"⚠️ **跟单失败: 余额不足** ⚠️\n\n{msg}\n\n💡 你 USDT ${usdt_free:.2f} 不足以开 1 张 {symbol} 3x 杠杆 (约需 ~$46k)\n"
            outcome = 'pushed_add_insufficient'
        else:
            msg = f"⚠️ **跟单失败: 执行错误** ⚠️\n\n{msg}\n\n❌ 错误: {exec_err}\n"
            outcome = 'auto_executed_failed'
        ...

2. exit code 2 让 signal_queue 标 failed (process_signal.py main())

result = process_signal(text)
print(result)
if '跟单失败' in str(result):
    sys.exit(2)  # signal_queue.retry 看到 rc != 0 → mark_failed

3. _get_usdt_free() helper (process_signal.py 604-619)

def _get_usdt_free():
    """实时查 OKX USDT free (失败返回 0)."""
    try:
        from okx_position_advisor import load_credentials, create_exchange
        creds = load_credentials()
        ex = create_exchange(creds)
        bal = ex.fetch_balance()
        usdt_info = bal.get('USDT', {}) if isinstance(bal, dict) else {}
        free = usdt_info.get('free', 0) if isinstance(usdt_info, dict) else 0
        return float(free or 0)
    except Exception as e:
        print(f"[warn] _get_usdt_free err: {e}", file=__import__('sys').stderr)
        return 0.0

🎯 修复效果 (预期)

场景 之前 现在
余额足够, 真下单 QQ 推"已跟单 X 张 @ Yx" + status=done 不变
余额不足, advisor contracts=0 QQ 推普通信号消息 + status=done ⚠️ QQ 推 "⚠️ 跟单失败: 余额不足 ⚠️ + USDT X 不足以开 1 张" + status=failed
advisor execute 报错 QQ 推普通信号消息 + status=done ⚠️ QQ 推 "⚠️ 跟单失败: 执行错误 ⚠️ + 错误信息" + status=failed
反向锁跳过 推"🔒 跳过" + status=done 不变 (这不是执行失败)

📊 实战数据 (2026-08-05 11:00 当前 OKX USDT)

信号 大佬仓位 所需保证金 USDT $107 能跟吗
SNDK 做空 197.17 张 @ 1390 × 3x $46k+ ❌ 不够 (但 advisor 会自动调张到 0.056 张, 占 99.7% 余额)
BTC 做多 1000 张 @ $64k × 10x $6.4k ❌ 不够 (advisor 调张到 1.25 张)
BTC 0.01 张 @ $64k × 10x $640 ❌ 不够

关键洞察: advisor 不是直接 0 张,而是按可用余额自动调小到 1 张或更少 → 跟单了但只下了 0.x 张,用户以为"真跟了 0 张失败", 实际"跟了但用了 99.7% 余额"。

🚨 关键提醒 (下次 session)

  1. 用户偏好: 余额不足必须显式通知, 不能"看起来跟了实际没跟"
  2. 信号推送文案: 用 ⚠️ **跟单失败: 余额不足** ⚠️ 前缀, 不要混在普通推送里
  3. status 闭环: process_signal rc != 0 → signal_queue 标 failed → cron retry 还能再试
  4. USDT < $50k 时, 几乎所有熬鹰大单 (SNDK/BTC 100+ 张) 都跟不了, 用户应主动入金

🔗 关联文件

  • scripts/process_signal.py line 604-619 (_get_usdt_free helper)
  • scripts/process_signal.py line 802-829 (余额不足分支)
  • scripts/process_signal.py main() (exit code 2)
  • scripts/signal_queue.py (mark_failed 已支持)
  • 实战案例: references/v4.5.41-signal-queue-done-but-no-order-execute.md (问题描述)