5.7 KiB
5.7 KiB
v4.5.41 (2026-08-04) 信号队列 done 但未实际下单 — process_signal.py add 信号路径 bug
⚠️ 问题
signal_queue.db 标记 status='done' ≠ OKX 实际下单成功。
实战案例 (2026-08-04 20:20-20:32):
- 熬鹰资本 SNDK 做空 加仓信号 (4 条, ID 41-44)
- 每条 3 秒内就 done
- 全部推到 QQ
- 用户 USDT $95.52 (账户实际余额)
- SNDK @ 1390, 1 张 = $139k 名义, 3x 杠杆保证金 = $46k
- 1 张 SNDK 都开不了 (USDT < 保证金)
execute_order返回 contracts=0 →process_signal.pyline 813-818 走pushed_add_insufficient分支- 未真下单, 但 status='done', QQ 推了消息
用户问"跟了吗": 看 signal_queue.db 都 done, QQ 也推了 → 看似跟了 实际: 0 张 SNDK 持仓, USDT $95 余额不足
🔍 根因 (process_signal.py 802-819)
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'
msg = format_execution_result(fields, rec, exec_result)
_tracker_record(...outcome='auto_executed_add')
else:
# 余额不足/执行失败 → 推消息但不执行
msg = format_message(fields, rec, signal_type)
_tracker_record(...outcome='pushed_add_insufficient')
# ⚠️ 此处没区分 "真正 done" vs "未下单",后续 mark done 时仍标 status='done'
核心问题: signal_queue.db 的 status 字段只有 done/failed,没有"未下单"状态。
🔍 检测方法
# 1. 看 signal_queue.db 标记 done 但实际没持仓的信号
sqlite3 ~/.hermes/trading/signal_queue.db "
SELECT id, substr(raw_text,1,40), datetime(created_at)
FROM queue WHERE status='done' AND datetime(created_at) > '2026-08-04'
ORDER BY id DESC LIMIT 10"
# 2. 同时查 OKX 当前持仓 (看是否有该币种)
# 用 raw REST: GET /api/v5/account/positions?instId=SNDK-USDT-SWAP
# 3. 如果 done 信号超过 N 条但持仓 0 → 大概率"余额不足未下单"
🛠️ 推荐修复
方案 A: 加新 status 字段 not_executed (推荐)
signal_queue.dbschema 加'not_executed'statusprocess_signal.pyline 818 改:mark_done→mark_not_executed- query 时:
SELECT * FROM queue WHERE status IN ('pending', 'failed') AND retries < 3不变 (仍然 retry pending/failed) - 单独 query
not_executed看哪些被余额不足跳过
方案 B: 在 outcome 字段加 'skipped_insufficient_balance'
_tracker_record已经传outcome='pushed_add_insufficient'signal_history.dbconfirmed_signals 表的 outcome 字段已支持- ✅ 这个方案已部分实现 — 但
signal_queue.db还是 done - 加 query helper:
SELECT * FROM confirmed_signals WHERE outcome LIKE 'pushed_%'看推送未下单信号
方案 C: 加 advisor 余额预警 (推荐)
execute_order返回 contracts=0 时:- 推 QQ 消息 + 写
outcome='pushed_add_insufficient' - 同时往
alert_log表写一行: "余额不足, 大佬 X 仓 Y 张, 你 USDT Z" - 用户主动查 alert_log 看 "为什么没跟"
- 推 QQ 消息 + 写
- 解决信号队列 done 误判问题
📊 已识别余额不足场景 (2026-08-04)
| 信号 | 大佬仓位 | 你的余额 | 所需保证金 | 状态 |
|---|---|---|---|---|
| SNDK 做空 197.17 张 (8/4 20:32) | @ 1390 × 100 SNDK × 3x | USDT $95 | $46k+ | done 但未下单 |
| SNDK 做空 65.85 张 (8/4 20:20) | @ 1391 × 100 × 2x | USDT $95 | $70k+ | done 但未下单 |
当前 OKX USDT = $107.43 (8/5 11:00 后)
- 几乎所有熬鹰大单 (SNDK 200 张, BTC 13 张) 都跟不了
- 小币种 (PEPE 1000x) 单张 < $1 → 可以, 但熬鹰不做这种
- BTC 0.01 张 @ $64k × 10x = $640 保证金 → USDT 107 仍不够
🎯 行动建议
短期 (现在能做的)
- 手动查 signal_queue.db 最近 done 信号,看是否有"标记 done 但未下单"的
- 记录 outcome='pushed_add_insufficient' 的信号,用户每天看一次
- 告诉用户: 你 USDT 余额不够,所有熬鹰大单跟不了
中期 (改 process_signal.py)
- 实施方案 A 或 C: 区分 "done 真下单" vs "not_executed 余额不足"
- add
signal_alert_log表: 余额不足信号写入 alert_log - 加 cron
signal-unfunded-alert.py: 每天 21:00 推"今日未跟余额不足信号清单"
长期 (用户决定)
- 入金 ≥ $50k USDT 才能正常跟单
- 改 advisor 用更小仓位 (
account_util_cap=0.05+min_contracts=1) 跟小信号 - 改跟单比例 (默认
account_util_cap=0.30, 改为0.02让 $100 USDT 也能跟)
📌 关联文件
~/.hermes/skills/trading/okx-auto-position/scripts/process_signal.py(line 802-819, add 信号路径)~/.hermes/skills/trading/okx-auto-position/scripts/signal_queue.py(mark_done 逻辑)~/.hermes/skills/trading/okx-auto-position/scripts/okx_position_advisor.py(execute_order 返回 contracts=0 条件)~/.hermes/trading/signal_queue.db(status 字段)~/.hermes/trading/signal_history.db(confirmed_signals.outcome 字段)
🔗 关联 SKILL.md 章节
references/v4.5.27-2026-07-08-silent-execute-failure.md— SSL 抽风 execute 静默失败 (本质同类问题)references/v4.5.34-2026-07-08-execute-returns-success-no-fill.md— execute 返回成功但无 fillreferences/v4.5.38-symbol-normalization-1000pepe-and-silent-execute.md— 1000PEPE 小币种静默失败references/post-execute-verification-checklist.md— execute 后必须 raw REST 反查
共同主题: "信号处理成功" 不等于 "实际下单成功" — 任何 cron 推送 "已跟" 都必须经过 raw REST 反查验证, 不依赖 process_signal 自身的 mark_done 逻辑。