diff --git a/manual_trading_hub/static/app.css b/manual_trading_hub/static/app.css index b8bdc67..b4f1d3f 100644 --- a/manual_trading_hub/static/app.css +++ b/manual_trading_hub/static/app.css @@ -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); diff --git a/manual_trading_hub/static/app.js b/manual_trading_hub/static/app.js index 2fc1f5e..52a387d 100644 --- a/manual_trading_hub/static/app.js +++ b/manual_trading_hub/static/app.js @@ -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 `
-
资金账户
${fmt(funding, 2)} U
-
交易账户
${fmt(trading, 2)} U
-
浮盈合计
${fmt(upnl, 2)}
+ const isOpt = kind === "options"; + const fundLabel = isOpt ? "期权资金账户" : "资金账户"; + const tradeLabel = isOpt ? "期权交易账户" : "交易账户"; + const pnlLabel = isOpt ? "期权浮盈" : "浮盈合计"; + const rowCls = isOpt ? "stat-row stat-row-options" : "stat-row"; + return `
+
${fundLabel}
${fmt(funding, 2)} U
+
${tradeLabel}
${fmt(trading, 2)} U
+
${pnlLabel}
${fmt(upnl, 2)}
`; } @@ -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 += '
期权持仓
'; html += '
期权未启用(OKX_OPTIONS_ENABLED)
'; } else if (opt.ok === false) { - html += renderStatRow(null, null, null); + html += renderOptionsAccountStatRow(opt); html += '
期权持仓
'; html += `
${esc(opt.msg || "期权数据不可用")}
`; } 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 += `
期权持仓 · ${pos.length} 仓
`; 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 = "期权"; } } } diff --git a/manual_trading_hub/static/index.html b/manual_trading_hub/static/index.html index bfdbd52..43049cd 100644 --- a/manual_trading_hub/static/index.html +++ b/manual_trading_hub/static/index.html @@ -16,7 +16,7 @@ - + @@ -1212,7 +1212,7 @@