fix复盘真盈亏按权利金USDT波动公式计算,忽略现货多买。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -429,7 +429,8 @@ def sync_options_from_local_trades(
|
||||
) -> dict[str, Any]:
|
||||
"""从本地 options_trades 已平仓记录导入复盘快照(不访问交易所).
|
||||
|
||||
真盈亏=卖光收回−买币(after−before / 已关桥);禁止权利金×指数冒充.
|
||||
真盈亏=历史币盈亏×卖回价 − (权利金×开仓价 − 权利金×卖回价);
|
||||
计入权利金 USDT 波动,忽略现货多买.
|
||||
"""
|
||||
init_options_review_tables(conn)
|
||||
from lib.options.options_db import init_options_tables
|
||||
@@ -555,13 +556,8 @@ def sync_options_from_local_trades(
|
||||
if not ccy:
|
||||
ccy = premium_ccy_for_mode(margin_mode_from_inst_id(inst), underly)
|
||||
frozen_usdt = _safe_float(r["realized_pnl_usdt"])
|
||||
try:
|
||||
settled = int(r["pnl_settled"] or 0) == 1
|
||||
except Exception:
|
||||
settled = False
|
||||
close_idx = _safe_float(r["close_index_px"])
|
||||
open_idx = _safe_float(r["open_index_px"])
|
||||
# 折算指数:仅用于初始权利金/期权手续费展示,不用于真盈亏
|
||||
idx = None
|
||||
if close_idx is not None and close_idx > 0:
|
||||
idx = close_idx
|
||||
@@ -570,26 +566,36 @@ def sync_options_from_local_trades(
|
||||
else:
|
||||
idx = idx_cache.get(underly)
|
||||
prem = _safe_float(r["premium_paid"])
|
||||
# 真盈亏=卖光收回−买币(账户 after−before 或已关桥);禁止权利金×指数冒充
|
||||
from lib.options.options_account_pnl_lib import resolve_true_pnl_usdt
|
||||
|
||||
pnl_u, pnl_src = resolve_true_pnl_usdt(
|
||||
# 仅期权开/平手续费折 U(不含现货);先解析再算真盈亏
|
||||
ofee = abs(_safe_float(r["open_fee"]) or 0.0)
|
||||
cfee = abs(_safe_float(r["close_fee"]) or 0.0)
|
||||
ofee, cfee = _resolve_option_fees_coin(
|
||||
conn,
|
||||
trading_usdt_before=r["trading_usdt_before"],
|
||||
trading_usdt_after=r["trading_usdt_after"],
|
||||
bridge_id=r["bridge_id"],
|
||||
realized_pnl_usdt=frozen_usdt,
|
||||
pnl_settled=settled,
|
||||
r,
|
||||
open_fee=ofee,
|
||||
close_fee=cfee,
|
||||
premium_ccy=ccy,
|
||||
)
|
||||
open_idx_for_prem = open_idx if (open_idx is not None and open_idx > 0) else idx
|
||||
sell_idx = close_idx if (close_idx is not None and close_idx > 0) else idx
|
||||
# 真盈亏=币盈亏×卖回价 − (权利金×开仓价 − 权利金×卖回价);忽略现货多买
|
||||
from lib.options.options_pnl_settle_lib import resolve_true_pnl_usdt_from_trade
|
||||
|
||||
pnl_u, pnl_src = resolve_true_pnl_usdt_from_trade(
|
||||
premium_paid=prem,
|
||||
premium_received=r["premium_received"],
|
||||
realized_pnl=r["realized_pnl"],
|
||||
open_index_px=open_idx_for_prem,
|
||||
close_index_px=sell_idx,
|
||||
open_fee=ofee,
|
||||
close_fee=cfee,
|
||||
premium_ccy=ccy,
|
||||
fee_ccy=str(r["premium_ccy"] or ccy or ""),
|
||||
)
|
||||
# 快照能算真盈亏但冻结值偏离:纠偏写回(仅纠正错账,不改口径)
|
||||
before_f = _safe_float(r["trading_usdt_before"])
|
||||
after_f = _safe_float(r["trading_usdt_after"])
|
||||
if (
|
||||
pnl_src == "account"
|
||||
and pnl_u is not None
|
||||
and before_f is not None
|
||||
and after_f is not None
|
||||
and (not settled or frozen_usdt is None or abs(float(frozen_usdt) - float(pnl_u)) > 0.05)
|
||||
pnl_u is not None
|
||||
and pnl_src != "none"
|
||||
and (frozen_usdt is None or abs(float(frozen_usdt) - float(pnl_u)) > 0.05)
|
||||
):
|
||||
try:
|
||||
conn.execute(
|
||||
@@ -600,49 +606,15 @@ def sync_options_from_local_trades(
|
||||
""",
|
||||
(pnl_u, trade_id),
|
||||
)
|
||||
settled = True
|
||||
except Exception:
|
||||
pass
|
||||
elif pnl_src == "bridge" and pnl_u is not None and not settled:
|
||||
try:
|
||||
after_heal = (
|
||||
round(float(before_f) + float(pnl_u), 8) if before_f is not None else None
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
UPDATE options_trades
|
||||
SET realized_pnl_usdt = ?,
|
||||
trading_usdt_after = COALESCE(trading_usdt_after, ?),
|
||||
pnl_settled = 1
|
||||
WHERE id = ? AND COALESCE(pnl_settled, 0)=0
|
||||
""",
|
||||
(pnl_u, after_heal, trade_id),
|
||||
)
|
||||
settled = True
|
||||
except Exception:
|
||||
pass
|
||||
acct_pending = pnl_u is None and (
|
||||
before_f is not None or r["bridge_id"] is not None
|
||||
)
|
||||
# 初始权利金(U)=开仓指数×权利金币量;不含多买
|
||||
stored_initial = _safe_float(r["initial_premium_usdt"])
|
||||
open_idx_for_prem = open_idx if (open_idx is not None and open_idx > 0) else idx
|
||||
prem_u = stored_initial
|
||||
if prem_u is None:
|
||||
prem_u = _to_usdt(prem, ccy=ccy, idx=open_idx_for_prem)
|
||||
if ccy in ("ETH", "BTC") and prem_u is None:
|
||||
prem_u = prem
|
||||
# 仅期权开/平手续费折 U(不含现货)
|
||||
ofee = abs(_safe_float(r["open_fee"]) or 0.0)
|
||||
cfee = abs(_safe_float(r["close_fee"]) or 0.0)
|
||||
# 模拟盘旧单曾按「权利金×费率」计费偏小:按 OKX 公式/订单回填
|
||||
ofee, cfee = _resolve_option_fees_coin(
|
||||
conn,
|
||||
r,
|
||||
open_fee=ofee,
|
||||
close_fee=cfee,
|
||||
premium_ccy=ccy,
|
||||
)
|
||||
fee_u = None
|
||||
if ccy in ("ETH", "BTC"):
|
||||
fee_parts = 0.0
|
||||
@@ -650,7 +622,6 @@ def sync_options_from_local_trades(
|
||||
if ofee > 0 and open_idx_for_prem is not None and open_idx_for_prem > 0:
|
||||
fee_parts += ofee * float(open_idx_for_prem)
|
||||
has_fee = True
|
||||
sell_idx = close_idx if (close_idx is not None and close_idx > 0) else idx
|
||||
if cfee > 0 and sell_idx is not None and sell_idx > 0:
|
||||
fee_parts += cfee * float(sell_idx)
|
||||
has_fee = True
|
||||
@@ -683,7 +654,7 @@ def sync_options_from_local_trades(
|
||||
"option_fee_usdt": fee_u,
|
||||
"created_at": opened_at,
|
||||
"closed_at": closed_at,
|
||||
"status_label": "待结算" if acct_pending else "已平",
|
||||
"status_label": "已平",
|
||||
},
|
||||
)
|
||||
if action == "inserted":
|
||||
|
||||
Reference in New Issue
Block a user