Files
Hermes-Skills/okx-auto-position/references/v4.5.79-2026-09-09-trader-name-variants-and-signal-target-parsing.md

196 lines
6.8 KiB
Markdown

# v4.5.79 (2026-09-09) Trader 变体陷阱 + 信号目标值解析 + Ghost Close 系统性观察
## 🎯 核心教训:Trader 名称必须**严格完整匹配**,不能前缀/包含
### 实战现场
9 月 9 日,4 个 trader 名字极其相似但完全不同:
- `熬鹰资本` ← **白名单内,跟单**
- `熬鹰FOMO合约实盘` ← 白名单外,被闸拦
- `熬鹰交易信号` ← 白名单外,被闸拦
- `熬鹰币安实盘` ← 白名单外,被闸拦
### 风险
如果白名单检查用了 `trader.startswith('熬鹰')` 这种前缀匹配,4 个 trader 全都会通过闸,造成**全部熬鹰变体的信号都跟着做**,持仓混乱+误平。
### 铁律
- ✅ trader 白名单用**集合 + 完整字符串等值比较**: `trader in _TRADER_WHITELIST`
- ✅ 白名单配置只放**精确 trader 名** (`whitelist.json::trader_whitelist`)
- ❌ 禁止 `startswith / endswith / contains` 这类模糊匹配
- ❌ 禁止在 trader 名字上做"标准化"(`熬鹰资本abc` → `熬鹰资本`),会有"abc" trader 跟着白名单走的风险
### 检测方法
```python
# 错: 模糊匹配
if '熬鹰' in trader:
follow(trader)
# 对: 集合精确匹配
if trader in {'熬鹰资本'}:
follow(trader)
```
---
## 🎯 核心教训:从信号文本提取"目标值"时,必须按"→后值",不能凭印象
### 实战现场
9 月 9 日 SKHYNIX 调杠杆信号原文:
> 🔧 注意,大佬修改了杠杆 3→5
> 币种: SKHYNIXUSDT|永续|5x
我手动调杠杆时,**凭印象写了 "ETH → 4x" 而不是读信号里的 "5x"**——这是 agent echo 错的目标值,不是 trader 报错。
### 风险
跟错节奏:熬鹰从 3x 调 5x 是加杠杆抗赚/扛亏,跟到 4x 是错向。
### 修复
```python
def adjust_leverage_raw(symbol_usdt, new_leverage):
# new_leverage 直接用 parse_signal 从 "→N" 后面提取
# 不要从"前一个状态"+1 推, 不要从历史值推断
body = {'instId': inst_id, 'lever': str(new_leverage), ...}
```
parse_signal 提取规则:
- 关键词: `修改了杠杆 X→Y` → Y (目标值,**不是 X 也不是 X+1**)
- 关键词: `调整为 X 倍` → X
- 关键词: `降低到 Xx` → X
### 检测方法
推送消息前必须包含杠杆值字段,让 user 可以核对:
```
⚙️ 杠杆已调整 | ETH → 5x
```
如果用户看到"5x"但信号里写"3→4",立刻能发现。
---
## 🎯 核心教训:Ghost Close 在 9 月 9 日 session 中反复出现
### 观察
当日 session 中,以下持仓发生 ghost close(平仓动作没记录到 `signal_history.db::position_history`):
- ZEC short 164 张(系统自动平,response=None,实际成交)
- SKHYNIX long 0.222 张(close 信号)
- ETH short 1.85 张(从未发过 close 信号,但 1.85→1.85 没变,实际可能也被平过)
- SPCX short 1.65 张
- DOGE long 2.92 张
### Ghost Close 触发原因(本次 session 验证)
1. **proxy 抽风** + null guard 缺失 → `close_result['action']` TypeError
2. **close_position_raw 调用 OKX API 成功但 position_history 没 record** (process_signal 没走到 record_signal 分支)
3. **同一信号反复触发**(msg_hash 不变但价格已变,平仓价格 ≠ signal 报价)
4. **trader 反向 close**(白名单闸修复前的兜底 close,实际平错仓位)
### 检测方法
每次 close 后必须:
```python
# 1. process_signal 内部 record
record_signal(dedup_conn, text, symbol, trader)
# 2. position_history 必须 record
_tracker_record(trader=trader, symbol=symbol, ..., outcome='auto_executed_close')
```
### 强制验证(2026-09-09 新增)
`check_account.py` 输出后,主动对比 `position_history`:
- 期望 close 后,最新一条 confirmed_signals 应该包含 `action=auto_executed_close`
- 如果 `has_position=false` 但 `position_history` 没有 close 记录 → ghost close,补 log
---
## 🎯 核心教训:modify-and-commit 铁律 v4.5.71 加强版
### 现状
之前已经有"改完即提交"铁律,但本次 session 又出现:
1. 改 whitelist.json 配置 → 不需要 commit, 是 config
2. 改 process_signal.py 加白名单闸 close → **没 commit**
3. 改 format_message / format_execution_result 文案 → **没 commit**
### 规则
- ✅ **任何代码改动**(process_signal.py / signal_tracker.py / okx_position_advisor.py) → `git add + commit + push` 立即执行
- ✅ **配置文件改动**(whitelist.json) → 不需要 commit,但要立即生效验证
- ✅ **文档改动**(SKILL.md / references/*.md) → 立即 commit
- ❌ **禁止"等一会儿一起 commit"** → 改完一段就 commit 一段
### 检测方法
```bash
git status --short # 每次改完代码立刻检查
```
如果出现 uncommitted 改动超过 5 分钟,推送 silent reminder 给 user。
---
## 🎯 核心教训:"回滚" 操作的歧义
### 现状
User 原话: "把性价比去掉"
Agent 解读 1(对): 删除 `is_low_rating` 判断逻辑
Agent 解读 2(错): "回滚之前的所有改动"——这会撤销刚刚加的白名单闸
### 规则
- ✅ **"去掉 X"** → 删除 X 相关的判断/输出/字段
- ❌ **禁止把"去掉 X" 解读为 "回滚到加 X 之前的状态"**
- ❌ **禁止在 user 没明确说 "回滚" 时,自己扩大解读范围**
### 检测方法
收到"去掉/移除/删除"指令,只针对**指定元素**操作,其它代码保持不动。
---
## 🎯 实战案例
### Case 1: 熬鹰 ETH 调杠杆 3→5,我手动调成 4x
- 现象: 信号原文 `3→5`, 我 echo 成 `4x`
- 原因: agent 自己"补全"了杠杆值, 不是从信号读
- 修复: parse_signal 直接读 `→N`, 不要从历史推断
### Case 2: 4 个熬鹰变体 trader
- 现象: 熬鹰资本(白名单) / 熬鹰FOMO / 熬鹰交易信号 / 熬鹰币安实盘
- 原因: 4 个 trader 在 TG 上都用"熬鹰"打头, 但实际是不同的 trader
- 修复: 严格字符串等值匹配, 不用 startswith
### Case 3: USDT 可用 $0 满仓,系统继续跟加仓信号
- 现象: advisor 报 0.324 张 SKHYNIX long, 实际 USDC $0 应该无法开仓
- 原因: advisor 没检查可用余额, 或 advisor 走的 ccxt fetch_balance 和 check_account 走的 raw REST 路径不一致
- 修复(待办): advisor 开仓前检查 USDT 可用, `if avail < required_margin: skip`
### Case 4: 推送消息里残留"性价比"字样
- 现象: process_signal 返回 `✅ 已推送 | X | Y张 | 性价比: 高`
- 原因: format_message 和 process_signal return 都有"性价比"字眼, agent 只删了一处
- 修复(本次): format_message "📐 建议参数" + process_signal return "评级:X"
- 验证: grep "性价比" 全文件, 应该只有注释
---
## 🎯 铁律汇总 (本节新增)
1. **trader 严格完整字符串等值匹配**, 禁止前缀/包含匹配
2. **杠杆目标值直接从 "→N" 后取**, 不要凭印象/历史推断
3. **close 后必须 record position_history**, 否则 ghost close
4. **改动立即 commit**, 不堆积
5. **"去掉 X" 只动 X**, 不扩大解读范围
6. **advisor 开仓前必须检查 USDT 可用**, 不然会"理论可开"但实际失败