1
This commit is contained in:
parent
d97363e3d4
commit
dab0981935
|
|
@ -2245,8 +2245,64 @@ class PositionManager:
|
||||||
|
|
||||||
# 尝试从币安历史订单获取实际平仓价格
|
# 尝试从币安历史订单获取实际平仓价格
|
||||||
exit_price = None
|
exit_price = None
|
||||||
|
realized_pnl = None
|
||||||
|
commission = None
|
||||||
close_orders = []
|
close_orders = []
|
||||||
try:
|
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的订单)
|
# 获取最近的平仓订单(reduceOnly=True的订单)
|
||||||
import time
|
import time
|
||||||
end_time = int(time.time() * 1000) # 当前时间(毫秒)
|
end_time = int(time.time() * 1000) # 当前时间(毫秒)
|
||||||
|
|
@ -2412,12 +2468,24 @@ class PositionManager:
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if trade.get('side') == 'BUY':
|
# 如果已经获取到精确的 Realized PnL,直接使用
|
||||||
pnl = (exit_price - entry_price) * quantity
|
if realized_pnl is not None:
|
||||||
pnl_percent = ((exit_price - entry_price) / entry_price) * 100
|
pnl = realized_pnl
|
||||||
else: # SELL
|
# 根据 Realized PnL 反推百分比 (PnL / 保证金) 或者 (PnL / 名义价值)?
|
||||||
pnl = (entry_price - exit_price) * quantity
|
# 这里保持与价格差计算一致的逻辑:(PriceDiff / EntryPrice) * 100
|
||||||
pnl_percent = ((entry_price - exit_price) / entry_price) * 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
|
||||||
|
else: # SELL
|
||||||
|
pnl = (entry_price - exit_price) * quantity
|
||||||
|
pnl_percent = ((entry_price - exit_price) / entry_price) * 100
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"{symbol} [状态同步] 盈亏计算: "
|
f"{symbol} [状态同步] 盈亏计算: "
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user