fix无法按新真盈亏公式更新的旧单标记为缺价未核。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-13 10:23:36 +08:00
parent 3416996ae5
commit 42a7ee9961
5 changed files with 126 additions and 111 deletions
+13 -3
View File
@@ -451,6 +451,11 @@
var badgeExtra = reviewed
? ' <span class="or-badge" style="background:rgba(61,214,140,.2)">已复盘</span>'
: "";
var needsMark = String(t.status_raw || "") === "缺价未核";
if (needsMark) {
badgeExtra +=
' <span class="or-badge" style="background:rgba(255,170,60,.28)" title="缺开仓价或卖回价,未能按新真盈亏公式更新">缺价未核</span>';
}
return (
'<tr class="or-trade-row' +
active +
@@ -471,7 +476,7 @@
'<td class="' +
pnlClass(t.realized_pnl_total) +
'">' +
fmtPnl(t.realized_pnl_total) +
(needsMark ? '<span class="muted" title="未能按新公式更新">—</span>' : fmtPnl(t.realized_pnl_total)) +
"</td>" +
'<td class="' +
pnlClass(pr) +
@@ -565,13 +570,18 @@
var entry = t.entry || {};
var direction = t.direction_view || entry.direction_view || "";
var entryLogic = t.entry_logic || entry.entry_logic || "";
var needsMarkR = String(t.status_raw || "") === "缺价未核";
return (
'<tr class="or-reviewed-row" data-id="' +
t.id +
'">' +
"<td><span class=\"or-badge\">" +
escapeHtml(t.source_label || t.source_type) +
"</span></td>" +
"</span>" +
(needsMarkR
? ' <span class="or-badge" style="background:rgba(255,170,60,.28)" title="缺开仓价或卖回价,未能按新真盈亏公式更新">缺价未核</span>'
: "") +
"</td>" +
"<td>" +
escapeHtml(tradeContractLabel(t)) +
"</td>" +
@@ -584,7 +594,7 @@
'<td class="' +
pnlClass(t.realized_pnl_total) +
'">' +
fmtPnl(t.realized_pnl_total) +
(needsMarkR ? '<span class="muted" title="未能按新公式更新">—</span>' : fmtPnl(t.realized_pnl_total)) +
"</td>" +
'<td class="' +
pnlClass(resolveProfitRate(t)) +
+28 -11
View File
@@ -576,35 +576,52 @@ def sync_options_from_local_trades(
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
# 真盈亏=币盈亏×卖回价 − (权利金×开仓价 − 权利金×卖回价);忽略现货多买
sell_idx = close_idx if (close_idx is not None and close_idx > 0) else None
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,
open_index_px=open_idx if (open_idx is not None and open_idx > 0) else None,
close_index_px=sell_idx,
open_fee=ofee,
close_fee=cfee,
premium_ccy=ccy,
fee_ccy=str(r["premium_ccy"] or ccy or ""),
)
if (
pnl_u is not None
and pnl_src != "none"
and (frozen_usdt is None or abs(float(frozen_usdt) - float(pnl_u)) > 0.05)
):
# 能算新公式则写回;算不出则清空旧冻结并标记「缺价未核」
status_label = "已平"
if pnl_u is not None and pnl_src != "none":
if frozen_usdt is None or abs(float(frozen_usdt) - float(pnl_u)) > 0.05:
try:
conn.execute(
"""
UPDATE options_trades
SET realized_pnl_usdt = ?, pnl_settled = 1
WHERE id = ?
""",
(pnl_u, trade_id),
)
except Exception:
pass
else:
status_label = "缺价未核"
pnl_u = None
try:
conn.execute(
"""
UPDATE options_trades
SET realized_pnl_usdt = ?, pnl_settled = 1
SET realized_pnl_usdt = NULL, pnl_settled = 0
WHERE id = ?
AND (
COALESCE(pnl_settled, 0) = 1
OR realized_pnl_usdt IS NOT NULL
)
""",
(pnl_u, trade_id),
(trade_id,),
)
except Exception:
pass
@@ -654,7 +671,7 @@ def sync_options_from_local_trades(
"option_fee_usdt": fee_u,
"created_at": opened_at,
"closed_at": closed_at,
"status_label": "已平",
"status_label": status_label,
},
)
if action == "inserted":
@@ -229,7 +229,7 @@
<span class="or-step" aria-hidden="true">1</span>
<div>
<div class="or-section-title" id="or-list-title">期权交易记录</div>
<p class="or-section-desc">真盈亏=历史币盈亏×卖回价 − 权利金×(开仓价−卖回价);计入权利金 USDT 波动,忽略现货多买。期权历史仅记币收益。</p>
<p class="or-section-desc">真盈亏=历史币盈亏×卖回价 − 权利金×(开仓价−卖回价)。缺开仓/卖回价的旧单标记「缺价未核」,不沿用旧冻结。期权历史仅记币收益。</p>
</div>
</div>
<div class="options-strike-table-wrap or-trades-table-wrap" id="or-trades-wrap">