124 lines
4.7 KiB
Markdown
124 lines
4.7 KiB
Markdown
# v4.5.35 (2026-07-08) 标题 vs 实际仓位 矛盾的精确判定规则 + 第 N 次实战
|
|
|
|
## 背景
|
|
|
|
信号源(麻吉 / 熬鹰)经常发"加仓"标题,但实际 `size` 字段比上一条减小。本会话麻吉大哥 ETH 多次出现:
|
|
|
|
| 标题 | 仓位变化 | 实际方向 |
|
|
|---|---|---|
|
|
| 📈 加仓 | 6000 → 4500 张 (-25%) | 减仓 |
|
|
| 📈 加仓 | 6360 → 6330 张 (-0.5%) | 减仓(噪声) |
|
|
| 📈 加仓 | 3404 → 6000 张 (+76%) | 真加仓 ✓ |
|
|
| 📈 加仓 | 16482 → 15164 张 (-8%) | 减仓 |
|
|
|
|
`process_signal.py` 字面信标题 → 推错方向的"加仓 X 张"建议。
|
|
|
|
## 精确判定规则 (应入主流程)
|
|
|
|
`classify_signal` 必须不只信标题,要对比**信号本身的 size 字段与上一条 size**:
|
|
|
|
```python
|
|
def classify_signal_robust(fields, prev_size=None):
|
|
"""强制对比 prev_size,不信标题字眼"""
|
|
text = fields.get('_raw', '')
|
|
current_size = float(str(fields.get('size', '0')).replace(',', ''))
|
|
|
|
# 检测"加仓"标题但 size 实际减小 (> 2% 阈值)
|
|
if '加仓' in text and prev_size and prev_size > 0:
|
|
delta = (current_size - prev_size) / prev_size
|
|
if delta < -0.02: # 减小超过 2%
|
|
return 'reduce' # 强制覆盖标题
|
|
|
|
# 检测"减仓"标题但 size 实际增大
|
|
if '减仓' in text and prev_size and prev_size > 0:
|
|
delta = (current_size - prev_size) / prev_size
|
|
if delta > 0.02: # 增大超过 2%
|
|
return 'add' # 强制覆盖标题
|
|
|
|
# 退回到字面分类
|
|
return classify_signal(fields)
|
|
```
|
|
|
|
## 信号源 prev_size 数据流
|
|
|
|
需要 signal_tracker.py 提供"同 trader + 同 symbol 的上一条 size":
|
|
|
|
```python
|
|
def get_prev_size(trader, symbol):
|
|
"""从 signal_tracker 查上一条该 trader 的该 symbol 的 size"""
|
|
# signal_tracker.py 维护 history 表
|
|
# 调用方式:
|
|
# history = signal_tracker.get_history(trader, symbol, limit=1)
|
|
# if history: return float(history[0]['size'])
|
|
# return None
|
|
```
|
|
|
|
## 实战案例
|
|
|
|
### 案例 1: 麻吉大哥 ETH 加仓 vs 减仓矛盾
|
|
|
|
```
|
|
[15:50] 加仓 6000 张 (涨到 1763)
|
|
[15:55] 加仓 4500 张 (-25%,标题错位) ← 应识别为 reduce
|
|
[15:55] 加仓 6330 张 (-0.5%,噪声,标题错位) ← 应识别为 reduce 但 delta < 2%,保守保留 add
|
|
[15:55] 加仓 6000 张 (+76% 回补) ← 真加仓 ✓
|
|
[15:55] 加仓 4500 张 (-25%,标题错位) ← 应识别为 reduce
|
|
```
|
|
|
|
agent 第一次犯这个错时,在回复里写:"标题写加仓但实际减仓,推错的加仓建议 0.32 张"。**之后用户应没看到 agent 主动修正**——意味着 process_signal 的 add/reduce 路径输出仍可能误导用户。
|
|
|
|
### 案例 2: 熬鹰 SKHYNIX 100+ 连发信号(本会话下半段)
|
|
|
|
熬鹰 SKHYNIX 加仓信号从 6.92 张 → 1410 张,**全是加仓**但加仓幅度 < 1% 的大量重复。这种:
|
|
- 不应触发 reduce 强制覆盖(delta > 0)
|
|
- 应触发**信号合并**(v4.5.14 规则:同币种同交易员 + 短间隔 = 合并)
|
|
- 应触发**零字符沉默**(v4.5.21:加仓幅度 < 1% 不需要 agent reply)
|
|
|
|
## 决策矩阵
|
|
|
|
| 标题 | current vs prev_size | 判定 | 处理 |
|
|
|---|---|---|---|
|
|
| 加仓 | delta > +2% | add | 走加仓流程 |
|
|
| 加仓 | delta ∈ [-2%, +2%] | add (噪声) | 信号合并,零字符沉默 |
|
|
| **加仓** | **delta < -2%** | **reduce (强制)** | **走减仓流程,推"减仓 X 张"** |
|
|
| 减仓 | delta < -2% | reduce | 走减仓流程 |
|
|
| 减仓 | delta ∈ [-2%, +2%] | reduce (噪声) | 信号合并,零字符沉默 |
|
|
| **减仓** | **delta > +2%** | **add (强制)** | **走加仓流程,推"加仓 X 张"** |
|
|
|
|
## 必备前置依赖
|
|
|
|
1. **signal_tracker.py 必须维护 history 表**(每条信号记录 trader+symbol+size+timestamp)
|
|
2. **classify_signal_robust 必须在 process_signal.py 主流程替换 classify_signal**
|
|
3. **阈值 2% 可配置**(太小易误判为 reduce,太大错过真正的矛盾)
|
|
|
|
## 暂未落地 (TODO 给下次 session)
|
|
|
|
```bash
|
|
# 1. 检查 signal_tracker 是否已有 history 表
|
|
sqlite3 ~/.hermes/skills/trading/okx-auto-position/data/signals.db \
|
|
".schema"
|
|
|
|
# 2. 如果没有,添加:
|
|
sqlite3 ~/.hermes/skills/trading/okx-auto-position/data/signals.db <<SQL
|
|
CREATE TABLE IF NOT EXISTS signal_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
trader TEXT NOT NULL,
|
|
symbol TEXT NOT NULL,
|
|
side TEXT NOT NULL,
|
|
size REAL NOT NULL,
|
|
price REAL,
|
|
title TEXT,
|
|
ts REAL NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_trader_symbol_ts
|
|
ON signal_history (trader, symbol, ts DESC);
|
|
SQL
|
|
|
|
# 3. 在 process_signal.py 加 classify_signal_robust + get_prev_size
|
|
```
|
|
|
|
## 关联
|
|
|
|
- v4.5.32 第一次记录"标题 vs 仓位矛盾",但只说"未部署"
|
|
- 本 v4.5.35 给出**精确判定规则 + 决策矩阵 + 决策树代码**,下次 session 可直接落地
|
|
- 与 v4.5.4 平仓 dedup 修复(同 session 上半段)配套,都是 process_signal 流程的硬约束 |