6.8 KiB
6.8 KiB
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 跟着白名单走的风险
检测方法
# 错: 模糊匹配
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 是错向。
修复
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 验证)
- proxy 抽风 + null guard 缺失 →
close_result['action']TypeError - close_position_raw 调用 OKX API 成功但 position_history 没 record (process_signal 没走到 record_signal 分支)
- 同一信号反复触发(msg_hash 不变但价格已变,平仓价格 ≠ signal 报价)
- trader 反向 close(白名单闸修复前的兜底 close,实际平错仓位)
检测方法
每次 close 后必须:
# 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 又出现:
- 改 whitelist.json 配置 → 不需要 commit, 是 config
- 改 process_signal.py 加白名单闸 close → 没 commit
- 改 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 一段
检测方法
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 "性价比" 全文件, 应该只有注释
🎯 铁律汇总 (本节新增)
- trader 严格完整字符串等值匹配, 禁止前缀/包含匹配
- 杠杆目标值直接从 "→N" 后取, 不要凭印象/历史推断
- close 后必须 record position_history, 否则 ghost close
- 改动立即 commit, 不堆积
- "去掉 X" 只动 X, 不扩大解读范围
- advisor 开仓前必须检查 USDT 可用, 不然会"理论可开"但实际失败