Show hedge-plan scenario preview in a modal with start/cancel.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -35,6 +35,9 @@
|
||||
fundingUsdc: null,
|
||||
tradeBudgetUsdc: null,
|
||||
budgetBuffer: 0.95,
|
||||
previewOk: false,
|
||||
canStart: false,
|
||||
previewPlanType: null,
|
||||
};
|
||||
|
||||
function $(id) {
|
||||
@@ -169,13 +172,24 @@
|
||||
];
|
||||
if (gates.reasons && gates.reasons.length) parts.push(gates.reasons.join("; "));
|
||||
el.textContent = parts.join(" · ");
|
||||
const start = $("hp-start-btn");
|
||||
const startOo = $("hp-start-btn-oo");
|
||||
if ((gates.plan_type || state.mode) === "options_options") {
|
||||
if (startOo) startOo.disabled = !gates.can_start;
|
||||
} else {
|
||||
if (start) start.disabled = !gates.can_start;
|
||||
}
|
||||
state.canStart = !!gates.can_start;
|
||||
syncPreviewStartBtn();
|
||||
}
|
||||
|
||||
function syncPreviewStartBtn() {
|
||||
const start = $("hp-preview-start");
|
||||
if (!start) return;
|
||||
start.disabled = !(state.previewOk && state.canStart);
|
||||
}
|
||||
|
||||
function openPreviewModal() {
|
||||
const modal = $("hp-preview-modal");
|
||||
if (modal) modal.hidden = false;
|
||||
}
|
||||
|
||||
function closePreviewModal() {
|
||||
const modal = $("hp-preview-modal");
|
||||
if (modal) modal.hidden = true;
|
||||
}
|
||||
|
||||
function setOptionsBalance(chain) {
|
||||
@@ -851,8 +865,18 @@
|
||||
|
||||
async function runPreview() {
|
||||
const isOo = state.mode === "options_options";
|
||||
const tbody = $(isOo ? "hp-result-tbody-oo" : "hp-result-tbody");
|
||||
const summary = $(isOo ? "hp-summary-oo" : "hp-summary");
|
||||
const tbody = $("hp-result-tbody");
|
||||
const summary = $("hp-preview-summary");
|
||||
const midTh = $("hp-preview-mid-th");
|
||||
const title = $("hp-preview-title");
|
||||
state.previewOk = false;
|
||||
state.previewPlanType = isOo ? "options_options" : "perp_options";
|
||||
syncPreviewStartBtn();
|
||||
if (midTh) midTh.textContent = isOo ? "腿盈亏" : "永续/腿盈亏";
|
||||
if (title) title.textContent = isOo ? "情景测算 · 期期" : "情景测算 · 永期";
|
||||
if (summary) summary.textContent = "";
|
||||
if (tbody) tbody.innerHTML = '<tr><td colspan="6" class="muted">计算中…</td></tr>';
|
||||
openPreviewModal();
|
||||
try {
|
||||
let body;
|
||||
if (isOo) {
|
||||
@@ -949,7 +973,11 @@
|
||||
"</td>";
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
state.previewOk = true;
|
||||
syncPreviewStartBtn();
|
||||
} catch (e) {
|
||||
state.previewOk = false;
|
||||
syncPreviewStartBtn();
|
||||
if (tbody) tbody.innerHTML = '<tr><td colspan="6" class="err">' + (e.message || e) + "</td></tr>";
|
||||
if (summary) summary.textContent = "";
|
||||
}
|
||||
@@ -1075,14 +1103,19 @@
|
||||
state.mode = "options_options";
|
||||
void runPreview();
|
||||
});
|
||||
if ($("hp-start-btn"))
|
||||
$("hp-start-btn").addEventListener("click", function () {
|
||||
void startPlan("perp_options");
|
||||
if ($("hp-preview-cancel")) $("hp-preview-cancel").addEventListener("click", closePreviewModal);
|
||||
if ($("hp-preview-cancel-x")) $("hp-preview-cancel-x").addEventListener("click", closePreviewModal);
|
||||
if ($("hp-preview-start"))
|
||||
$("hp-preview-start").addEventListener("click", function () {
|
||||
const planType = state.previewPlanType || state.mode;
|
||||
void startPlan(planType, true);
|
||||
});
|
||||
if ($("hp-start-btn-oo"))
|
||||
$("hp-start-btn-oo").addEventListener("click", function () {
|
||||
void startPlan("options_options");
|
||||
const previewModal = $("hp-preview-modal");
|
||||
if (previewModal) {
|
||||
previewModal.addEventListener("click", function (ev) {
|
||||
if (ev.target === previewModal) closePreviewModal();
|
||||
});
|
||||
}
|
||||
if ($("hp-detail-close")) $("hp-detail-close").addEventListener("click", closeModal);
|
||||
const modal = $("hp-detail-modal");
|
||||
if (modal) {
|
||||
@@ -1442,8 +1475,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function startPlan(planType) {
|
||||
async function startPlan(planType, fromPreviewModal) {
|
||||
const isOo = planType === "options_options";
|
||||
const startBtn = $("hp-preview-start");
|
||||
try {
|
||||
let body;
|
||||
if (isOo) {
|
||||
@@ -1487,17 +1521,22 @@
|
||||
margin: state.market && state.market.full_margin_sizing && state.market.full_margin_sizing.margin_capital,
|
||||
};
|
||||
}
|
||||
if (!window.confirm("确认启动对冲计划并真实下单?\n(将按期权账户/合约账户分别下单)")) return;
|
||||
if (!fromPreviewModal) {
|
||||
if (!window.confirm("确认启动对冲计划并真实下单?\n(将按期权账户/合约账户分别下单)")) return;
|
||||
}
|
||||
if (startBtn) startBtn.disabled = true;
|
||||
const d = await apiJson("/api/hedge-plan/start", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
setGateLine(d.gates);
|
||||
closePreviewModal();
|
||||
alert("计划已启动 #" + (d.plan_id || "") + (d.dry_run ? " (dry_run)" : ""));
|
||||
void loadGates();
|
||||
} catch (e) {
|
||||
alert(e.message || String(e));
|
||||
syncPreviewStartBtn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3536,15 +3536,24 @@ html[data-theme="light"] .opt-be-dist-down {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.hedge-plan-page-wrap .hp-preview-card {
|
||||
margin-top: 0;
|
||||
clear: both;
|
||||
}
|
||||
.hedge-plan-page-wrap .hp-action-row {
|
||||
margin-top: 10px;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.hedge-plan-page-wrap .hp-preview-modal {
|
||||
width: min(96vw, 920px);
|
||||
}
|
||||
.hedge-plan-page-wrap .hp-preview-summary {
|
||||
margin: 0 0 10px;
|
||||
font-size: 0.84rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
.hedge-plan-page-wrap .hp-preview-actions {
|
||||
margin-top: 14px;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
.hedge-plan-page-wrap .hp-pick.active,
|
||||
.hedge-plan-page-wrap .opt-row-selected td {
|
||||
background: rgba(90, 140, 255, 0.18);
|
||||
|
||||
Reference in New Issue
Block a user