refactor(hedge): env-driven option-primary UI with grouped params

Move mode switch to HEDGE_PLAN_OPTION_PRIMARY, split left into capital/select/exit groups, and show perp quote above options with leverage auto-match.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-09 09:05:32 +08:00
parent c3c7243dd7
commit 20e0c2cb9f
8 changed files with 281 additions and 130 deletions
+66 -46
View File
@@ -37,7 +37,7 @@
ooCloseModeEnabled: root.getAttribute("data-oo-close-mode-enabled") !== "0",
ooCloseMode: "close_all",
direction: "long",
optionPrimary: true,
optionPrimary: root.getAttribute("data-option-primary") !== "0",
opLevTouched: false,
opRatioTouched: false,
tradingUsdc: null,
@@ -283,14 +283,9 @@
function syncOptionPrimaryUI() {
const on = isOptionPrimary();
document.querySelectorAll(".hp-po-mode").forEach(function (b) {
const v = b.getAttribute("data-option-primary") === "1";
b.classList.toggle("is-selected", v === on);
b.classList.toggle("active", v === on);
});
const ins = $("hp-po-fields-insurance");
const op = $("hp-po-fields-option-primary");
// 保险模式只显示开仓价/张数/止盈止损;以期权为主显示权利金等执行参数
// 保险模式只显示开仓价/张数/止盈止损;以期权为主显示三组参数(env 切换,页内不可改)
if (ins) {
ins.classList.toggle("hidden", on);
if (on) ins.setAttribute("hidden", "hidden");
@@ -303,48 +298,39 @@
else op.removeAttribute("hidden");
op.style.display = on ? "" : "none";
}
const otmBtn = document.querySelector(".hp-money-otm");
if (otmBtn) {
const insMoney = $("hp-po-ins-money");
if (insMoney) {
if (on) {
insMoney.setAttribute("hidden", "hidden");
insMoney.classList.add("hidden");
} else {
insMoney.removeAttribute("hidden");
insMoney.classList.remove("hidden");
}
}
document.querySelectorAll(".hp-money-otm").forEach(function (otmBtn) {
otmBtn.classList.toggle("hidden", !on);
if (!on) otmBtn.setAttribute("hidden", "hidden");
else otmBtn.removeAttribute("hidden");
}
});
if (!on && state.moneyFilter === "otm") {
state.moneyFilter = "itm";
syncMoneyUI();
}
if (on) applyOpDefaultsFromMoney(false);
const title = $("hp-po-card-title");
if (title) title.textContent = on ? "执行参数" : "永续";
const rightQ = $("hp-po-perp-quote-right");
if (rightQ) {
rightQ.classList.toggle("hidden", !on);
if (!on) rightQ.setAttribute("hidden", "hidden");
else rightQ.removeAttribute("hidden");
const badge = $("hp-po-mode-badge");
if (badge) {
badge.textContent = on ? "以期权为主" : "保险模式";
badge.classList.toggle("is-insurance", !on);
}
const title = $("hp-po-card-title");
if (title) title.textContent = "执行参数";
const dirLong = document.querySelector('.hp-po-dir[data-dir="long"]');
const dirShort = document.querySelector('.hp-po-dir[data-dir="short"]');
if (dirLong) dirLong.title = on ? "做多=买Call+永续空" : "做多永续";
if (dirShort) dirShort.title = on ? "做空=买Put+永续多" : "做空永续";
}
function setOptionPrimary(on, forceReload) {
const next = !!on;
const changed = next !== isOptionPrimary();
state.optionPrimary = next;
if (changed) {
state.opLevTouched = false;
state.opRatioTouched = false;
state.selected = null;
if ($("hp-sel-inst")) $("hp-sel-inst").textContent = "—";
}
syncOptionPrimaryUI();
if (!changed && !forceReload) return;
void loadMarket().then(function () {
return loadChain();
});
}
function hoursFromExpMs(expMs) {
const n = Number(expMs);
if (!n || Number.isNaN(n)) return null;
@@ -440,6 +426,37 @@
return (Math.round((k / a) * 10) / 10).toFixed(1) + "×";
}
/** 永期期权行情杠杆:指数÷卖一(与选约杠杆门一致). */
function calcIndexAskLeverage(ask) {
const idx = indexPx();
const a = Number(ask);
if (!(idx > 0) || !(a > 0)) return "—";
return (Math.round((idx / a) * 10) / 10).toFixed(1) + "×";
}
function clearPoSelection() {
state.selected = null;
if ($("hp-sel-inst")) $("hp-sel-inst").textContent = "—";
updatePremiumLine();
updatePerpPnlHint();
}
/** 以期权为主:按类型/间隔/杠杆自动匹配最近合约. */
function autoMatchPoOption(force) {
if (!isOptionPrimary()) return;
const want = optTypeForDirection(getDirection());
const sel = state.selected;
const stillOk =
!force &&
sel &&
String(sel.opt_type || "").toUpperCase() === want &&
matchesMoneyFilter(sel);
if (stillOk) return;
const c = pickClosestItmAtm(currentContracts("hp-exp-select"), want);
if (c) pickContract(c);
else clearPoSelection();
}
function findAtmStrikeFromRows(rows, idx) {
if (!rows.length) return null;
if (idx == null || Number.isNaN(Number(idx))) return rows[0].strike;
@@ -913,10 +930,6 @@
: "");
const q = $("hp-perp-quote");
if (q) q.innerHTML = quoteHtml;
const rightQ = $("hp-po-perp-quote-right");
if (rightQ && isOptionPrimary()) {
rightQ.innerHTML = "永续行情 · " + quoteHtml;
}
const contractsInput = $("hp-contracts");
if (contractsInput) {
const step = amtPrec <= 0 ? "1" : String(Math.pow(10, -amtPrec));
@@ -1130,7 +1143,8 @@
const prevInst = state.selected && state.selected.inst_id;
tbody.innerHTML = "";
if (!exp) {
tbody.innerHTML = '<tr><td colspan="5" class="muted">请选择到期日</td></tr>';
tbody.innerHTML = '<tr><td colspan="6" class="muted">请选择到期日</td></tr>';
if (isOptionPrimary()) clearPoSelection();
return;
}
const sameType = (exp.contracts || []).filter(function (c) {
@@ -1158,7 +1172,8 @@
(idx ? " · 指数 " + fmt(idx, 2) : "") +
" · 可换到期或点刷新链";
}
tbody.innerHTML = '<tr><td colspan="5" class="muted">' + hint + "</td></tr>";
tbody.innerHTML = '<tr><td colspan="6" class="muted">' + hint + "</td></tr>";
if (isOptionPrimary()) clearPoSelection();
return;
}
list.forEach(function (c) {
@@ -1171,6 +1186,8 @@
c.strike +
"</td><td>" +
moneynessBadge(c) +
'</td><td class="opt-chain-lev" title="指数÷卖一">' +
calcIndexAskLeverage(c.ask) +
'</td><td class="opt-px-sz">' +
fmtPxSz(c.ask, c.ask_sz, c.ask_estimated, c.tick_sz) +
'</td><td class="opt-px-sz">' +
@@ -1191,6 +1208,7 @@
pickContract(c);
});
});
autoMatchPoOption(false);
}
function updatePremiumLine() {
@@ -1729,7 +1747,7 @@
b.addEventListener("click", function () {
const m = b.getAttribute("data-money") || "itm";
if (m === "otm" && !isOptionPrimary()) {
alert("永期保险腿仅允许实值或平值;请先打开「以期权为主」");
alert("永期保险腿仅允许实值或平值;请在 env 将 HEDGE_PLAN_OPTION_PRIMARY=true");
return;
}
state.moneyFilter = m === "otm" ? "otm" : m === "atm" ? "atm" : "itm";
@@ -1738,11 +1756,6 @@
renderListStrikes();
});
});
document.querySelectorAll(".hp-po-mode").forEach(function (b) {
b.addEventListener("click", function () {
setOptionPrimary(b.getAttribute("data-option-primary") === "1", true);
});
});
if ($("hp-opt-leverage")) {
$("hp-opt-leverage").addEventListener("input", function () {
state.opLevTouched = true;
@@ -1789,6 +1802,13 @@
});
if ($("hp-recommend-opt")) {
$("hp-recommend-opt").addEventListener("click", function () {
if (isOptionPrimary()) {
autoMatchPoOption(true);
if (!state.selected) {
alert("当前选约条件下无匹配合约,请调整类型/间隔/杠杆或换到期");
}
return;
}
const want = optTypeForDirection(getDirection());
const c = pickClosestItmAtm(currentContracts("hp-exp-select"), want);
if (!c) {
+81 -2
View File
@@ -3470,6 +3470,34 @@ html[data-theme="light"] .opt-be-dist-down {
font-size: 0.74rem;
line-height: 1.4;
}
.hedge-plan-page-wrap .hp-po-mode-badge {
display: inline-block;
margin-right: 6px;
padding: 2px 8px;
border-radius: 6px;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.02em;
color: #c4b5fd;
background: rgba(139, 92, 246, 0.22);
border: 1px solid rgba(167, 139, 250, 0.35);
vertical-align: middle;
}
.hedge-plan-page-wrap .hp-po-mode-badge.is-insurance {
color: #93c5fd;
background: rgba(59, 130, 246, 0.18);
border-color: rgba(96, 165, 250, 0.35);
}
.hedge-plan-page-wrap .hp-po-section {
margin: 8px 0 10px;
}
.hedge-plan-page-wrap .hp-po-section-title {
margin: 0 0 6px;
font-size: 0.8rem;
font-weight: 650;
color: #c5cdd9;
letter-spacing: 0.02em;
}
.hedge-plan-page-wrap .hp-po-fields {
display: grid;
grid-template-columns: 1fr 1fr;
@@ -3480,11 +3508,53 @@ html[data-theme="light"] .opt-be-dist-down {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.06);
}
.hedge-plan-page-wrap .hp-po-fields--section {
margin: 0;
}
.hedge-plan-page-wrap .hp-po-field--type {
grid-column: 1 / -1;
}
.hedge-plan-page-wrap .hp-po-type-seg {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.hedge-plan-page-wrap .hp-po-right-stack {
display: flex;
flex-direction: column;
gap: 12px;
min-width: 0;
min-height: 0;
}
.hedge-plan-page-wrap .hp-po-quote-head {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 4px;
}
.hedge-plan-page-wrap .hp-po-ins-money {
display: inline-flex;
flex-wrap: wrap;
gap: 6px;
}
.hedge-plan-page-wrap .hp-po-ins-money[hidden],
.hedge-plan-page-wrap .hp-po-ins-money.hidden {
display: none !important;
}
/* display:grid 会盖掉 [hidden];模式切换必须显式 none */
.hedge-plan-page-wrap .hp-po-fields.hidden,
.hedge-plan-page-wrap .hp-po-fields[hidden] {
.hedge-plan-page-wrap .hp-po-fields[hidden],
.hedge-plan-page-wrap #hp-po-fields-option-primary.hidden,
.hedge-plan-page-wrap #hp-po-fields-option-primary[hidden] {
display: none !important;
}
.hedge-plan-page-wrap .hp-strike-table-wrap--6 {
max-height: 280px;
min-height: 200px;
overflow-y: auto;
margin-top: 4px;
flex: 1 1 auto;
}
.hedge-plan-page-wrap .hp-po-field {
display: flex;
flex-direction: column;
@@ -3731,6 +3801,7 @@ html[data-theme="light"] .opt-be-dist-down {
margin-top: 4px;
flex: 0 0 auto;
}
.hedge-plan-page-wrap .opt-chain-lev,
.hedge-plan-page-wrap .hp-oo-table-wrap .opt-chain-lev {
text-align: center;
white-space: nowrap;
@@ -3747,12 +3818,20 @@ html[data-theme="light"] .opt-be-dist-down {
align-items: stretch;
margin-bottom: 28px;
}
.hedge-plan-page-wrap .options-dual-grid > .card {
.hedge-plan-page-wrap .options-dual-grid > .card,
.hedge-plan-page-wrap .hp-po-right-stack > .card {
height: 100%;
min-height: 0;
display: flex;
flex-direction: column;
}
.hedge-plan-page-wrap .hp-po-right-stack > .hp-po-perp-quote-card {
height: auto;
flex: 0 0 auto;
}
.hedge-plan-page-wrap .hp-po-right-stack > .hp-opt-card {
flex: 1 1 auto;
}
.hedge-plan-page-wrap .hp-action-row {
margin-top: 10px;
gap: 8px;
+5
View File
@@ -96,6 +96,7 @@ HOT_RELOAD_EXACT = frozenset({
"OKX_TRADE_MODE",
"MAX_ACTIVE_HEDGE_PLANS",
"HEDGE_PLAN_LIVE_ORDER",
"HEDGE_PLAN_OPTION_PRIMARY",
"HEDGE_PLAN_OPEN_ORDER",
"HEDGE_PLAN_ON_PERP_SL_CLOSE_OPTIONS",
"HEDGE_PLAN_ON_PERP_TP_CLOSE_OPTIONS",
@@ -154,6 +155,10 @@ SELECT_OPTIONS: dict[str, tuple[tuple[str, str], ...]] = {
("perp_options", "永期对冲"),
("options_options", "期期对冲"),
),
"HEDGE_PLAN_OPTION_PRIMARY": (
("true", "以期权为主"),
("false", "保险模式"),
),
}
_SELECT_ALIASES: dict[str, dict[str, str]] = {
+6
View File
@@ -186,6 +186,11 @@ _HEDGE_COMMON_FIELDS: list[tuple[str, str, str]] = [
]
_HEDGE_PO_FIELDS: list[tuple[str, str, str]] = [
(
"HEDGE_PLAN_OPTION_PRIMARY",
"永期模式(以期权为主/保险)",
"默认 true=以期权为主;false=保险模式;页面标题前显示标识,不可在页内切换",
),
("HEDGE_PLAN_OPEN_ORDER", "永期开仓顺序", "options_first 或 perp_first"),
("HEDGE_PLAN_ON_PERP_SL_CLOSE_OPTIONS", "永期止损后强制平期权", "保护机制,建议保持 true"),
("HEDGE_PLAN_ON_PERP_TP_CLOSE_OPTIONS", "永期止盈后强制平期权", "默认 false,保险腿不平"),
@@ -263,6 +268,7 @@ _RUNTIME_ENV_DEFAULTS: dict[str, str] = {
"HEDGE_PLAN_OO_BIAS_SPLIT_BY": "budget",
"HEDGE_PLAN_OO_BIAS_RATIO": "0.7",
"HEDGE_PLAN_BUDGET_BUFFER": "0.95",
"HEDGE_PLAN_OPTION_PRIMARY": "true",
"HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE": "true",
"HEDGE_PLAN_MANUAL_COMPLETE_ON_PARTIAL": "true",
}
+113 -78
View File
@@ -5,6 +5,7 @@
data-show-perp="{{ '1' if hedge_plan_show_perp_options else '0' }}"
data-show-oo="{{ '1' if hedge_plan_show_options_options else '0' }}"
data-oo-close-mode-enabled="{{ '1' if hedge_plan_oo_close_mode_enabled else '0' }}"
data-option-primary="{{ '1' if hedge_plan_option_primary|default(true) else '0' }}"
data-budget-buffer="{{ hedge_plan_budget_buffer | default(0.95) }}"
data-sizing-mode="{{ position_sizing_mode | default('risk') }}"
data-is-full-margin="{{ '1' if position_sizing_mode == 'full_margin' else '0' }}">
@@ -43,31 +44,31 @@
<div id="hp-tab-perp_options" class="hp-tab-panel" role="tabpanel">
<div class="options-dual-grid" id="hp-po-layout">
<div class="card hp-po-perp-card">
<h2><span id="hp-po-card-title">执行参数</span> · <span id="hp-perp-uly-label">ETH</span> <span class="muted hp-acct-tag" id="hp-perp-acct-tag">合约账户</span></h2>
<h2>
<span id="hp-po-mode-badge" class="hp-po-mode-badge">以期权为主</span>
<span id="hp-po-card-title">执行参数</span>
· <span id="hp-perp-uly-label">ETH</span>
<span class="muted hp-acct-tag" id="hp-perp-acct-tag">合约账户</span>
</h2>
<details class="tip-collapse hp-rule-collapse">
<summary class="tip-collapse-summary">规则说明</summary>
<div class="tip-collapse-body rule-tip">
<p><strong>账户</strong>:永续腿走<strong>合约账户</strong>(USDT);期权腿走<strong>期权账户</strong>(USDC)。两账户分开下单、资金不互通。</p>
<p><strong>保险模式</strong>(开关关):做多配 Put、做空配 Call;左填开仓/止盈止损;仅实值/平值;交易所 TP/SL 出场</p>
<p><strong>以期权为主</strong>(开关开):做多买 Call+永续空、做空买 Put+永续多;左填权利金/杠杆/比例/目标点数;开仓先期权后市价永续;期权目标验买一且净利&gt;0后双平;永续目标只平永续、期权持有至到期</p>
<p><strong>模式</strong>:在 env <code>HEDGE_PLAN_OPTION_PRIMARY</code> 切换(true=以期权为主 / false=保险模式);标题前标识当前模式</p>
<p><strong>保险模式</strong>:做多配 Put、做空配 Call;左填开仓/止盈止损;仅实值/平值;交易所 TP/SL 出场</p>
<p><strong>以期权为主</strong>:做多买 Call+永续空、做空买 Put+永续多;左分资金/选约/出场三组;右侧上永续下期权(含杠杆),按类型自动匹配;开仓先期权后市价永续。</p>
</div>
</details>
<div class="form-row hp-uly-row">
<button type="button" class="btn-secondary hp-uly-btn active" data-uly="ETH">ETH</button>
<button type="button" class="btn-secondary hp-uly-btn" data-uly="BTC">BTC</button>
</div>
<div class="form-row hp-po-mode-row" role="group" aria-label="永期模式">
<button type="button" class="btn-secondary hp-po-mode" data-option-primary="0">保险模式</button>
<button type="button" class="btn-secondary hp-po-mode is-selected" data-option-primary="1">以期权为主</button>
</div>
<div class="hp-po-top">
<div class="hp-oo-seg hp-po-dir-seg" role="group" aria-label="方向">
<button type="button" class="btn-secondary hp-po-dir is-selected" data-dir="long" title="做多=买Call+永续空"><span class="hp-oo-check" aria-hidden="true"></span>做多</button>
<button type="button" class="btn-secondary hp-po-dir" data-dir="short" title="做空=买Put+永续多"><span class="hp-oo-check" aria-hidden="true"></span>做空</button>
</div>
<span id="hp-po-mark" class="hp-po-mark" aria-live="polite">标记 —</span>
</div>
<p id="hp-perp-quote" class="muted hp-po-meta">加载中…</p>
<div class="hp-po-fields hidden" id="hp-po-fields-insurance" hidden>
<label class="hp-po-field">
<span class="hp-po-field-lab">开仓价 <em>USDT</em></span>
@@ -86,81 +87,115 @@
<input type="number" step="any" id="hp-sl" placeholder="保护价" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
</div>
<div class="hp-po-fields" id="hp-po-fields-option-primary">
<label class="hp-po-field">
<span class="hp-po-field-lab">权利金 <em>USDC</em></span>
<input type="number" step="any" id="hp-premium-budget" placeholder="预算(执行×0.95)" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">永续杠杆</span>
<input type="number" step="1" id="hp-perp-leverage" value="100" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权杠杆</span>
<input type="number" step="1" id="hp-opt-leverage" value="100" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权:永续比例</span>
<input type="number" step="any" id="hp-opt-perp-ratio" value="2" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">到期时间 <em>最短h</em></span>
<input type="number" step="1" id="hp-min-hours" value="36" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权间隔 <em></em></span>
<input type="number" step="any" id="hp-strike-interval" value="15" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权目标位 <em>相对K</em></span>
<input type="number" step="any" id="hp-opt-target-pts" placeholder="点数" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">永续目标位 <em>相对K</em></span>
<input type="number" step="any" id="hp-perp-target-pts" placeholder="点数" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<div id="hp-po-fields-option-primary">
<section class="hp-po-section" aria-labelledby="hp-po-sec-capital">
<h3 id="hp-po-sec-capital" class="hp-po-section-title">资金与杠杆配置</h3>
<div class="hp-po-fields hp-po-fields--section">
<label class="hp-po-field">
<span class="hp-po-field-lab">权利金 <em>USDC</em></span>
<input type="number" step="any" id="hp-premium-budget" placeholder="预算(执行×0.95)" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">永续杠杆</span>
<input type="number" step="1" id="hp-perp-leverage" value="100" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权杠杆</span>
<input type="number" step="1" id="hp-opt-leverage" value="100" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
</div>
</section>
<section class="hp-po-section" aria-labelledby="hp-po-sec-select">
<h3 id="hp-po-sec-select" class="hp-po-section-title">选约条件</h3>
<div class="hp-po-fields hp-po-fields--section">
<label class="hp-po-field">
<span class="hp-po-field-lab">到期时间 <em>最短h</em></span>
<input type="number" step="1" id="hp-min-hours" value="36" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权间隔 <em></em></span>
<input type="number" step="any" id="hp-strike-interval" value="15" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<div class="hp-po-field hp-po-field--type">
<span class="hp-po-field-lab">类型</span>
<div class="hp-oo-seg hp-po-type-seg" role="group" aria-label="虚实值类型">
<button type="button" class="btn-secondary hp-money-btn active" data-money="itm" title="实值+平值"><span class="hp-oo-check" aria-hidden="true"></span>实值/平值</button>
<button type="button" class="btn-secondary hp-money-btn" data-money="atm" title="仅平值"><span class="hp-oo-check" aria-hidden="true"></span>仅平值</button>
<button type="button" class="btn-secondary hp-money-btn hp-money-otm" data-money="otm" title="虚值"><span class="hp-oo-check" aria-hidden="true"></span>虚值</button>
</div>
</div>
<label class="hp-po-field">
<span class="hp-po-field-lab">比例 <em>期权:永续</em></span>
<input type="number" step="any" id="hp-opt-perp-ratio" value="2" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
</div>
</section>
<section class="hp-po-section" aria-labelledby="hp-po-sec-exit">
<h3 id="hp-po-sec-exit" class="hp-po-section-title">出场条件</h3>
<div class="hp-po-fields hp-po-fields--section">
<label class="hp-po-field">
<span class="hp-po-field-lab">期权目标位 <em>相对K</em></span>
<input type="number" step="any" id="hp-opt-target-pts" placeholder="点数" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">永续目标位 <em>相对K</em></span>
<input type="number" step="any" id="hp-perp-target-pts" placeholder="点数" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
</div>
</section>
</div>
<div class="hp-po-summary">
<div id="hp-perp-pnl-line" class="hp-po-pnl"></div>
<div id="hp-sizing-line" class="muted hp-po-sizing"></div>
</div>
</div>
<div class="card hp-opt-card">
<h2>期权 · <span id="hp-opt-type-label">Call</span> <span class="muted hp-acct-tag" id="hp-opt-acct-tag">期权账户</span></h2>
<p id="hp-po-perp-quote-right" class="muted hp-po-meta"></p>
<div class="form-row hp-opt-toolbar hp-po-opt-toolbar">
<select id="hp-exp-select"><option value="">选择到期日</option></select>
<button type="button" class="btn-secondary hp-money-btn active" data-money="itm" title="实值+平值">实值/平值</button>
<button type="button" class="btn-secondary hp-money-btn" data-money="atm" title="仅平值">仅平值</button>
<button type="button" class="btn-secondary hp-money-btn hp-money-otm" data-money="otm" title="虚值">虚值</button>
<button type="button" class="btn-secondary" id="hp-recommend-opt" title="推荐选约">推荐</button>
<button type="button" class="btn-secondary" id="hp-load-chain">刷新链</button>
<span id="hp-index-line" class="hp-po-index" aria-live="polite">指数 —</span>
<div class="hp-po-right-stack">
<div class="card hp-po-perp-quote-card">
<h2>永续行情 <span class="muted hp-acct-tag">合约账户</span></h2>
<div class="hp-po-quote-head">
<span id="hp-po-mark" class="hp-po-mark" aria-live="polite">标记 —</span>
</div>
<p id="hp-perp-quote" class="muted hp-po-meta">加载中…</p>
<p id="hp-po-perp-quote-right" class="muted hp-po-meta" hidden></p>
</div>
<div class="options-strike-table-wrap hp-strike-table-wrap--5">
<table class="options-strike-table" id="hp-strike-table">
<thead>
<tr>
<th>行权价</th>
<th></th>
<th>卖一/张</th>
<th>买一/张</th>
<th>操作</th>
</tr>
</thead>
<tbody id="hp-strike-tbody">
<tr><td colspan="5" class="muted">请刷新期权链</td></tr>
</tbody>
</table>
</div>
<div class="form-row hp-pick-row">
<label>已选 <code id="hp-sel-inst"></code></label>
<label>张数 <span class="hp-unit">期权张</span> <input type="number" step="1" min="1" id="hp-sheets" value="1" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></label>
<span class="muted" id="hp-premium-line"></span>
</div>
<div id="hp-opt-bal-line" class="muted hp-po-meta hp-opt-bal-line"></div>
<div class="form-row hp-action-row">
<button type="button" class="primary" id="hp-preview-btn">计算</button>
<div class="card hp-opt-card">
<h2>期权 · <span id="hp-opt-type-label">Call</span> <span class="muted hp-acct-tag" id="hp-opt-acct-tag">期权账户</span></h2>
<div class="form-row hp-opt-toolbar hp-po-opt-toolbar">
<select id="hp-exp-select"><option value="">选择到期日</option></select>
<span class="hp-po-ins-money" id="hp-po-ins-money" hidden>
<button type="button" class="btn-secondary hp-money-btn active" data-money="itm" title="实值+平值">值/平</button>
<button type="button" class="btn-secondary hp-money-btn" data-money="atm" title="仅平值">仅平值</button>
</span>
<button type="button" class="btn-secondary" id="hp-recommend-opt" title="按当前类型自动匹配最近合约">自动匹配</button>
<button type="button" class="btn-secondary" id="hp-load-chain">刷新链</button>
<span id="hp-index-line" class="hp-po-index" aria-live="polite">指数 —</span>
</div>
<div class="options-strike-table-wrap hp-strike-table-wrap--6">
<table class="options-strike-table" id="hp-strike-table">
<thead>
<tr>
<th>行权价</th>
<th>实虚值</th>
<th title="指数÷卖一">杠杆</th>
<th>卖一/张</th>
<th>买一/张</th>
<th>操作</th>
</tr>
</thead>
<tbody id="hp-strike-tbody">
<tr><td colspan="6" class="muted">请刷新期权链</td></tr>
</tbody>
</table>
</div>
<div class="form-row hp-pick-row">
<label>已选 <code id="hp-sel-inst"></code></label>
<label>张数 <span class="hp-unit">期权张</span> <input type="number" step="1" min="1" id="hp-sheets" value="1" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" /></label>
<span class="muted" id="hp-premium-line"></span>
</div>
<div id="hp-opt-bal-line" class="muted hp-po-meta hp-opt-bal-line"></div>
<div class="form-row hp-action-row">
<button type="button" class="primary" id="hp-preview-btn">计算</button>
</div>
</div>
</div>
</div>
@@ -368,4 +403,4 @@
</div>
</div>
</div>
<script src="/static/hedge_plan.js?v=40"></script>
<script src="/static/hedge_plan.js?v=41"></script>