币本位盈亏双显ETH/U(按指数换算);平仓卖币改为卖光交易户可用余额
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -782,13 +782,37 @@
|
||||
return fmt(n, 2);
|
||||
}
|
||||
|
||||
function fmtOptPnlText(v, ccy) {
|
||||
function spotPxFromOptMeta(optMeta, p) {
|
||||
if (p) {
|
||||
const n = Number(p.idx_px != null ? p.idx_px : p.idxPx != null ? p.idxPx : p.index_px);
|
||||
if (Number.isFinite(n) && n > 0) return n;
|
||||
}
|
||||
if (optMeta) {
|
||||
const n = Number(optMeta.options_index_px != null ? optMeta.options_index_px : optMeta.index_px);
|
||||
if (Number.isFinite(n) && n > 0) return n;
|
||||
const pos = Array.isArray(optMeta.positions) ? optMeta.positions : [];
|
||||
for (let i = 0; i < pos.length; i++) {
|
||||
const px = Number(pos[i] && (pos[i].idx_px != null ? pos[i].idx_px : pos[i].idxPx));
|
||||
if (Number.isFinite(px) && px > 0) return px;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function fmtOptPnlText(v, ccy, spotPx) {
|
||||
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}`;
|
||||
const coin = `${sign}${fmtOptPnlAmt(Math.abs(n), unit)}`;
|
||||
const signedCoin = n < 0 ? `-${fmtOptPnlAmt(Math.abs(n), unit)}` : coin;
|
||||
const px = Number(spotPx);
|
||||
if (!Number.isFinite(px) || !(px > 0)) return `${signedCoin} ${unit}`;
|
||||
const u = n * px;
|
||||
const uAbs = Math.abs(u).toFixed(2);
|
||||
const uTxt = u < 0 ? `-${uAbs}` : u > 0 ? `+${uAbs}` : uAbs;
|
||||
return `${signedCoin} ${unit} / ${uTxt}U`;
|
||||
}
|
||||
return `${sign}${fmt(n, 2)}U`;
|
||||
}
|
||||
@@ -3948,9 +3972,10 @@
|
||||
: "—";
|
||||
const tradeTxt = formatCoinTradingLabel(usdt, eth, btc);
|
||||
const pnlCcy = optionsPanelCcy(optMeta);
|
||||
const spotPx = spotPxFromOptMeta(optMeta);
|
||||
const pnlTxt = upnl == null || Number.isNaN(Number(upnl))
|
||||
? "—"
|
||||
: `<span class="${pnlCls(upnl)}">${fmtOptPnlText(upnl, pnlCcy)}</span>`;
|
||||
: `<span class="${pnlCls(upnl)}">${fmtOptPnlText(upnl, pnlCcy, spotPx)}</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>
|
||||
@@ -4116,7 +4141,7 @@
|
||||
${renderOptionsTargetCell(target, p)}`;
|
||||
if (showPnl) {
|
||||
const premCcy = optPremiumCcyOf(p);
|
||||
html += `<td class="${pnlCls(net)}">${net == null ? "—" : fmtOptPnlText(net, premCcy)}</td>
|
||||
html += `<td class="${pnlCls(net)}">${net == null ? "—" : fmtOptPnlText(net, premCcy, spotPxFromOptMeta(null, p))}</td>
|
||||
<td class="${pnlCls(net)}">${roi == null ? "—" : esc(Number(roi).toFixed(2)) + "%"}</td>`;
|
||||
}
|
||||
html += "</tr>";
|
||||
@@ -4602,6 +4627,7 @@
|
||||
let pnlShow = upnl;
|
||||
let pnlSuffix = "";
|
||||
let pnlUnit = "U";
|
||||
let pnlSpotPx = null;
|
||||
if (hasOptCap) {
|
||||
if (opt.enabled === false) {
|
||||
optLine = "期权未启用";
|
||||
@@ -4629,13 +4655,14 @@
|
||||
parts.push(`交易 ${fmt(bal.trading, 2)}U`);
|
||||
}
|
||||
if (optUpl != null && Number.isFinite(Number(optUpl))) {
|
||||
parts.push(`浮盈 ${fmtOptPnlText(optUpl, optCcy)}`);
|
||||
parts.push(`浮盈 ${fmtOptPnlText(optUpl, optCcy, spotPxFromOptMeta(opt))}`);
|
||||
}
|
||||
if (optUpl != null && Number.isFinite(Number(optUpl)) && openCount === 0) {
|
||||
// 永续空仓时主数字优先展示期权浮盈,避免一直显示 0U
|
||||
pnlShow = optUpl;
|
||||
pnlSuffix = "期权";
|
||||
pnlUnit = optCcy;
|
||||
pnlSpotPx = spotPxFromOptMeta(opt);
|
||||
}
|
||||
}
|
||||
optLine = parts.join(" · ");
|
||||
@@ -4646,7 +4673,7 @@
|
||||
const strategyStats = renderCardStrategyStats(row, hm, flaskOk);
|
||||
const tilePnlHtml =
|
||||
pnlUnit === "ETH" || pnlUnit === "BTC"
|
||||
? `${fmtOptPnlAmt(pnlShow, pnlUnit)} <small>${esc(pnlUnit)}${pnlSuffix ? " · " + esc(pnlSuffix) : ""}</small>`
|
||||
? `${fmtOptPnlText(pnlShow, pnlUnit, pnlSpotPx)} <small>${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="点击进入全屏详情">
|
||||
|
||||
@@ -51,14 +51,20 @@
|
||||
return "USDC";
|
||||
}
|
||||
|
||||
function pnlSignedOpt(v, ccy) {
|
||||
function pnlSignedOpt(v, ccy, spotPx) {
|
||||
const n = Number(v);
|
||||
if (!Number.isFinite(n)) return "—";
|
||||
const unit = String(ccy || "USDC").toUpperCase();
|
||||
if (unit === "ETH" || unit === "BTC") {
|
||||
const abs = Math.abs(n).toFixed(8).replace(/\.?0+$/, "") || "0";
|
||||
const sign = n > 0 ? "+" : n < 0 ? "-" : "";
|
||||
return `${sign}${abs} ${unit}`;
|
||||
const coinTxt = `${sign}${abs} ${unit}`;
|
||||
const px = Number(spotPx);
|
||||
if (!Number.isFinite(px) || !(px > 0)) return coinTxt;
|
||||
const u = n * px;
|
||||
const uAbs = Math.abs(u).toFixed(2);
|
||||
const uSign = u < 0 ? "-" : u > 0 ? "+" : "";
|
||||
return `${coinTxt} / ${uSign}${uAbs}U`;
|
||||
}
|
||||
return pnlSigned(n, 2);
|
||||
}
|
||||
@@ -361,7 +367,15 @@
|
||||
<td>${p.idx_px != null ? fmt(p.idx_px, 0) : "—"}</td>
|
||||
<td><span class="${targetCls}">${esc(target)}</span></td>`;
|
||||
if (showPnl) {
|
||||
html += `<td class="${pnlClass(net)}">${net != null ? pnlSignedOpt(net, optPremiumCcyOf(p)) : "—"}</td>
|
||||
html += `<td class="${pnlClass(net)}">${
|
||||
net != null
|
||||
? pnlSignedOpt(
|
||||
net,
|
||||
optPremiumCcyOf(p),
|
||||
Number(p.idx_px != null ? p.idx_px : p.idxPx) || null
|
||||
)
|
||||
: "—"
|
||||
}</td>
|
||||
<td class="${pnlClass(roi)}">${roi != null ? esc(Number(roi).toFixed(2)) + "%" : "—"}</td>`;
|
||||
}
|
||||
html += "</tr>";
|
||||
|
||||
Reference in New Issue
Block a user