okx-auto-position: 余额不足显式提示 + exit code != 0
**Bug**: 8/4 20:32 SNDK 加仓信号 done, 但 OKX 没持仓 — 用户以为是 bug **原因**: process_signal.py 余额不足时只推'pushed_add_insufficient'消息, 不标 failed signal_queue.db 标 done → 用户/agent 都以为是 bug **Fix**: 1. process_signal.py 新增 _get_usdt_free() helper (实时查 OKX USDT free) 2. 余额不足时 QQ 推送加前缀 '⚠️ 跟单失败: 余额不足 ⚠️' + USDT 余额显示 3. process_signal.py main() 加 exit code 2 (跟单失败时) → signal_queue.retry 标 failed (而非 done) 4. retry < 3 仍会重试, 但 failed 状态可区分 done (signal_queue.db 加 status='failed') **注意**: advisor 实际会给 0.056 张 SNDK (USDT 26.82 保证金), 不是 0 张 — 但用 99.7% 余额不健康 → 用户应该知道是'满仓'而非'跟单成功'
This commit is contained in:
@@ -602,6 +602,22 @@ def format_close_message(fields, close_result):
|
|||||||
|
|
||||||
# ─── 执行订单 ────────────────────────────────────────────────────────────
|
# ─── 执行订单 ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
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()
|
||||||
|
# 兼容 ccxt OKX 多账户结构
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def execute_order(symbol, side, leverage, rec):
|
def execute_order(symbol, side, leverage, rec):
|
||||||
"""执行开仓订单"""
|
"""执行开仓订单"""
|
||||||
cmd = [
|
cmd = [
|
||||||
@@ -809,14 +825,28 @@ def process_signal(text):
|
|||||||
trader_pnl=float(fields.get('pnl', '0').replace(',', '')),
|
trader_pnl=float(fields.get('pnl', '0').replace(',', '')),
|
||||||
raw_text=text, outcome='auto_executed_add')
|
raw_text=text, outcome='auto_executed_add')
|
||||||
else:
|
else:
|
||||||
# 余额不足/执行失败 → 推消息不执行
|
# 余额不足/执行失败 → 推消息不执行 (2026-08-05: 余额不足显式提示)
|
||||||
msg = format_message(fields, rec, signal_type)
|
exec_err = (exec_result or {}).get('error', 'unknown') if exec_result else 'no result'
|
||||||
|
# 看是余额不足还是其他错
|
||||||
|
is_insufficient = '余额不足' in str(exec_err) or 'insufficient' in str(exec_err).lower()
|
||||||
|
# 实时查 USDT free (用 okx_position_advisor helper)
|
||||||
|
usdt_free = _get_usdt_free()
|
||||||
|
if is_insufficient:
|
||||||
|
msg = format_message(fields, rec, signal_type)
|
||||||
|
msg = f"⚠️ **跟单失败: 余额不足** ⚠️\n\n{msg}\n\n💡 你 USDT ${usdt_free:.2f} 不足以开 1 张 {symbol} 3x 杠杆 (约需 ~$46k)\n"
|
||||||
|
outcome = 'pushed_add_insufficient'
|
||||||
|
else:
|
||||||
|
msg = format_message(fields, rec, signal_type)
|
||||||
|
msg = f"⚠️ **跟单失败: 执行错误** ⚠️\n\n{msg}\n\n❌ 错误: {exec_err}\n"
|
||||||
|
outcome = 'auto_executed_failed'
|
||||||
_tracker_record(trader=trader, symbol=symbol, side=side,
|
_tracker_record(trader=trader, symbol=symbol, side=side,
|
||||||
leverage=int(leverage) if leverage else 10,
|
leverage=int(leverage) if leverage else 10,
|
||||||
trader_size=float(fields.get('size', '0').replace(',', '')),
|
trader_size=float(fields.get('size', '0').replace(',', '')),
|
||||||
trader_entry=float(fields.get('entry', '0').replace(',', '')),
|
trader_entry=float(fields.get('entry', '0').replace(',', '')),
|
||||||
trader_pnl=float(fields.get('pnl', '0').replace(',', '')),
|
trader_pnl=float(fields.get('pnl', '0').replace(',', '')),
|
||||||
raw_text=text, outcome='pushed_add_insufficient')
|
raw_text=text, outcome=outcome)
|
||||||
|
# 2026-08-05: 在 main() 标记 status=failed (signal_queue.db) — 让 cron retry 时知道
|
||||||
|
_exec_failed = exec_err
|
||||||
elif signal_type == 'reduce':
|
elif signal_type == 'reduce':
|
||||||
# 减仓信号: 锁了同方向 → 按大佬减仓比例, 自动减我们的同向持仓
|
# 减仓信号: 锁了同方向 → 按大佬减仓比例, 自动减我们的同向持仓
|
||||||
try:
|
try:
|
||||||
@@ -908,6 +938,10 @@ def main():
|
|||||||
|
|
||||||
result = process_signal(text)
|
result = process_signal(text)
|
||||||
print(result)
|
print(result)
|
||||||
|
# 2026-08-05: 余额不足/执行失败 → exit code != 0 → signal_queue.retry 标 failed
|
||||||
|
import sys as _sys
|
||||||
|
if '跟单失败' in str(result):
|
||||||
|
_sys.exit(2)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user