Files
Hermes-Skills/trading-signal-aggregator/SKILL.md
T

6.9 KiB

name, description, version, tags
name description version tags
trading-signal-aggregator Aggregates and categorizes high-frequency trading signals (A/B/C/D/E) to prevent spam and manage risk. 1.0.0
trading
signal
crypto
eth
btc

Trading Signal Aggregator (TSA)

This skill manages the high-frequency signal stream from multiple sources (e.g., 5912, 熬鹰, 麻吉) to prevent chat-flooding while maintaining enough granularity for profitable execution.

⚠️ Core Logic (The "Anti-Spam" Filter)

1. Signal Classification (Priority: High)

When a signal arrives, classify it immediately to determine the appropriate response/push.

Class Trigger Condition Push Strategy (to QQ)
A-加仓 (e.get_pos_change() > 5%) OR (New high-conviction signal) Full Template: Trend analysis + detailed plan.
B-减仓/危险 (Pos change < -5%) OR (Liquidation risk high) Full Template: Focus on risk/exit.
C-新开仓 (First appearance of coin/trader) Full Template: Light entry plan.
D-持有更新 (Pos change < 5% OR minor price/leverage adjustment) Minimalist: Skip trend analysis, show current status + plan.
E-多鲸对比 (Multiple signals or cross-trader comparison) Comparison Template: Side-by-side summary.

2. The "Noise" Rule (Cruo/D-class)

If the change in position or price is within a certain threshold (e.g., <2% or <5% depending on context), do not push a new message. Instead, track it in the current session.

  • If multiple signals arrive in one tick, prioritize the one with the largest absolute change or highest risk/reward.
  • If a signal is "D-class" (minor adjustment), it should only be pushed if it crosses a significant threshold or if the user asks for an update.

📦 Templates (Reference)

[trade-confirm] - Full Template

(Use for A, B, and C classes)

⚡ 跟单建议 | {币种} {方向} {杠get_leverage}x

📊 {交易员} {仓位} {币种} (价值{总值})
入场: {入场价} | 当前: {当前价}
浮盈/亏: {盈亏} 🔥 | 强平距: {距离} ✅

📈 趋势分析
• {trend_point_1}
• {trend_point_2}

🛡️ ATR/Risk Check
• {atr_info} | {risk_status} (e.g. SL/ATR check)

🎯 跟单方案
• 入m: {入场价} (市价/参考均价)
• 止损: {止损价} ({+/-%}, {amount}, 盈亏比)
• 止盈: {止盈价} ({+/-%}, {amount})
• 仓位: {建议仓位} (e.g. 轻/中/重)

回复 Y 确认 / N 取消

[trade-update] - Minimalist (D-class)

(Use for minor adjustments/noise)

📊 {交易员} {仓位} {币种} (当前: {当前价})
入场: {入场价} | 状态: {status_msg} (e.get_pos_change())

🎯 跟单方案
• 入场: {入场价}
• 止损/止盈: {sl_tp_info}
• 仓位: {建议仓位}

回复 Y 确认 / N 取消

🛠️ Operational Rules (The "Golden Rule")

  1. No redundant analysis: If the signal is a minor adjustment (D-class), do not re-calculate trend/ATR unless it's a significant enough change to warrant it.
  2. Priority: A-class (加仓) and C-class (新开) always get full attention.
  3. Aggregator logic: If multiple signals arrive, group them into a single response if possible (e.g., "Summary of last 3 signals").
  4. Manual override: If the user asks for a summary or "what's next", use the current state to provide a consolidated view.

5. No verbose tracking (User correction 2026-07-02): Do NOT create statistical tables, trend analysis, or verbose summaries for D-class signals. Just process A/B/C signals with the opening skill and push to QQ. For D-class signals, simply note "跳过QQ推送" (skip QQ push) without detailed tracking tables. The user explicitly said: "有信号就用开仓技能就行了,其他不需要你统计" (Just use the opening skill for signals, no need for you to do statistics).

6. **"无持仓 + 减仓信号 = 静默跳过" (User correction 2026-09-20) 🔇

踩坑现场: 熬鹰币安实盘重复发同一减仓信号(同币种同方向),如果用户没有对应持仓 → process_signal.py line 1131 推 ⏭️ 减仓信号: 你无 ZAMA 持仓, 跳过 到 QQ → 1 分钟内刷屏 50+ 条相同消息。User 原话: "这种减仓的,而我没有持仓的就不处理了"。

正确行为 (修改 process_signal.py):

if not our_pos:
    msg = None              # None = 不推 QQ
    outcome = 'silent_no_pos'
    # ... 后续 record_signal + dedup 正常执行, 但跳过 push_to_qq
if msg is None:
    return f"🔇 静默跳过 | {symbol} {side} {leverage}x"

铁律:

  • 静默 "无持仓 + 减仓信号" 路径 = 不推 QQ 但仍然 record_signal (用于去重)
  • 不要给静默留 push 选项 ("要不要 push 一下说明?") — 用户明令"不处理"
  • 静默指标: outcome = 'silent_no_pos' 写到 _tracker_record() 便于事后查询"为什么没动"
  • 同类 D-class 静默候选: 平仓信号无持仓、加仓信号总资产超阈值 ($1000)、调杠杆信号无持仓、减仓信号无持仓

7. **process_signal 失败路径仍 mark_done — 信号队列 bug (2026-09-20 实战)

踩坑现场: BTC 平仓信号 (queue 337, 9/21 03:12) → close_position_raw() 因 proxy 抽风返 None → process_signal.py line 868 return "❌ 平仓失败: ..." → returncode = 0(正常退出)→ signal_queue.py line 110 if r.returncode == 0: mark_done(row_id, r.stdout[:200]) → queue 标 done 但仓位没平。

事故代价: BTC 1.6 张 short 5 小时持仓, 价格波动导致 UPL 从 -X% 到 -50.5% (-$69) — 用户手动发现前已扩大亏损 (User 原话: "是啊,为什么标记done了,亏损翻倍了")。

根因:

  • signal_queue.py 只判 returncode, 不看 result 内容
  • process_signal.py 平仓失败分支只 return 字符串, 不抛异常 → returncode = 0
  • result 列被写成 ❌ 平仓失败: ... 但被标为 done

当前修复 (临时):

  1. 平仓失败必须推 QQ (line 864-866 已修, 2026-09-16)
  2. 用户会看到 ❌ 推送 → 手动补救
  3. 但 queue 仍然标 done → 不会 retry → 错过的信号不会再来

推荐修复 (TODO):

  • process_signal.py 平仓失败时 sys.exit(1) 或 raise exception → signal_queue.py mark_failed
  • OR: signal_queue.py 改判 returncode + 检测 stdout 是否含 ❌/失败/proxy 抽风
  • OR: 加 retry 字段 (retries < 3 才 fail)

应急检测 (查历史有没有漏掉的失败):

sqlite3 ~/.hermes/trading/signal_queue.db \
  "SELECT id, substr(created_at,1,19), substr(result,1,80) \
   FROM queue WHERE result LIKE '%❌%' AND status='done' ORDER BY id DESC LIMIT 20"
# → 列出来的就是"标 done 但实际失败"的信号, 必须手动补救

铁律:

  • signal_queue.db 的 status 不等于 实际结果 — 必须看 result 列
  • 任何 status='done' + result 含 ❌ / 失败 / proxy 抽风 = 实际失败, 必须 re-fetch OKX 验证
  • 不要信任 cron "跑过" 的日志 — 必须 cross-check 实际仓位