" +
+ (opt.inst_id || "—") +
+ "" +
+ '" +
+ (perp.symbol || "—") +
+ "" +
+ 'diff --git a/lib/common/static/hedge_plan.js b/lib/common/static/hedge_plan.js
index 02582fd..8298cf7 100644
--- a/lib/common/static/hedge_plan.js
+++ b/lib/common/static/hedge_plan.js
@@ -862,7 +862,8 @@
}
function setHpPosTab(tab) {
- const next = tab === "pending" || tab === "history" || tab === "stats" ? tab : "live";
+ const allowed = { live: 1, plans: 1, pending: 1, history: 1, stats: 1 };
+ const next = allowed[tab] ? tab : "live";
state.posTab = next;
document.querySelectorAll(".hp-pos-tab").forEach(function (btn) {
const on = btn.getAttribute("data-hp-pos-tab") === next;
@@ -875,17 +876,146 @@
if (on) pane.removeAttribute("hidden");
else pane.setAttribute("hidden", "");
});
- if (next === "live" || next === "pending") void loadActivePlans();
+ if (next === "live") void loadLivePositions();
+ else if (next === "plans" || next === "pending") void loadActivePlans();
else if (next === "history") void loadHistory();
else if (next === "stats") void loadStats();
}
function refreshHpPosPanel() {
+ void loadLivePositions();
void loadActivePlans();
void loadHistory();
if (state.posTab === "stats") void loadStats();
}
+ function pnlClsNum(v) {
+ if (v == null || Number.isNaN(Number(v))) return "";
+ const n = Number(v);
+ if (n > 0) return "hp-pnl-pos";
+ if (n < 0) return "hp-pnl-neg";
+ return "";
+ }
+
+ function fmtSigned(v, d) {
+ if (v == null || Number.isNaN(Number(v))) return "—";
+ const n = Number(v);
+ const s = fmt(n, d == null ? 2 : d);
+ return n > 0 ? "+" + s : s;
+ }
+
+ function renderLivePosCard(card) {
+ const opt = card.option || {};
+ const perp = card.perp || {};
+ const combo = card.combo || {};
+ const optType = String(opt.opt_type || "").toUpperCase() === "P" ? "Put" : "Call";
+ const perpSide = String(perp.side || "").toLowerCase() === "short" ? "空" : "多";
+ const comboCls = pnlClsNum(combo.net_usdt);
+ return (
+ '" +
+ (opt.inst_id || "—") +
+ "" +
+ '" +
+ (perp.symbol || "—") +
+ "" +
+ '
暂无期权/永续对冲持仓
'; + return; + } + box.innerHTML = cards.map(renderLivePosCard).join(""); + box.querySelectorAll(".hp-btn-detail").forEach(function (btn) { + btn.addEventListener("click", function () { + void showPlanDetail(Number(btn.getAttribute("data-id"))); + }); + }); + box.querySelectorAll(".hp-btn-end").forEach(function (btn) { + btn.addEventListener("click", function () { + void endActivePlan(Number(btn.getAttribute("data-id"))); + }); + }); + } catch (e) { + box.innerHTML = '' + (e.message || e) + "
"; + } + } + /** 手动选约:不自动代选;仅在已选失效(换 Call/Put 或筛掉)时清空. */ function autoMatchPoOption(force) { if (!isOptionPrimary()) return; @@ -3379,8 +3509,8 @@ if (state.tab === "perp_options" && isOptionPrimary()) void refreshPoStrategyStatus(); }, 15000); setInterval(function () { - if (state.tab === "perp_options" && (state.posTab === "live" || state.posTab === "pending")) { - void loadActivePlans(); - } - }, 20000); + if (state.tab !== "perp_options") return; + if (state.posTab === "live") void loadLivePositions(); + else if (state.posTab === "plans" || state.posTab === "pending") void loadActivePlans(); + }, 8000); })(); diff --git a/lib/common/static/instance_theme.css b/lib/common/static/instance_theme.css index 58414f7..6f0c60f 100644 --- a/lib/common/static/instance_theme.css +++ b/lib/common/static/instance_theme.css @@ -4118,6 +4118,83 @@ html[data-theme="light"] .opt-be-dist-down { .hedge-plan-page-wrap .hp-po-pos-card .options-pos-pane { overflow: auto; } +.hedge-plan-page-wrap .hp-live-pos-list { + display: flex; + flex-direction: column; + gap: 12px; +} +.hedge-plan-page-wrap .hp-live-card { + padding: 12px 14px; + border-radius: 10px; + border: 1px solid rgba(255, 255, 255, 0.08); + background: rgba(255, 255, 255, 0.03); +} +.hedge-plan-page-wrap .hp-live-card-head { + display: flex; + justify-content: space-between; + gap: 8px; + align-items: baseline; + margin-bottom: 10px; + font-size: 0.88rem; +} +.hedge-plan-page-wrap .hp-live-legs { + display: grid; + grid-template-columns: 1fr; + gap: 10px; +} +@media (min-width: 720px) { + .hedge-plan-page-wrap .hp-live-legs { + grid-template-columns: 1fr 1fr; + } +} +.hedge-plan-page-wrap .hp-live-leg { + padding: 10px; + border-radius: 8px; + background: rgba(0, 0, 0, 0.18); + border: 1px solid rgba(255, 255, 255, 0.05); +} +.hedge-plan-page-wrap .hp-live-leg-title { + font-size: 0.78rem; + font-weight: 650; + color: #9ec0ff; + margin-bottom: 4px; +} +.hedge-plan-page-wrap .hp-live-leg code { + display: block; + font-size: 0.78rem; + word-break: break-all; + margin-bottom: 8px; + color: #c5d0ee; +} +.hedge-plan-page-wrap .hp-live-leg-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4px 10px; + font-size: 0.76rem; + color: #9aa4b2; +} +.hedge-plan-page-wrap .hp-live-leg-grid strong { + color: #e8ecf4; + font-weight: 600; +} +.hedge-plan-page-wrap .hp-live-combo { + display: flex; + justify-content: space-between; + align-items: baseline; + margin-top: 12px; + padding-top: 10px; + border-top: 1px solid rgba(255, 255, 255, 0.06); + font-size: 0.9rem; +} +.hedge-plan-page-wrap .hp-live-combo strong { + font-size: 1.05rem; +} +.hedge-plan-page-wrap .hp-live-actions { + margin-top: 10px; + display: flex; + gap: 8px; + flex-wrap: wrap; +} .hedge-plan-page-wrap .hp-po-order-dialog .hp-po-section-title { margin: 0 0 6px; font-size: 0.85rem; diff --git a/lib/common/static/options_panel.js b/lib/common/static/options_panel.js index 1d1e1e7..4ed8af5 100644 --- a/lib/common/static/options_panel.js +++ b/lib/common/static/options_panel.js @@ -1931,7 +1931,6 @@ '