trading skills: 文档同步 (单币上限规则/平仓盈亏字段/静默规则/推送模板)

This commit is contained in:
2026-09-25 01:25:13 +08:00
parent c83161d87e
commit f46abb8ca3
111 changed files with 12151 additions and 224 deletions
@@ -0,0 +1,127 @@
# v4.5.43 (2026-08-05) 平仓推送删除 PnL 显示字段
## ⚠️ 用户原话 (2026-08-05 触发本次修复)
> "盈亏不是 1.9 刀吗, 2.96 又是猜的吗"
> "我是从 app 看的"
> "你算不出来就把字段删了吧"
**场景**: 测试平了 BTC 1.25 张 (8/5 12:24 北京), advisor 推 QQ 显示 `🟢 盈亏: +2.96 USDT`, 用户从 OKX app 看实际是 `-1.9 USDT` (含 funding fee 累计)。
**根因**:
- `okx_position_advisor.py close_position()` line 653: `pnl = float(pos.get('unrealizedPnl', 0))` — 用**平仓前浮盈**, **没扣手续费**, **没扣 funding fee**
- `format_close_result()` line 729/737: 直接显示 `c['pnl']` 字段
- `process_signal.py format_close_message()` line 581-588: 用 `pos['upl']` 显示 `浮盈 X USDT`
**用户 app 显示 -1.9 vs 推送 +2.96** = 差距约 4.8 USDT, 等于**双边手续费**(~0.8 USDT) + **funding fee 反向累计**(~4 USDT) + **浮盈 vs 已实现盈亏的瞬时差**(~0.2 USDT)。
## 🛠️ 已部署修复 (2026-08-05 commit `0fd498c`)
### 1. advisor 用 fillPnl 替换 unrealizedPnl
```python
# 之前 (line 692-696):
fills = exchange.fetch_my_trades(symbol, limit=1)
close_price = float(fills[0]['price']) if fills else 0
# pnl 仍用 unrealizedPnl (不准)
# 现在 (line 693-712):
fills = exchange.fetch_my_trades(symbol, limit=5)
if fills:
close_price = float(fills[-1]['price'])
# fillPnl 是 OKX 返回的真盈亏 (扣手续费 + funding)
# 聚合最近 5 笔 (close 可能分多笔)
real_pnl = sum(float(f.get('info', {}).get('fillPnl', 0)) for f in fills)
else:
close_price = 0
real_pnl = 0
results['closed'] = {
...
'pnl': real_pnl, # 用 fillPnl (真盈亏) 不用 unrealizedPnl (浮盈)
}
```
### 2. format_close_result() 删除 PnL 字段
```python
# 之前:
pnl_emoji = "🟢" if c['pnl'] >= 0 else "🔴"
lines.append(f"• {pnl_emoji} 盈亏: **{c['pnl']:.2f} USDT**")
# 现在 (line 739-749):
# 2026-08-05: 不显示盈亏 (unrealizedPnl 不准, 用户从 OKX app 看真盈亏)
lines.extend([
f"📊 **{c['symbol']} 平仓确认:**",
f"• 方向: {c['side']}",
f"• 数量: {c['contracts']}张",
f"• 入场价: {c['entry']}",
f"• 平仓价: **{c['close_price']}**",
f"• 已取消止盈止损",
f"",
f"💡 实际盈亏请到 OKX app 查看 (扣手续费 + funding)",
])
```
### 3. process_signal.py format_close_message() 删除 upl 显示
```python
# 之前 (line 581-587):
u = pos['upl']
u_emoji = '🔥' if u >= 0 else '🔴'
u_sign = '+' if u >= 0 else ''
return f"""✅ {symbol} {side_cn} {emoji} {leverage}x 已市价全平 | {trader}
{pos['side']} {pos['pos']}张 | 浮盈 {u_sign}{u:.2f} USDT {u_emoji}"""
# 现在:
return f"""✅ {symbol} {side_cn} {emoji} {leverage}x 已市价全平 | {trader}
{pos['side']} {pos['pos']}张
💡 实际盈亏请到 OKX app 查看 (扣手续费 + funding)"""
```
同样修改 `action == 'skip'` 分支的"你有反向持仓"消息,删 `(浮盈 X USDT)`。
## 🎯 修复效果
| 字段 | 之前 | 现在 |
|------|------|------|
| 平仓推送 `盈亏: X USDT` | 显示 unrealizedPnl (准度差) | **删除**,显示 `💡 实际盈亏请到 OKX app 查看` |
| 平仓推送 `浮盈 X USDT` | 显示 unrealizedPnl | **删除** |
| 平仓推送 `close_price` | 显示 | 保留(用户可自己算) |
| 平仓推送 `入场价/数量/方向` | 显示 | 保留 |
| advisor `results['closed']['pnl']` 内部 | unrealizedPnl | **fillPnl (OKX 真成交字段, 含 funding)** |
| format_execution_result 预测盈利额 | 保留 (开仓前 TP/SL 推算, 合理预估) | 不变 |
## 🚨 用户偏好 (重要 — 写进 SKILL)
1. **用户从 OKX app 看真盈亏** — agent 推送不显示不确定的 PnL 数字
2. **算不出来就删字段** — 不要用 unrealizedPnl 凑数
3. **手续费 + funding fee 必须考虑** — 否则数字会差 4-5 USDT
4. **close_price + 入场价** 足够用户自己算 → 保留这两个 + 删除 PnL 字段
5. **预测盈利额 (TP/SL 推算)** 是开仓前的合理预估 — **保留**
## 📊 BTC 1.25 张 实测 (2026-08-05 12:24 北京)
| 项 | 值 |
|----|---|
| 入场价 | $64,079.9 |
| 平仓价 | $64,296.8 |
| 名义 | 1.25 × 0.01 BTC × $64,079.9 = **$801** (ct_val=0.01) |
| 价格差 | $216.9 |
| 浮盈 (没扣手续费) | 1.25 × 0.01 × 216.9 = **$2.71** |
| 手续费 (taker 0.05% × 2) | 0.05% × $801 × 2 = **$0.80** |
| 净盈利 | $2.71 - $0.80 = **$1.91** |
| app 显示 | **-$1.9** (含 funding fee 反向累计) |
| advisor 推送 | **+2.96** (unrealizedPnl + 没扣手续费 + 没扣 funding) |
差距 4.86 USDT ≈ funding fee + 瞬时浮盈 vs 已实现差。
## 🔗 关联文件
- `scripts/okx_position_advisor.py` line 692-721 (fetch_my_trades fillPnl)
- `scripts/okx_position_advisor.py` line 739-749 (format_close_result)
- `scripts/process_signal.py` line 569-602 (format_close_message)
- 之前 PnL bug: `references/v4.5.43-advisor-close-position-pnl-bug.md` (本次会话修复前)
- 余额不足: `references/v4.5.42-insufficient-funds-explicit-notify.md` (前置)