Label dashboard positions from monitor sources with priority.
Match hedge/roll/trend/order/key monitors for source badges, show option target monitors in green, and refresh the dashboard with the board 5s cycle. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -373,6 +373,51 @@ body.hub-page-dashboard .page#page-dashboard {
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.dash-pos-source.is-hedge {
|
||||
color: #fbbf24;
|
||||
background: rgba(245, 158, 11, 0.16);
|
||||
border: 1px solid rgba(245, 158, 11, 0.4);
|
||||
}
|
||||
|
||||
.dash-pos-source.is-roll {
|
||||
color: #6ee7b7;
|
||||
background: rgba(16, 185, 129, 0.16);
|
||||
border: 1px solid rgba(16, 185, 129, 0.4);
|
||||
}
|
||||
|
||||
.dash-pos-source.is-trend {
|
||||
color: #93c5fd;
|
||||
background: rgba(59, 130, 246, 0.18);
|
||||
border: 1px solid rgba(59, 130, 246, 0.35);
|
||||
}
|
||||
|
||||
.dash-pos-source.is-order {
|
||||
color: #c4b5fd;
|
||||
background: rgba(139, 92, 246, 0.18);
|
||||
border: 1px solid rgba(139, 92, 246, 0.35);
|
||||
}
|
||||
|
||||
.dash-pos-source.is-key {
|
||||
color: #fdba74;
|
||||
background: rgba(249, 115, 22, 0.16);
|
||||
border: 1px solid rgba(249, 115, 22, 0.4);
|
||||
}
|
||||
|
||||
.dash-pos-source.is-none {
|
||||
color: var(--dash-muted);
|
||||
background: rgba(148, 163, 184, 0.12);
|
||||
border: 1px solid rgba(148, 163, 184, 0.28);
|
||||
}
|
||||
|
||||
.dash-target-monitor {
|
||||
color: var(--dash-muted);
|
||||
}
|
||||
|
||||
.dash-target-monitor.is-on {
|
||||
color: #4ade80;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dash-pos-source.is-perp {
|
||||
color: #93c5fd;
|
||||
background: rgba(59, 130, 246, 0.18);
|
||||
|
||||
@@ -144,19 +144,29 @@
|
||||
return perp.length > 0 || (ac && ac.options_layout && optionsPositions.length > 0);
|
||||
}
|
||||
|
||||
function sourceBadgeClass(source) {
|
||||
const s = String(source || "");
|
||||
if (s.indexOf("对冲") >= 0) return "is-hedge";
|
||||
if (s.indexOf("顺势") >= 0) return "is-roll";
|
||||
if (s.indexOf("趋势") >= 0) return "is-trend";
|
||||
if (s.indexOf("关键位") >= 0) return "is-key";
|
||||
if (s.indexOf("下单") >= 0) return "is-order";
|
||||
return "is-none";
|
||||
}
|
||||
|
||||
function renderDashboardPerpTable(lines) {
|
||||
const rows = Array.isArray(lines) ? lines : [];
|
||||
if (!rows.length) return "";
|
||||
const body = rows
|
||||
.map((ln) => {
|
||||
const source = esc((ln && ln.source) || "永续");
|
||||
const source = String((ln && ln.source) || "—");
|
||||
const symbol = esc((ln && (ln.symbol || ln.text)) || "—");
|
||||
const side = esc((ln && ln.side) || "—");
|
||||
const contracts =
|
||||
ln && ln.contracts != null && ln.contracts !== "" ? esc(String(ln.contracts)) : "—";
|
||||
const pnl = ln && ln.pnl != null ? Number(ln.pnl) : NaN;
|
||||
return `<tr>
|
||||
<td><span class="dash-pos-source is-perp">${source}</span></td>
|
||||
<td><span class="dash-pos-source ${sourceBadgeClass(source)}">${esc(source)}</span></td>
|
||||
<td>${symbol}</td>
|
||||
<td>${side}</td>
|
||||
<td>${contracts}</td>
|
||||
@@ -188,14 +198,16 @@
|
||||
: (p.opt_type || "").toUpperCase() === "P"
|
||||
? "Put"
|
||||
: p.opt_type || "—";
|
||||
const source = String(p.source_label || p.source || "—");
|
||||
const target = String(p.target_monitor_text || "—");
|
||||
const targetCls = target && target !== "—" ? "dash-target-monitor is-on" : "dash-target-monitor";
|
||||
return `<tr>
|
||||
<td><span class="dash-pos-source is-opt">期权</span></td>
|
||||
<td><span class="dash-pos-source ${sourceBadgeClass(source)}">${esc(source)}</span></td>
|
||||
<td title="${esc(p.inst_id || "")}">${esc(shortDashInst(p.inst_id))}</td>
|
||||
<td>${esc(optType)}</td>
|
||||
<td>${dashOptionsExpiryCd(p.exp_time_ms != null ? p.exp_time_ms : p.exp_time)}</td>
|
||||
<td>${p.idx_px != null ? fmt(p.idx_px, 0) : "—"}</td>
|
||||
<td>${p.expiry_be_px != null ? fmt(p.expiry_be_px, 0) : "—"}</td>
|
||||
<td>${p.close_be_px != null ? fmt(p.close_be_px, 0) : "—"}</td>
|
||||
<td><span class="${targetCls}">${esc(target)}</span></td>
|
||||
<td class="${pnlClass(p.upl)}">${p.upl != null ? pnlSigned(p.upl, 2) : "—"}</td>
|
||||
</tr>`;
|
||||
})
|
||||
@@ -205,7 +217,7 @@
|
||||
<div class="dash-table-wrap dash-options-table-wrap">
|
||||
<table class="dash-table dash-options-table">
|
||||
<thead><tr>
|
||||
<th>来源</th><th>合约</th><th>类型</th><th>到期倒计时</th><th>指数</th><th>到期平衡</th><th>平掉回本</th><th>浮盈</th>
|
||||
<th>来源</th><th>合约</th><th>类型</th><th>到期倒计时</th><th>指数</th><th>目标监控</th><th>浮盈</th>
|
||||
</tr></thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>
|
||||
@@ -360,7 +372,7 @@
|
||||
const ver = Number(data.dashboard_version) || 0;
|
||||
if (ver) localDashVersion = ver;
|
||||
renderPayload(data);
|
||||
const sec = Number(data.poll_interval_sec) || 60;
|
||||
const sec = Number(data.poll_interval_sec) || 5;
|
||||
setStatus(options.silent ? `SSE 已连接 · 后台每 ${sec}s 聚合` : `已更新 · 后台每 ${sec}s 聚合`);
|
||||
} catch (e) {
|
||||
setStatus(String(e.message || e), true);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<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>
|
||||
<link rel="stylesheet" href="/assets/dashboard.css?v=20260717-dash-pos-only" />
|
||||
<link rel="stylesheet" href="/assets/dashboard.css?v=20260717-dash-source" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-bg" aria-hidden="true"></div>
|
||||
@@ -1373,7 +1373,7 @@
|
||||
<script src="/assets/archive.js?v=20260717-archive-cal-chart"></script>
|
||||
<script src="/assets/quotes.js?v=20260717-quotes-feed"></script>
|
||||
<script src="/assets/funds.js?v=20260717-funds-scroll-fix"></script>
|
||||
<script src="/assets/dashboard.js?v=20260717-dash-pos-only"></script>
|
||||
<script src="/assets/dashboard.js?v=20260717-dash-source"></script>
|
||||
<script src="/assets/strategy.js?v=3"></script>
|
||||
<script src="/assets/help.js?v=1"></script>
|
||||
<script src="/assets/logs.js?v=1"></script>
|
||||
|
||||
Reference in New Issue
Block a user