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 `
-
-
-
+ 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 @@