修复币本位期权浮盈二次折算:中控汇总与实例统计把已折 U 的数再乘指数。

约 -6.5U 被当成 ETH 再 ×2700 显示成 -1.7万U;汇总框直接按 U 展示,stats 不再对 open_float 二次换算。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-09-30 22:30:24 +08:00
parent 32746b0a34
commit d2d431e4c9
2 changed files with 34 additions and 24 deletions
+29 -11
View File
@@ -817,7 +817,19 @@
return `${sign}${fmt(n, 2)}U`;
}
/** 中控期权浮盈汇总框:只显示换算后的 U(持仓表净盈亏仍用 fmtOptPnlText 双显). */
/** 已是 USDT 的期权浮盈合计(upl_total_usdc),禁止再按币×指数. */
function fmtOptFloatUsdt(v) {
if (v === null || v === undefined || Number.isNaN(Number(v))) return "—";
const n = Number(v);
const uAbs = Math.abs(n).toFixed(2);
const uSign = n < 0 ? "-" : n > 0 ? "+" : "";
return `${uSign}${uAbs}U`;
}
/**
* 币数量 → U(仅逐仓净盈亏双显/兜底合计用).
* 汇总框勿用:后端 upl_total 已折 U,再乘会变成上万假亏.
*/
function fmtOptPnlUsdtOnly(v, ccy, spotPx) {
if (v === null || v === undefined || Number.isNaN(Number(v))) return "—";
const n = Number(v);
@@ -3939,6 +3951,7 @@
const bal =
opt.balances && typeof opt.balances === "object" ? opt.balances : {};
const pick = (a, b) => (a != null && a !== "" ? a : b);
// upl_total_usdc 实际为已折 USDT 的合计(币本位 × 指数后)
let upl =
opt.upl_total_usdc != null && Number.isFinite(Number(opt.upl_total_usdc))
? Number(opt.upl_total_usdc)
@@ -3949,10 +3962,16 @@
let found = false;
pos.forEach((p) => {
const n = optionsRowDisplayPnl(p);
if (n != null) {
sum += n;
found = true;
if (n == null || !Number.isFinite(Number(n))) return;
const ccy = String(optPremiumCcyOf(p) || "").toUpperCase();
let uu = Number(n);
if (ccy === "ETH" || ccy === "BTC") {
const px = spotPxFromOptMeta(opt, p);
if (!Number.isFinite(px) || !(px > 0)) return;
uu = Number(n) * px;
}
sum += uu;
found = true;
});
if (found) upl = sum;
}
@@ -3987,11 +4006,10 @@
? `${fmt(fundUsdt, 2)} <small style="font-size:12px;color:var(--muted)">U</small>`
: "—";
const tradeTxt = formatCoinTradingLabel(usdt, eth, btc);
const pnlCcy = optionsPanelCcy(optMeta);
const spotPx = spotPxFromOptMeta(optMeta);
// 汇总 upnl 已是 USDT,勿再按 ETH/BTC×指数(否则 -6U 会变成 -1.7万U)
const pnlTxt = upnl == null || Number.isNaN(Number(upnl))
? "—"
: `<span class="${pnlCls(upnl)}">${fmtOptPnlUsdtOnly(upnl, pnlCcy, spotPx)}</span>`;
: `<span class="${pnlCls(upnl)}">${fmtOptFloatUsdt(upnl)}</span>`;
return `<div class="${rowCls}">
<div class="stat-box"><div class="stat-label">资金账户</div><div class="stat-value">${fundTxt}</div></div>
<div class="stat-box"><div class="stat-label">交易账户</div><div class="stat-value">${tradeTxt}</div></div>
@@ -4671,14 +4689,14 @@
parts.push(`交易 ${fmt(bal.trading, 2)}U`);
}
if (optUpl != null && Number.isFinite(Number(optUpl))) {
parts.push(`浮盈 ${fmtOptPnlUsdtOnly(optUpl, optCcy, spotPxFromOptMeta(opt))}`);
parts.push(`浮盈 ${fmtOptFloatUsdt(optUpl)}`);
}
if (optUpl != null && Number.isFinite(Number(optUpl)) && openCount === 0) {
// 永续空仓时主数字优先展示期权浮盈(只显示 U)
// 永续空仓时主数字优先展示期权浮盈(已是 U,勿再按币折算)
pnlShow = optUpl;
pnlSuffix = "期权";
pnlUnit = optCcy;
pnlSpotPx = spotPxFromOptMeta(opt);
pnlUnit = "USDC";
pnlSpotPx = null;
}
}
optLine = parts.join(" · ");