Files
Hermes-Skills/crypto-t-monitor/references/change-driven-push.md
T
mikeandClaude 4aae222173 feat(crypto-t-monitor): v2.3.0 新币自动挑选池 (PICKS=2, POOL_MAX=6)
- NEW_COIN_PICKS=2: 每次扫描后筛 2 个 (按 24h vol 排序)
- NEW_COIN_POOL_MAX=6: 永久保留上限, 超限自动裁最早加入
- 30 天内新币 + 24h vol > $1M, 自动加入监控池
- 推 QQ 仅在变化时 (与 v2.1 C 方案一致)
- references/: 新增 backtest-usage.md, change-driven-push.md, symbol-coverage-pitfall.md

用户原话: 新币最多保留六个, 每次扫描后筛选

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-10 19:43:21 +08:00

116 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Change-Driven Push 推送策略细节 (v2.1)
`okx_t_monitor.py` v2.1 的核心: **只在有变化时推 QQ**,其他静默。
## 📋 推送触发矩阵
| 触发条件 | 推送条目 | 频率 |
|----------|---------|------|
| 持仓变化 (`abs(new_pos - old_pos) > 0.001`) | 🔄 "持仓: X → Y 张" | **每次变化** |
| 价格触及 buy1/buy2/sell1/sell2 (距 < 0.5%) | 📍 "价格触及 buy2=Z (距 W%)" | **每次扫描** |
| 浮盈 ≥ 5% 且变化 ≥ 3% | 📈/📉 "浮盈变化: X% → Y% (Z%)" | **变化触发** |
| 做 T 实际成交 | ✅ 完整做T记录 (保留 v2.0 格式) | **每次成交** |
| 做 T 失败 (API code != 0) | ❌ 失败原因 | **每次失败** |
| 静默 (无以上 5 种) | (本地 print `💤 静默:`) | **静默** |
## 🔧 实现细节 (代码视角)
### `find_nearest_level(price, levels, traded_levels) -> str|None`
```python
def find_nearest_level(price, levels, traded_levels):
"""找价格 0.5% 内最近的关键位, 跨 4 个候选 (buy2/buy1/sell1/sell2)"""
threshold = 0.005 # 0.5%
nearest = None
min_dist = float('inf')
for name in ['buy2', 'buy1', 'sell1', 'sell2']:
if levels.get(name) is None:
continue
dist = abs(price - levels[name]) / price
if dist < threshold and dist < min_dist:
min_dist = dist
nearest = name
return nearest
```
**关键**: 同时检查 buy2 (距 -0.7×ATR) 和 sell1 (距 +0.49×ATR)。两个临界区都在 0.5% 内,**只汇报最近的一个**。
### `check_changes(sym, price, pos_qty, avg_px, upl, levels, state) -> list[str]`
```python
def check_changes(sym, price, pos_qty, avg_px, upl, levels, state):
"""返回事件 list (空 list = 无变化)"""
events = []
# 1. 持仓变化
prev_pos = state.get(f'{sym}_prev_pos')
if prev_pos is not None and abs(pos_qty - prev_pos) > 0.001:
events.append(f'🔄 持仓变化: {prev_pos:.2f}{pos_qty:.2f} 张')
# 2. 价格触及
nearest = find_nearest_level(price, levels, [])
if nearest:
level_price = levels[nearest]
dist_pct = abs(price - level_price) / price * 100
events.append(f'📍 价格触及 {nearest}={level_price:.2f} (距 {dist_pct:.2f}%)')
# 3. 浮盈变化 (多空方向修正)
if avg_px > 0 and pos_qty != 0:
leverage = SYMBOL_SPECS.get(sym, {}).get('leverage', 25)
pos_sign = 1 if pos_qty > 0 else -1
upl_pct = (price - avg_px) / avg_px * 100 * leverage * pos_sign
prev_upl_pct = state.get(f'{sym}_prev_upl_pct')
if prev_upl_pct is not None and abs(upl_pct) >= 5:
upl_diff = upl_pct - prev_upl_pct
if abs(upl_diff) >= 3:
emoji = '📈' if upl_diff > 0 else '📉'
events.append(f'{emoji} 浮盈变化: {prev_upl_pct:.1f}% → {upl_pct:.1f}% ({upl_diff:+.1f}%)')
return events
```
### State 持久化
`state` 字典除了原有 `traded_levels` 之外,新增两类 key:
- `{sym}_prev_pos`: 浮点数, 上次持仓张数
- `{sym}_prev_upl_pct`: 浮点数 or None, 上次浮盈百分比
**重要**: **首次 cron 跑** 这些 key 不存在, 不会触发变化 (因为没"上次"可比)。**这是有意为之** — 不让首次运行就推"持仓从无 → 1.45 张"的噪音。
## 🚨 Pitfall
### 1. 浮盈方向
**计算**:`(price - avg_px) / avg_px * 100 * leverage * pos_sign`
`pos_sign` 是关键 — **空头**是 `pos_qty < 0`, 价格跌时浮盈大, 所以乘 `-1` 让"价格下跌 = 浮盈增加"。
不乘 `pos_sign` 会把空头的 📈/📉 推反 — 价格跌了你说"📉 浮盈变小"是反的。
### 2. 静默不等于"系统没跑"
- cron 触发 → `monitor()` 跑 → 无变化 → 本地 print `💤 静默: 有持仓但无变化` + **不推 QQ**
- 系统正常, 只是没新事件
监控 cron 故障排查: 看本地 print 日志 (cron 输出文件 `~/.hermes/cron/output/db03f9255ad0/`)
### 3. 首次 cron 的"假静默"
- 第 1 次跑: 没有 `prev_pos` 基准 → 全是"无变化" → 静默
- 第 2 次跑起: 才有真正的变化检测
**这是有意为之**, 不是 bug。
## 🧪 验证测试
第一次部署改这版后, 建议:
1. 手动 `python3 ~/.hermes/scripts/crypto/okx_t_monitor.py` 看本地输出
2. 确认 cron 跑 5 次 (约 75 分钟) 后**没推 QQ** (静默)
3. 触发一次手动市价调整 (App 改 1 张), 看下次 cron 跑是否推"持仓变化"
## 🔄 v2.1 升级步骤
如果你 fork 改了 v2.0 想升 v2.1:
1.`push_qq(msg)` helper (提取 subprocess 调用)
2.`find_nearest_level()` 函数
3.`check_changes()` 函数
4. 重构 `monitor()` 分两阶段:
- Phase 1: 收集 `syms_to_check`, 跑变化检测, 推 QQ
- Phase 2: 只对有持仓币种做 T
5. 静默分支合并到最后
参考 `crypto/okx_t_monitor.py` 的 v2.1 实现。