okx-auto-position: 平仓推送删 unrealizedPnl 字段 (改用 fillPnl/不显示)
**Bug**: 平仓推送显示 unrealizedPnl (浮盈) + 不扣手续费
**实际**: 用户从 OKX app 看真盈亏 (-1.9 vs 推送 +2.96 不一致)
**Fix**:
1. okx_position_advisor.py close_position() 用 fillPnl (OKX 真成交字段) 替换 unrealizedPnl
2. format_close_result() 删 '盈亏: X USDT' 字段
3. format_close_message() 删 '浮盈' 字段
4. 平仓推送加 '💡 实际盈亏请到 OKX app 查看 (扣手续费 + funding)' 提示
**保留**:
- format_execution_result() 开仓前预测盈利额 (TP/SL 推算的合理预估)
- record_confirmed 表的 pnl 字段 (历史归档)
预期: 用户平仓时推送不带误导性'X USDT 浮盈', 改从 OKX app 自己看真盈亏
This commit is contained in:
@@ -692,12 +692,21 @@ def close_position(exchange, symbol, inst_id):
|
||||
import time
|
||||
time.sleep(2)
|
||||
|
||||
# 5. Get close price from trades
|
||||
# 5. Get REAL close PnL from fills (扣手续费后的已实现盈亏)
|
||||
# fetch_my_trades 返回字段: price/fee/cost/info/fillPnl (OKX 真实成交)
|
||||
try:
|
||||
fills = exchange.fetch_my_trades(symbol, limit=1)
|
||||
close_price = float(fills[0]['price']) if fills else 0
|
||||
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
|
||||
except Exception:
|
||||
close_price = 0
|
||||
real_pnl = 0
|
||||
|
||||
results['closed'] = {
|
||||
'symbol': symbol.split('/')[0] + '/USDT',
|
||||
@@ -705,7 +714,7 @@ def close_position(exchange, symbol, inst_id):
|
||||
'contracts': contracts,
|
||||
'entry': entry,
|
||||
'close_price': close_price,
|
||||
'pnl': pnl,
|
||||
'pnl': real_pnl, # 用 fillPnl (真盈亏) 不用 unrealizedPnl (浮盈)
|
||||
}
|
||||
|
||||
return results
|
||||
@@ -726,7 +735,8 @@ def format_close_result(results):
|
||||
|
||||
c = results.get('closed')
|
||||
if c:
|
||||
pnl_emoji = "🟢" if c['pnl'] >= 0 else "🔴"
|
||||
# 2026-08-05: 不显示盈亏 (unrealizedPnl 不准, fillPnl 需要查询)
|
||||
# 用户从 OKX app 自己看实际盈亏
|
||||
lines.extend([
|
||||
f"",
|
||||
f"📊 **{c['symbol']} 平仓确认:**",
|
||||
@@ -734,8 +744,9 @@ def format_close_result(results):
|
||||
f"• 数量: {c['contracts']}张",
|
||||
f"• 入场价: {c['entry']}",
|
||||
f"• 平仓价: **{c['close_price']}**",
|
||||
f"• {pnl_emoji} 盈亏: **{c['pnl']:.2f} USDT**",
|
||||
f"• 已取消止盈止损",
|
||||
f"",
|
||||
f"💡 实际盈亏请到 OKX app 查看 (扣手续费 + funding)",
|
||||
])
|
||||
|
||||
return '\n'.join(lines)
|
||||
|
||||
@@ -578,17 +578,17 @@ def format_close_message(fields, close_result):
|
||||
|
||||
if action == 'closed':
|
||||
pos = close_result['pos_before']
|
||||
u = pos['upl']
|
||||
u_emoji = '🔥' if u >= 0 else '🔴'
|
||||
u_sign = '+' if u >= 0 else ''
|
||||
# 2026-08-05: 不显示浮盈 (unrealizedPnl 不准, 用户从 OKX app 看真盈亏)
|
||||
return f"""✅ {symbol} {side_cn} {emoji} {leverage}x 已市价全平 | {trader}
|
||||
|
||||
{pos['side']} {pos['pos']}张 | 浮盈 {u_sign}{u:.2f} USDT {u_emoji}"""
|
||||
{pos['side']} {pos['pos']}张
|
||||
💡 实际盈亏请到 OKX app 查看 (扣手续费 + funding)"""
|
||||
elif action == 'skip':
|
||||
pos = close_result['pos_before']
|
||||
return f"""⏭️ {symbol} 平仓信号跳过 | {trader}
|
||||
|
||||
你有反向持仓 {pos['side']} {pos['pos']}张 @ {pos['avgPx']:.2f} (浮盈 {pos['upl']:+.2f})"""
|
||||
你有反向持仓 {pos['side']} {pos['pos']}张 @ {pos['avgPx']:.2f}
|
||||
💡 实际盈亏请到 OKX app 查看 (扣手续费 + funding)"""
|
||||
elif action == 'none':
|
||||
return f"""ℹ️ {symbol} {side_cn} 平仓信号 | {trader}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user