Add live expiry countdown for options positions on instance page and trading hub.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8161,6 +8161,20 @@ html[data-theme="light"] .hub-monitor-options .hub-monitor-block-label {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.opt-expiry-cd {
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.opt-expiry-cd--urgent {
|
||||
color: #ffb347;
|
||||
}
|
||||
|
||||
.opt-expiry-cd--expired {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
html[data-theme="light"] .hub-options-table th {
|
||||
color: #3a5068;
|
||||
}
|
||||
|
||||
@@ -2250,6 +2250,9 @@
|
||||
TimeCloseUI.tickLocalCountdowns();
|
||||
}
|
||||
ensureHubHoldDurationTimer();
|
||||
if (window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
|
||||
OptionsExpiryCountdown.ensureTimer();
|
||||
}
|
||||
|
||||
if (expandedExchangeId && fs && fsInner) {
|
||||
const row = rows.find((r) => String(r.id) === String(expandedExchangeId));
|
||||
@@ -2264,6 +2267,9 @@
|
||||
TimeCloseUI.tickLocalCountdowns();
|
||||
}
|
||||
ensureHubHoldDurationTimer();
|
||||
if (window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
|
||||
OptionsExpiryCountdown.ensureTimer();
|
||||
}
|
||||
fsInner.querySelectorAll(".btn-expand-back").forEach((btn) => {
|
||||
btn.onclick = (ev) => {
|
||||
ev.stopPropagation();
|
||||
@@ -3472,10 +3478,16 @@
|
||||
return s.slice(0, 10) + "…" + s.slice(-8);
|
||||
}
|
||||
|
||||
function optionsExpiryCdHtml(expMs) {
|
||||
const ms = expMs != null && expMs !== "" ? String(expMs) : "";
|
||||
if (!ms) return "—";
|
||||
return `<span class="opt-expiry-cd" data-opt-exp-ms="${esc(ms)}">—</span>`;
|
||||
}
|
||||
|
||||
function renderOptionsPositionsTable(pos) {
|
||||
if (!pos.length) return '<div class="empty-hint">暂无期权持仓</div>';
|
||||
let html = '<div class="table-wrap hub-options-table-wrap"><table class="hub-options-table"><thead><tr>';
|
||||
html += "<th>合约</th><th>类型</th><th>张数</th><th>指数</th><th>到期平衡</th><th>平掉回本</th><th>浮盈</th><th>浮盈%</th>";
|
||||
html += "<th>合约</th><th>类型</th><th>张数</th><th>到期倒计时</th><th>指数</th><th>到期平衡</th><th>平掉回本</th><th>浮盈</th><th>浮盈%</th>";
|
||||
html += "</tr></thead><tbody>";
|
||||
pos.forEach((p) => {
|
||||
const optType = (p.opt_type || "").toUpperCase() === "C" ? "Call" : (p.opt_type || "").toUpperCase() === "P" ? "Put" : (p.opt_type || "—");
|
||||
@@ -3483,6 +3495,7 @@
|
||||
<td><code class="hub-options-inst" title="${esc(p.inst_id || "")}">${esc(shortOptionsInst(p.inst_id))}</code></td>
|
||||
<td>${esc(optType)}</td>
|
||||
<td>${esc(p.pos)}</td>
|
||||
<td>${optionsExpiryCdHtml(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>
|
||||
|
||||
@@ -118,6 +118,12 @@
|
||||
return chips;
|
||||
}
|
||||
|
||||
function dashOptionsExpiryCd(expMs) {
|
||||
const ms = expMs != null && expMs !== "" ? String(expMs) : "";
|
||||
if (!ms) return "—";
|
||||
return `<span class="opt-expiry-cd" data-opt-exp-ms="${esc(ms)}">—</span>`;
|
||||
}
|
||||
|
||||
function renderDashboardOptionsTable(positions) {
|
||||
const pos = Array.isArray(positions) ? positions : [];
|
||||
if (!pos.length) return "";
|
||||
@@ -132,6 +138,7 @@
|
||||
return `<tr>
|
||||
<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>
|
||||
@@ -144,7 +151,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>
|
||||
</tr></thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>
|
||||
@@ -303,6 +310,9 @@
|
||||
})
|
||||
.join("");
|
||||
bindDashboardExpand();
|
||||
if (window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
|
||||
OptionsExpiryCountdown.ensureTimer();
|
||||
}
|
||||
}
|
||||
|
||||
function renderTrades(trades, accounts) {
|
||||
|
||||
@@ -1146,11 +1146,12 @@
|
||||
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
||||
<script src="/assets/archive.js?v=20260626-archive-layout"></script>
|
||||
<script src="/assets/funds.js?v=20260707-hub-options-funds"></script>
|
||||
<script src="/assets/dashboard.js?v=20260707-dash-okx-options"></script>
|
||||
<script src="/assets/dashboard.js?v=20260708-options-expiry-cd"></script>
|
||||
<script src="/assets/strategy.js?v=3"></script>
|
||||
<script src="/assets/ai_review_render.js?v=3"></script>
|
||||
<script src="/assets/time_close_ui.js?v=3"></script>
|
||||
<script src="/assets/options_expiry_countdown.js?v=1"></script>
|
||||
<script src="/assets/backup.js?v=1"></script>
|
||||
<script src="/assets/app.js?v=20260707-monitor-options-split"></script>
|
||||
<script src="/assets/app.js?v=20260708-options-expiry-cd"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user