Add cumulative P&L banner to fund overview for at-a-glance profit/loss.
Expose period delta from equity curve start and surface it in the toolbar and summary cards with green/red cues. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7266,6 +7266,10 @@ html[data-theme="light"] .funds-stage {
|
||||
50% { opacity: 0.55; transform: scale(0.88); }
|
||||
}
|
||||
.funds-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 10px 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.funds-btn-refresh {
|
||||
@@ -7273,15 +7277,115 @@ html[data-theme="light"] .funds-stage {
|
||||
letter-spacing: 0.06em;
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
.funds-pnl-banner {
|
||||
flex: 1 1 240px;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px 16px;
|
||||
padding: 10px 14px;
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid var(--border-soft);
|
||||
background: rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
html[data-theme="light"] .funds-pnl-banner {
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
}
|
||||
.funds-pnl-banner.is-pos {
|
||||
border-color: color-mix(in srgb, var(--green) 45%, var(--border-soft));
|
||||
background: color-mix(in srgb, var(--green) 10%, rgba(0, 0, 0, 0.28));
|
||||
box-shadow: inset 0 0 28px color-mix(in srgb, var(--green) 8%, transparent);
|
||||
}
|
||||
.funds-pnl-banner.is-neg {
|
||||
border-color: color-mix(in srgb, var(--red) 45%, var(--border-soft));
|
||||
background: color-mix(in srgb, var(--red) 10%, rgba(0, 0, 0, 0.28));
|
||||
box-shadow: inset 0 0 28px color-mix(in srgb, var(--red) 8%, transparent);
|
||||
}
|
||||
html[data-theme="light"] .funds-pnl-banner.is-pos {
|
||||
background: color-mix(in srgb, var(--green) 8%, rgba(255, 255, 255, 0.9));
|
||||
}
|
||||
html[data-theme="light"] .funds-pnl-banner.is-neg {
|
||||
background: color-mix(in srgb, var(--red) 8%, rgba(255, 255, 255, 0.9));
|
||||
}
|
||||
.funds-pnl-main {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
gap: 8px 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
.funds-pnl-label {
|
||||
font-family: var(--display);
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--muted);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.funds-pnl-value {
|
||||
font-family: var(--font);
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.funds-pnl-pct {
|
||||
font-family: var(--mono);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
opacity: 0.92;
|
||||
}
|
||||
.funds-pnl-value.pos,
|
||||
.funds-pnl-pct.pos,
|
||||
.funds-pnl-side-val.pos {
|
||||
color: var(--green);
|
||||
}
|
||||
.funds-pnl-value.neg,
|
||||
.funds-pnl-pct.neg,
|
||||
.funds-pnl-side-val.neg {
|
||||
color: var(--red);
|
||||
}
|
||||
.funds-pnl-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 2px;
|
||||
padding-left: 12px;
|
||||
border-left: 1px solid var(--border-soft);
|
||||
}
|
||||
.funds-pnl-side-label {
|
||||
font-family: var(--display);
|
||||
font-size: 0.58rem;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--muted);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.funds-pnl-side-val {
|
||||
font-family: var(--font);
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.funds-status.err {
|
||||
color: var(--red);
|
||||
}
|
||||
.funds-summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.funds-stat-card-pnl .funds-stat-val {
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
.funds-stat-sub {
|
||||
margin-top: 4px;
|
||||
font-size: 0.72rem;
|
||||
font-family: var(--mono);
|
||||
color: var(--muted);
|
||||
}
|
||||
.funds-stat-card {
|
||||
position: relative;
|
||||
background: rgba(0, 0, 0, 0.28);
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
const elDdU = document.getElementById("funds-total-dd-u");
|
||||
const elDdPct = document.getElementById("funds-total-dd-pct");
|
||||
const elDelta = document.getElementById("funds-total-delta");
|
||||
const elPeriod = document.getElementById("funds-total-period");
|
||||
const elPeriodSub = document.getElementById("funds-total-period-sub");
|
||||
const elPeriodBanner = document.getElementById("funds-period-delta");
|
||||
const elPeriodPct = document.getElementById("funds-period-pct");
|
||||
const elDayChip = document.getElementById("funds-day-chip");
|
||||
const elPnlBanner = document.getElementById("funds-pnl-banner");
|
||||
const elMeta = document.getElementById("funds-meta");
|
||||
const elDescBody = document.getElementById("funds-desc-body");
|
||||
const elChartSub = document.getElementById("funds-chart-sub");
|
||||
@@ -50,6 +56,13 @@
|
||||
return sign + v.toFixed(2) + " U";
|
||||
}
|
||||
|
||||
function fmtPct(n) {
|
||||
if (n == null || !Number.isFinite(Number(n))) return "—";
|
||||
const v = Number(n);
|
||||
const sign = v > 0 ? "+" : "";
|
||||
return sign + v.toFixed(2) + "%";
|
||||
}
|
||||
|
||||
function deltaClass(n) {
|
||||
if (!Number.isFinite(Number(n))) return "";
|
||||
if (Number(n) > 0) return "pos";
|
||||
@@ -193,6 +206,8 @@
|
||||
const ddPct = dd.max_drawdown_pct != null ? fmt(dd.max_drawdown_pct, 2) + "%" : "—";
|
||||
const deltaCls = deltaClass(ac.day_delta_usdt);
|
||||
const deltaText = monitored ? fmtDelta(ac.day_delta_usdt) : "—";
|
||||
const periodCls = deltaClass(ac.period_delta_usdt);
|
||||
const periodText = monitored ? fmtDelta(ac.period_delta_usdt) : "—";
|
||||
return (
|
||||
'<button type="button" class="funds-ac-card' +
|
||||
offCls +
|
||||
@@ -227,6 +242,11 @@
|
||||
trading +
|
||||
"</span></div>" +
|
||||
optLine +
|
||||
'<div><span class="k">累计盈亏</span><span class="v ' +
|
||||
periodCls +
|
||||
'">' +
|
||||
periodText +
|
||||
"</span></div>" +
|
||||
'<div><span class="k">较昨日</span><span class="v ' +
|
||||
deltaCls +
|
||||
'">' +
|
||||
@@ -370,6 +390,35 @@
|
||||
elDelta.textContent = fmtDelta(totals.day_delta_usdt);
|
||||
elDelta.className = "funds-stat-val " + deltaClass(totals.day_delta_usdt);
|
||||
}
|
||||
const periodCls = deltaClass(totals.period_delta_usdt);
|
||||
if (elPeriod) {
|
||||
elPeriod.textContent = fmtDelta(totals.period_delta_usdt);
|
||||
elPeriod.className = "funds-stat-val " + periodCls;
|
||||
}
|
||||
if (elPeriodSub) {
|
||||
const startDay = data.history_start_day || "—";
|
||||
const pct = fmtPct(totals.period_delta_pct);
|
||||
elPeriodSub.textContent =
|
||||
pct !== "—"
|
||||
? "自 " + startDay + " · " + pct
|
||||
: "自 " + startDay + " 起相对起点";
|
||||
}
|
||||
if (elPeriodBanner) {
|
||||
elPeriodBanner.textContent = fmtDelta(totals.period_delta_usdt);
|
||||
elPeriodBanner.className = "funds-pnl-value " + periodCls;
|
||||
}
|
||||
if (elPeriodPct) {
|
||||
elPeriodPct.textContent = fmtPct(totals.period_delta_pct);
|
||||
elPeriodPct.className = "funds-pnl-pct " + periodCls;
|
||||
}
|
||||
if (elDayChip) {
|
||||
elDayChip.textContent = fmtDelta(totals.day_delta_usdt);
|
||||
elDayChip.className = "funds-pnl-side-val " + deltaClass(totals.day_delta_usdt);
|
||||
}
|
||||
if (elPnlBanner) {
|
||||
elPnlBanner.className =
|
||||
"funds-pnl-banner" + (periodCls ? " is-" + periodCls : "");
|
||||
}
|
||||
if (elMeta) {
|
||||
const parts = [
|
||||
"交易日 " + (data.trading_day || "—"),
|
||||
|
||||
@@ -15,7 +15,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=20260715-hub-phone-folds" />
|
||||
<link rel="stylesheet" href="/assets/app.css?v=20260716-funds-pnl-banner" />
|
||||
<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>
|
||||
@@ -625,6 +625,17 @@
|
||||
</div>
|
||||
<div class="funds-toolbar toolbar">
|
||||
<button type="button" id="funds-btn-refresh" class="primary funds-btn-refresh">同步快照</button>
|
||||
<div id="funds-pnl-banner" class="funds-pnl-banner" aria-live="polite">
|
||||
<div class="funds-pnl-main">
|
||||
<span class="funds-pnl-label">累计盈亏 · P&L</span>
|
||||
<span id="funds-period-delta" class="funds-pnl-value">—</span>
|
||||
<span id="funds-period-pct" class="funds-pnl-pct">—</span>
|
||||
</div>
|
||||
<div class="funds-pnl-side">
|
||||
<span class="funds-pnl-side-label">较昨日</span>
|
||||
<span id="funds-day-chip" class="funds-pnl-side-val">—</span>
|
||||
</div>
|
||||
</div>
|
||||
<span id="funds-status" class="toolbar-meta funds-status"></span>
|
||||
</div>
|
||||
<section class="funds-summary">
|
||||
@@ -632,6 +643,11 @@
|
||||
<div class="funds-stat-label">总资金 · TOTAL</div>
|
||||
<div id="funds-total-usdt" class="funds-stat-value">—</div>
|
||||
</div>
|
||||
<div class="funds-stat-card funds-stat-card-pnl">
|
||||
<div class="funds-stat-label">累计盈亏 · SINCE START</div>
|
||||
<div id="funds-total-period" class="funds-stat-val">—</div>
|
||||
<div id="funds-total-period-sub" class="funds-stat-sub">相对统计起点</div>
|
||||
</div>
|
||||
<div class="funds-stat-card">
|
||||
<div class="funds-stat-label">较昨日 · Δ24H</div>
|
||||
<div id="funds-total-delta" class="funds-stat-val">—</div>
|
||||
@@ -1301,7 +1317,7 @@
|
||||
<script src="/assets/calculator.js?v=20260715-calc-tabs"></script>
|
||||
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
||||
<script src="/assets/archive.js?v=20260710-archive-cum2"></script>
|
||||
<script src="/assets/funds.js?v=20260707-hub-options-funds"></script>
|
||||
<script src="/assets/funds.js?v=20260716-funds-pnl-banner"></script>
|
||||
<script src="/assets/dashboard.js?v=20260708-options-expiry-cd"></script>
|
||||
<script src="/assets/strategy.js?v=3"></script>
|
||||
<script src="/assets/help.js?v=1"></script>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
### 总览
|
||||
|
||||
- **总资金**:当前监控板最新一轮聚合的实时合计(资金户+交易户齐全才计入)
|
||||
- **累计盈亏**:相对统计起点(`HUB_FUND_HISTORY_START_DAY`)首个快照的总资金变动(U / %);顶栏大字绿涨红跌,一眼可看盈亏。含出入金影响,口径同权益曲线,不含浮盈
|
||||
- **较昨日**:相对上一交易日快照点的变动(U)
|
||||
- **最大回撤**:总资金历史曲线的峰值回撤(U / %)
|
||||
- **总资金曲线**:近 180 交易日
|
||||
@@ -78,9 +79,11 @@
|
||||
返回字段概要:
|
||||
|
||||
- `totals.total_usdt` — 当前总资金
|
||||
- `totals.day_delta_usdt` — 较昨日变动
|
||||
- `totals.period_delta_usdt` / `period_delta_pct` / `start_usdt` — 相对曲线起点累计盈亏
|
||||
- `totals.series[]` — `{ day, total_usdt }` 总曲线
|
||||
- `totals.drawdown` — `{ peak_usdt, max_drawdown_u, max_drawdown_pct }`
|
||||
- `accounts[]` — 分户实时余额,曲线,回撤,`monitored` 标记
|
||||
- `accounts[]` — 分户实时余额,曲线,回撤,日/累计变动,`monitored` 标记
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user