币本位实时盈亏/期权浮盈按ETH展示,避免两位小数抹成0.00U
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -746,6 +746,53 @@
|
||||
return Number(n).toLocaleString(undefined, { maximumFractionDigits: d });
|
||||
}
|
||||
|
||||
/** 币本位权利金/盈亏:ETH/BTC 保留足量小数;USDC 两位. */
|
||||
function optPremiumCcyOf(p, fallbackUnderly) {
|
||||
const ccy = String((p && p.premium_ccy) || "").trim().toUpperCase();
|
||||
if (ccy) return ccy;
|
||||
const mode = String((p && p.margin_mode) || "").toLowerCase();
|
||||
const inst = String((p && p.inst_id) || "");
|
||||
if (mode === "coin" || (inst.indexOf("-USD-") >= 0 && inst.indexOf("_UM") < 0)) {
|
||||
return (inst.split("-")[0] || fallbackUnderly || "ETH").toUpperCase() || "ETH";
|
||||
}
|
||||
return "USDC";
|
||||
}
|
||||
|
||||
function optionsPanelCcy(optMeta) {
|
||||
if (!optMeta || typeof optMeta !== "object") return "USDC";
|
||||
const mode = String(optMeta.options_margin_mode || optMeta.margin_mode || "").toLowerCase();
|
||||
const underly = String(optMeta.options_underly || "ETH").toUpperCase() || "ETH";
|
||||
if (mode === "coin") return underly;
|
||||
const pos = Array.isArray(optMeta.positions) ? optMeta.positions : [];
|
||||
for (let i = 0; i < pos.length; i++) {
|
||||
const c = optPremiumCcyOf(pos[i], underly);
|
||||
if (c && c !== "USDC") return c;
|
||||
}
|
||||
return "USDC";
|
||||
}
|
||||
|
||||
function fmtOptPnlAmt(v, ccy) {
|
||||
if (v === null || v === undefined || Number.isNaN(Number(v))) return "—";
|
||||
const n = Number(v);
|
||||
const unit = String(ccy || "USDC").toUpperCase();
|
||||
if (unit === "ETH" || unit === "BTC") {
|
||||
const s = n.toFixed(8).replace(/\.?0+$/, "");
|
||||
return s || "0";
|
||||
}
|
||||
return fmt(n, 2);
|
||||
}
|
||||
|
||||
function fmtOptPnlText(v, ccy) {
|
||||
if (v === null || v === undefined || Number.isNaN(Number(v))) return "—";
|
||||
const n = Number(v);
|
||||
const unit = String(ccy || "USDC").toUpperCase();
|
||||
const sign = n > 0 ? "+" : "";
|
||||
if (unit === "ETH" || unit === "BTC") {
|
||||
return `${sign}${fmtOptPnlAmt(n, unit)} ${unit}`;
|
||||
}
|
||||
return `${sign}${fmt(n, 2)}U`;
|
||||
}
|
||||
|
||||
/** 交易所持仓开仓价(三所子代理 entry_price) */
|
||||
function positionEntryPrice(pos) {
|
||||
if (!pos) return null;
|
||||
@@ -3900,10 +3947,14 @@
|
||||
? `${fmt(fundUsdt, 2)} <small style="font-size:12px;color:var(--muted)">U</small>`
|
||||
: "—";
|
||||
const tradeTxt = formatCoinTradingLabel(usdt, eth, btc);
|
||||
const pnlCcy = optionsPanelCcy(optMeta);
|
||||
const pnlTxt = upnl == null || Number.isNaN(Number(upnl))
|
||||
? "—"
|
||||
: `<span class="${pnlCls(upnl)}">${fmtOptPnlText(upnl, pnlCcy)}</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>
|
||||
<div class="stat-box"><div class="stat-label">${pnlLabel}</div><div class="stat-value ${pnlCls(upnl)}">${fmt(upnl, 2)}</div></div>
|
||||
<div class="stat-box"><div class="stat-label">${pnlLabel}</div><div class="stat-value">${pnlTxt}</div></div>
|
||||
</div>`;
|
||||
}
|
||||
let fundTxt = `${fmt(funding, 2)} <small style="font-size:12px;color:var(--muted)">U</small>`;
|
||||
@@ -4064,7 +4115,8 @@
|
||||
<td>${optionsExpiryCdHtml(p.exp_time_ms != null ? p.exp_time_ms : p.exp_time)}</td>
|
||||
${renderOptionsTargetCell(target, p)}`;
|
||||
if (showPnl) {
|
||||
html += `<td class="${pnlCls(net)}">${net == null ? "—" : fmt(net, 2)}</td>
|
||||
const premCcy = optPremiumCcyOf(p);
|
||||
html += `<td class="${pnlCls(net)}">${net == null ? "—" : fmtOptPnlText(net, premCcy)}</td>
|
||||
<td class="${pnlCls(net)}">${roi == null ? "—" : esc(Number(roi).toFixed(2)) + "%"}</td>`;
|
||||
}
|
||||
html += "</tr>";
|
||||
@@ -4549,6 +4601,7 @@
|
||||
let optLine = "";
|
||||
let pnlShow = upnl;
|
||||
let pnlSuffix = "";
|
||||
let pnlUnit = "U";
|
||||
if (hasOptCap) {
|
||||
if (opt.enabled === false) {
|
||||
optLine = "期权未启用";
|
||||
@@ -4561,17 +4614,28 @@
|
||||
const n = Number.isFinite(optCount) ? optCount : 0;
|
||||
const bal = optionsBalanceFields(opt);
|
||||
const optUpl = bal.upl != null ? bal.upl : null;
|
||||
const optCcy = optionsPanelCcy(opt);
|
||||
const parts = [n > 0 ? `期权 ${n}仓` : "期权 空仓"];
|
||||
if (showAccountPnlPref()) {
|
||||
if (bal.funding != null) parts.push(`资金 ${fmt(bal.funding, 2)}U`);
|
||||
if (bal.trading != null) parts.push(`交易 ${fmt(bal.trading, 2)}U`);
|
||||
if (opt.options_margin_mode === "coin") {
|
||||
const coinTrade = formatCoinTradingLabel(
|
||||
bal.trading != null ? bal.trading : opt.trading_usdt,
|
||||
(opt.balances || {}).trading_eth,
|
||||
(opt.balances || {}).trading_btc
|
||||
);
|
||||
if (coinTrade && coinTrade !== "—") parts.push(`交易 ${coinTrade}`);
|
||||
} else if (bal.trading != null) {
|
||||
parts.push(`交易 ${fmt(bal.trading, 2)}U`);
|
||||
}
|
||||
if (optUpl != null && Number.isFinite(Number(optUpl))) {
|
||||
parts.push(`浮盈 ${fmt(optUpl, 2)}U`);
|
||||
parts.push(`浮盈 ${fmtOptPnlText(optUpl, optCcy)}`);
|
||||
}
|
||||
if (optUpl != null && Number.isFinite(Number(optUpl)) && openCount === 0) {
|
||||
// 永续空仓时主数字优先展示期权浮盈,避免一直显示 0U
|
||||
pnlShow = optUpl;
|
||||
pnlSuffix = "期权";
|
||||
pnlUnit = optCcy;
|
||||
}
|
||||
}
|
||||
optLine = parts.join(" · ");
|
||||
@@ -4580,6 +4644,10 @@
|
||||
const hm = row.hub_monitor || {};
|
||||
const flaskOk = row.flask_ok !== false && hm.ok !== false;
|
||||
const strategyStats = renderCardStrategyStats(row, hm, flaskOk);
|
||||
const tilePnlHtml =
|
||||
pnlUnit === "ETH" || pnlUnit === "BTC"
|
||||
? `${fmtOptPnlAmt(pnlShow, pnlUnit)} <small>${esc(pnlUnit)}${pnlSuffix ? " · " + esc(pnlSuffix) : ""}</small>`
|
||||
: `${fmt(pnlShow, 2)} <small>U${pnlSuffix ? " · " + esc(pnlSuffix) : ""}</small>`;
|
||||
return `<div class="card hub-tile ${tileCls}" data-ex-id="${esc(row.id)}">
|
||||
<div class="hub-tile-body card-expand-zone" title="点击进入全屏详情">
|
||||
<div class="hub-tile-top">
|
||||
@@ -4589,9 +4657,7 @@
|
||||
</div>
|
||||
${
|
||||
showAccountPnlPref()
|
||||
? `<div class="hub-tile-pnl ${pnlCls(pnlShow)}">${fmt(pnlShow, 2)} <small>U${
|
||||
pnlSuffix ? " · " + pnlSuffix : ""
|
||||
}</small></div>`
|
||||
? `<div class="hub-tile-pnl ${pnlCls(pnlShow)}">${tilePnlHtml}</div>`
|
||||
: ""
|
||||
}
|
||||
<div class="hub-tile-meta">${esc(posLine)}</div>
|
||||
|
||||
Reference in New Issue
Block a user