This commit is contained in:
薇薇安 2026-02-14 09:31:44 +08:00
parent d97363e3d4
commit dab0981935

View File

@ -2245,8 +2245,64 @@ class PositionManager:
# 尝试从币安历史订单获取实际平仓价格
exit_price = None
realized_pnl = None
commission = None
close_orders = []
try:
# 优先尝试从成交记录(Trade History)获取精确的 Realized PnL
# 这是最准确的方式,因为它包含了资金费率、手续费扣除后的实际盈亏
try:
recent_trades = await self.client.get_recent_trades(symbol, limit=50)
# 确定过滤时间戳
entry_ts_ms_filter = 0
et_obj = trade.get('entry_time')
if hasattr(et_obj, 'timestamp'):
entry_ts_ms_filter = int(et_obj.timestamp() * 1000)
elif isinstance(et_obj, (int, float)):
# 区分秒和毫秒
entry_ts_ms_filter = int(et_obj * 1000) if et_obj < 3000000000 else int(et_obj)
elif isinstance(et_obj, str):
try:
from datetime import datetime
dt_obj = datetime.strptime(et_obj, "%Y-%m-%d %H:%M:%S")
entry_ts_ms_filter = int(dt_obj.timestamp() * 1000)
except:
pass
if entry_ts_ms_filter > 0:
# 筛选出入场之后的成交记录
closing_trades = [
t for t in recent_trades
if t.get('time', 0) > entry_ts_ms_filter and float(t.get('realizedPnl', 0)) != 0
]
if closing_trades:
total_pnl = 0.0
total_comm = 0.0
total_qty = 0.0
total_val = 0.0
for t in closing_trades:
total_pnl += float(t.get('realizedPnl', 0))
total_comm += float(t.get('commission', 0))
qty = float(t.get('qty', 0))
price = float(t.get('price', 0))
total_qty += qty
total_val += qty * price
realized_pnl = total_pnl
commission = total_comm
if total_qty > 0:
exit_price = total_val / total_qty
logger.info(
f"{symbol} [状态同步] ✓ 从成交记录获取精确盈亏: "
f"PnL={realized_pnl} USDT, 均价={exit_price:.4f}"
)
except Exception as trade_hist_err:
logger.warning(f"{symbol} [状态同步] 获取成交记录失败: {trade_hist_err}")
# 获取最近的平仓订单reduceOnly=True的订单
import time
end_time = int(time.time() * 1000) # 当前时间(毫秒)
@ -2412,6 +2468,18 @@ class PositionManager:
)
continue
# 如果已经获取到精确的 Realized PnL直接使用
if realized_pnl is not None:
pnl = realized_pnl
# 根据 Realized PnL 反推百分比 (PnL / 保证金) 或者 (PnL / 名义价值)?
# 这里保持与价格差计算一致的逻辑:(PriceDiff / EntryPrice) * 100
# 如果 exit_price 是计算出来的均价,这个公式依然成立
if trade.get('side') == 'BUY':
pnl_percent = ((exit_price - entry_price) / entry_price) * 100
else:
pnl_percent = ((entry_price - exit_price) / entry_price) * 100
else:
# 降级方案:使用价格差计算
if trade.get('side') == 'BUY':
pnl = (exit_price - entry_price) * quantity
pnl_percent = ((exit_price - entry_price) / entry_price) * 100