实盘数据统计改用期权历史交易所盈亏;模拟盘仍走本地结算。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-08 23:20:16 +08:00
parent d05629c362
commit 7943cd2167
6 changed files with 222 additions and 139 deletions
+12 -57
View File
@@ -188,13 +188,14 @@ def settle_closed_pnl(
) -> dict[str, float | None]:
"""
由「毛权利金」结算.
币数量净盈亏 = 收回 − 已付 − 开/平手续费.
冻结 U(币本位):
平仓收回×平仓指数 − 开仓成本U − 手续费U
开仓成本优先 budget_usdt,否则 已付×开仓指数(缺省才用平仓指数).
这样不会把开仓成本也按平仓价重估,避免和余额对不上.
币数量净盈亏 = 收回 − 已付 − 开/平手续费(只扣一次).
冻结 U(币本位) = 净盈亏 × 平仓指数.
注意:不要用 budget_usdt 当开仓成本——它含现货买入缓冲,多余币会卖回,
拿全额预算当成本会把亏损算大. open_index/budget 参数保留兼容,不参与 U 计算.
不要对 OKX realizedPnl 再调此函数扣费.
"""
del open_index_px, budget_usdt, fee_ccy # 兼容旧调用,不参与结算
paid = float(_safe_float(premium_paid) or 0.0)
recv = float(_safe_float(premium_received) or 0.0)
ofee = float(_safe_float(open_fee) or 0.0)
@@ -204,59 +205,13 @@ def settle_closed_pnl(
if cfee < 0:
cfee = abs(cfee)
net = round(recv - paid - ofee - cfee, 8)
pc = str(premium_ccy or "").strip().upper()
close_idx = _safe_float(index_px)
open_idx = _safe_float(open_index_px)
budget = _safe_float(budget_usdt)
fc = str(fee_ccy or pc or "").strip().upper()
if pc not in ("ETH", "BTC"):
return freeze_pnl_to_usdt(
net,
premium_ccy=premium_ccy,
index_px=close_idx,
total_fee=ofee + cfee,
)
if close_idx is None or close_idx <= 0:
return {
"realized_pnl": net,
"close_index_px": None,
"open_index_px": float(open_idx) if open_idx and open_idx > 0 else None,
"realized_pnl_usdt": None,
"total_fee": round(ofee + cfee, 8),
}
# 开仓成本 U:预算(真实花出去的 USDT) > 已付×开仓指数 > 已付×平仓指数
if budget is not None and budget > 0:
entry_u = float(budget)
if open_idx is None or open_idx <= 0:
open_idx = (entry_u / paid) if paid > 1e-12 else close_idx
elif open_idx is not None and open_idx > 0:
entry_u = paid * float(open_idx)
else:
entry_u = paid * float(close_idx)
open_idx = close_idx
exit_u = recv * float(close_idx)
# 开仓费按开仓指数、平仓费按平仓指数折 U
fee_u = fee_to_usdt(ofee, fc or pc, index_px=open_idx) + fee_to_usdt(
cfee, fc or pc, index_px=close_idx
out = freeze_pnl_to_usdt(
net,
premium_ccy=premium_ccy,
index_px=index_px,
total_fee=ofee + cfee,
)
# 若开仓成本已是 budget(含买币),ETH 开仓费已体现在币变少/卖回变少,不再重复扣 ETH 开仓费
if budget is not None and budget > 0 and (fc or pc) in ("ETH", "BTC"):
fee_u = fee_to_usdt(cfee, fc or pc, index_px=close_idx)
if str(fee_ccy or "").strip().upper() in ("USDT", "USDC", "USD"):
fee_u += fee_to_usdt(ofee, fee_ccy, index_px=open_idx)
usdt = round(exit_u - entry_u - fee_u, 4)
return {
"realized_pnl": net,
"close_index_px": float(close_idx),
"open_index_px": float(open_idx) if open_idx and open_idx > 0 else None,
"realized_pnl_usdt": usdt,
"total_fee": round(ofee + cfee, 8),
}
return out
def settle_exchange_realized_pnl(