Show options funding, trading, and float PnL in monitor account stats.

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-23 12:34:23 +08:00
parent 0096467d14
commit f11f89e760
3 changed files with 61 additions and 27 deletions
+6
View File
@@ -2357,6 +2357,12 @@ html[data-theme="light"] .hub-pos-card .pos-tp-profit {
margin-bottom: 12px;
}
.stat-row-options .stat-label {
color: var(--accent);
text-transform: none;
letter-spacing: 0;
}
.stat-box {
background: var(--inset-surface);
border: 1px solid var(--border-soft);
+52 -24
View File
@@ -3755,22 +3755,39 @@
}
function optionsBalanceFields(opt) {
const bal = (opt && opt.balances) || opt || {};
if (!opt || typeof opt !== "object") {
return { funding: null, trading: null, upl: null };
}
const bal =
opt.balances && typeof opt.balances === "object" ? opt.balances : {};
const pick = (a, b) => (a != null && a !== "" ? a : b);
return {
funding: sumUsdtEquiv(bal.funding_usdt, bal.funding_usdc),
trading: sumUsdtEquiv(bal.trading_usdt, bal.trading_usdc),
upl: opt && opt.upl_total_usdc != null && Number.isFinite(Number(opt.upl_total_usdc))
? Number(opt.upl_total_usdc)
: null,
funding: sumUsdtEquiv(
pick(bal.funding_usdt, opt.funding_usdt),
pick(bal.funding_usdc, opt.funding_usdc)
),
trading: sumUsdtEquiv(
pick(bal.trading_usdt, opt.trading_usdt),
pick(bal.trading_usdc, opt.trading_usdc)
),
upl:
opt.upl_total_usdc != null && Number.isFinite(Number(opt.upl_total_usdc))
? Number(opt.upl_total_usdc)
: null,
};
}
function renderStatRow(funding, trading, upnl) {
function renderStatRow(funding, trading, upnl, kind) {
if (!showAccountPnlPref()) return "";
return `<div class="stat-row">
<div class="stat-box"><div class="stat-label">资金账户</div><div class="stat-value">${fmt(funding, 2)} <small style="font-size:12px;color:var(--muted)">U</small></div></div>
<div class="stat-box"><div class="stat-label">交易账户</div><div class="stat-value">${fmt(trading, 2)} <small style="font-size:12px;color:var(--muted)">U</small></div></div>
<div class="stat-box"><div class="stat-label">浮盈合计</div><div class="stat-value ${pnlCls(upnl)}">${fmt(upnl, 2)}</div></div>
const isOpt = kind === "options";
const fundLabel = isOpt ? "期权资金账户" : "资金账户";
const tradeLabel = isOpt ? "期权交易账户" : "交易账户";
const pnlLabel = isOpt ? "期权浮盈" : "浮盈合计";
const rowCls = isOpt ? "stat-row stat-row-options" : "stat-row";
return `<div class="${rowCls}">
<div class="stat-box"><div class="stat-label">${fundLabel}</div><div class="stat-value">${fmt(funding, 2)} <small style="font-size:12px;color:var(--muted)">U</small></div></div>
<div class="stat-box"><div class="stat-label">${tradeLabel}</div><div class="stat-value">${fmt(trading, 2)} <small style="font-size:12px;color:var(--muted)">U</small></div></div>
<div class="stat-box"><div class="stat-label">${pnlLabel}</div><div class="stat-value ${pnlCls(upnl)}">${fmt(upnl, 2)}</div></div>
</div>`;
}
@@ -3778,6 +3795,11 @@
return renderStatRow(row.funding_usdt, row.trading_usdt, ag.total_unrealized_pnl);
}
function renderOptionsAccountStatRow(opt) {
const bal = optionsBalanceFields(opt);
return renderStatRow(bal.funding, bal.trading, bal.upl, "options");
}
function shortOptionsInst(instId) {
const s = String(instId || "");
if (s.length <= 22) return s;
@@ -3883,18 +3905,17 @@
const opt = row.options || {};
let html = "";
if (opt.enabled === false) {
html += renderStatRow(null, null, null);
html += renderOptionsAccountStatRow(opt);
html += '<div class="section-title hub-options-title">期权持仓</div>';
html += '<div class="empty-hint">期权未启用(OKX_OPTIONS_ENABLED)</div>';
} else if (opt.ok === false) {
html += renderStatRow(null, null, null);
html += renderOptionsAccountStatRow(opt);
html += '<div class="section-title hub-options-title">期权持仓</div>';
html += `<div class="err">${esc(opt.msg || "期权数据不可用")}</div>`;
} else {
const pos = Array.isArray(opt.positions) ? opt.positions : [];
const targets = Array.isArray(opt.target_monitors) ? opt.target_monitors : [];
const bal = optionsBalanceFields(opt);
html += renderStatRow(bal.funding, bal.trading, bal.upl);
html += renderOptionsAccountStatRow(opt);
html += `<div class="section-title hub-options-title">期权持仓 · ${pos.length} 仓</div>`;
html +=
layout === "cards"
@@ -4326,16 +4347,23 @@
opt.position_count != null ? opt.position_count : (opt.positions || []).length
);
const n = Number.isFinite(optCount) ? optCount : 0;
const bal = typeof optionsBalanceFields === "function" ? optionsBalanceFields(opt) : {};
const optUpl = bal && bal.upl != null ? bal.upl : null;
optLine = n > 0 ? `期权 ${n}` : "期权 空仓";
if (optUpl != null && Number.isFinite(Number(optUpl))) {
optLine += ` · 浮盈 ${fmt(optUpl, 2)}U`;
// 永续空仓时主数字优先展示期权浮盈,避免一直显示 0U
if (openCount === 0) {
pnlShow = optUpl;
pnlSuffix = "期权";
const bal = optionsBalanceFields(opt);
const optUpl = bal.upl != null ? bal.upl : null;
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 (optUpl != null && Number.isFinite(Number(optUpl))) {
parts.push(`浮盈 ${fmt(optUpl, 2)}U`);
}
} else if (optUpl != null && Number.isFinite(Number(optUpl))) {
parts.push(`浮盈 ${fmt(optUpl, 2)}U`);
}
optLine = parts.join(" · ");
if (optUpl != null && Number.isFinite(Number(optUpl)) && openCount === 0) {
// 永续空仓时主数字优先展示期权浮盈,避免一直显示 0U
pnlShow = optUpl;
pnlSuffix = "期权";
}
}
}
+3 -3
View File
@@ -16,7 +16,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
<link rel="stylesheet" href="/assets/app.css?v=20260723-amp-hist" />
<link rel="stylesheet" href="/assets/app.css?v=20260723-opt-acct" />
<link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=4" />
<link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" />
<script src="/assets/account_risk_badge.js?v=4"></script>
@@ -1212,7 +1212,7 @@
</div>
<label class="chk-label settings-display-chk">
<input type="checkbox" id="pref-show-account-pnl" checked />
监控区显示资金账户,交易账户与浮动盈亏
监控区显示资金账户交易账户与浮动盈亏(含期权)
</label>
<label class="chk-label settings-display-chk">
<input type="checkbox" id="pref-show-nav-funds" checked />
@@ -1516,6 +1516,6 @@
<script src="/assets/options_expiry_countdown.js?v=1"></script>
<script src="/assets/options_position_cards.js?v=2"></script>
<script src="/assets/backup.js?v=1"></script>
<script src="/assets/app.js?v=20260723-amp-stats"></script>
<script src="/assets/app.js?v=20260723-opt-acct"></script>
</body>
</html>