Hide perp-option settings when option-option hedge is selected.

Show OO selection and reward-ratio fields in their tabs instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-07 16:21:36 +08:00
parent 8d3c181246
commit cd88fa5d83
+269 -180
View File
@@ -368,10 +368,12 @@ export default function SettingsPage() {
setStratOk("");
setErr("");
const isLive = mode === "LIVE";
const oo = hedgeMode === "option_option";
try {
const body: Record<string, unknown> = {
fee_rate: fee,
exit_mode: sizingMode === "risk_based" ? "fixed_usdt" : exitMode,
exit_mode:
oo || sizingMode === "risk_based" ? "fixed_usdt" : exitMode,
premium_exit_multiple: premMult,
rest_seconds: rest,
live_order_interval_sec: orderInterval,
@@ -381,16 +383,16 @@ export default function SettingsPage() {
perp_margin_mode: perpMarginMode,
min_option_hours: minHours,
min_option_leverage: minOptLev,
atm_open_offset_enabled: atmOffOn,
atm_open_offset_enabled: oo ? false : atmOffOn,
max_atm_open_offset: maxAtmOff,
fixed_direction_enabled: fixedDirOn,
fixed_direction_enabled: oo ? false : fixedDirOn,
fixed_perp_side: fixedPerpSide,
close_bid_mark_max_pct: closeDevPct,
residual_min_premium_pct: residualMinPremPct,
show_manual_trade_buttons: showManualTrade,
sizing_mode: sizingMode,
sizing_mode: oo ? "risk_based" : sizingMode,
risk_leverage_basis: riskLeverageBasis,
risk_loss_mode: riskLossMode,
risk_loss_mode: oo ? "percent" : riskLossMode,
risk_loss_pct: riskLossPct,
risk_loss_usdt: riskLossUsdt,
risk_capital_source: riskCapitalSource,
@@ -399,8 +401,8 @@ export default function SettingsPage() {
risk_option_unit: riskOptUnit,
risk_exit_unit: riskExitUnit,
martingale_enabled:
sizingMode === "risk_based" &&
riskLossMode === "percent" &&
(oo || sizingMode === "risk_based") &&
(oo || riskLossMode === "percent") &&
riskLossPct <= 3 &&
martingaleOn,
martingale_start_after_loss_days: martingaleStartAfter,
@@ -543,6 +545,8 @@ export default function SettingsPage() {
}
}
const isOo = hedgeMode === "option_option";
return (
<div className="settings-page">
<h2 style={{ marginTop: 0 }}></h2>
@@ -676,34 +680,40 @@ export default function SettingsPage() {
/>
</div>
) : null}
<div className="field">
<label htmlFor="lev"></label>
<input
id="lev"
className="mono"
type="number"
step="1"
min="1"
value={leverage}
onChange={(e) => setLeverage(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="perpMm"></label>
<select
id="perpMm"
className="mono"
value={perpMarginMode}
onChange={(e) =>
setPerpMarginMode(
e.target.value === "isolated" ? "isolated" : "cross",
)
}
>
<option value="cross"></option>
<option value="isolated"></option>
</select>
</div>
{!isOo ? (
<>
<div className="field">
<label htmlFor="lev"></label>
<input
id="lev"
className="mono"
type="number"
step="1"
min="1"
value={leverage}
onChange={(e) => setLeverage(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="perpMm"></label>
<select
id="perpMm"
className="mono"
value={perpMarginMode}
onChange={(e) =>
setPerpMarginMode(
e.target.value === "isolated"
? "isolated"
: "cross",
)
}
>
<option value="cross"></option>
<option value="isolated"></option>
</select>
</div>
</>
) : null}
<div className="field">
<label htmlFor="hedgeMode"></label>
<select
@@ -730,145 +740,110 @@ export default function SettingsPage() {
N Call/Put
</p>
</div>
{hedgeMode === "option_option" ? (
<>
<div className="field">
<label htmlFor="ooAmp">%</label>
<input
id="ooAmp"
className="mono"
type="number"
step="0.1"
min="0.1"
value={ooAmpPct}
onChange={(e) => setOoAmpPct(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="ooAmpH"></label>
<input
id="ooAmpH"
className="mono"
type="number"
step="1"
min="1"
value={ooAmpHours}
onChange={(e) =>
setOoAmpHours(Number(e.target.value))
}
/>
</div>
<div className="field">
<label htmlFor="ooMinH"></label>
<input
id="ooMinH"
className="mono"
type="number"
step="1"
min="1"
value={ooMinHours}
onChange={(e) =>
setOoMinHours(Number(e.target.value))
}
/>
</div>
<div className="field">
<label htmlFor="ooLev"></label>
<input
id="ooLev"
className="mono"
type="number"
step="1"
min="1"
value={ooMinLev}
onChange={(e) => setOoMinLev(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="ooRR"></label>
<input
id="ooRR"
className="mono"
type="number"
step="0.1"
min="0.5"
value={ooRewardRatio}
onChange={(e) =>
setOoRewardRatio(Number(e.target.value))
}
/>
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
= × 100U 2
200U 1:1
</p>
</div>
</>
{isOo ? (
<div className="field">
<label htmlFor="ooRR"></label>
<input
id="ooRR"
className="mono"
type="number"
step="0.1"
min="0.5"
value={ooRewardRatio}
onChange={(e) =>
setOoRewardRatio(Number(e.target.value))
}
/>
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
= × 100U 2
200U 1:1 /
</p>
</div>
) : null}
<div className="field">
<label htmlFor="sizingMode"></label>
<select
id="sizingMode"
className="mono"
value={sizingMode}
disabled={hedgeMode === "option_option"}
onChange={(e) =>
setSizingMode(
e.target.value === "risk_based"
? "risk_based"
: "manual",
)
}
>
<option value="manual"> ETH </option>
<option value="risk_based"></option>
</select>
</div>
{sizingMode === "risk_based" ? (
{!isOo ? (
<div className="field">
<label htmlFor="sizingMode"></label>
<select
id="sizingMode"
className="mono"
value={sizingMode}
onChange={(e) =>
setSizingMode(
e.target.value === "risk_based"
? "risk_based"
: "manual",
)
}
>
<option value="manual"> ETH </option>
<option value="risk_based">
</option>
</select>
</div>
) : (
<div className="field">
<label></label>
<div className="mono" style={{ fontSize: 13 }}>
· Call/Put 1:1
</div>
</div>
)}
{sizingMode === "risk_based" || isOo ? (
<>
<div className="field">
<label htmlFor="riskLevBasis"></label>
<select
id="riskLevBasis"
className="mono"
value={riskLeverageBasis}
onChange={(e) =>
setRiskLeverageBasis(
e.target.value === "actual"
? "actual"
: "selection",
)
}
>
<option value="selection">
</option>
<option value="actual"></option>
</select>
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
÷ k便
便 k
</p>
</div>
<div className="field">
<label htmlFor="riskLossMode"></label>
<select
id="riskLossMode"
className="mono"
value={riskLossMode}
onChange={(e) => {
const mode =
e.target.value === "absolute"
? "absolute"
: "percent";
setRiskLossMode(mode);
if (mode !== "percent") setMartingaleOn(false);
}}
>
<option value="percent"> %</option>
<option value="absolute">USDT</option>
</select>
</div>
{riskLossMode === "percent" ? (
{!isOo ? (
<div className="field">
<label htmlFor="riskLevBasis">
</label>
<select
id="riskLevBasis"
className="mono"
value={riskLeverageBasis}
onChange={(e) =>
setRiskLeverageBasis(
e.target.value === "actual"
? "actual"
: "selection",
)
}
>
<option value="selection">
</option>
<option value="actual"></option>
</select>
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
÷
k便
便 k
</p>
</div>
) : null}
{!isOo ? (
<div className="field">
<label htmlFor="riskLossMode"></label>
<select
id="riskLossMode"
className="mono"
value={riskLossMode}
onChange={(e) => {
const mode =
e.target.value === "absolute"
? "absolute"
: "percent";
setRiskLossMode(mode);
if (mode !== "percent") setMartingaleOn(false);
}}
>
<option value="percent">
%
</option>
<option value="absolute">USDT</option>
</select>
</div>
) : null}
{isOo || riskLossMode === "percent" ? (
<>
<div className="field">
<label htmlFor="riskCapSrc"></label>
@@ -1072,10 +1047,18 @@ export default function SettingsPage() {
: mg != null && mg.enabled === true
? ` · 倍投待命(连亏${Number(mg.loss_days) || 0}天)`
: "";
return `k=${pk ?? "—"} · 预算=${budS}U · 估亏=${mxS}U · 永续=${perp ?? "—"} · 期权=${opt ?? "—"} · 出场=${exit ?? "—"}${basisS}${mgS}`;
return isOo
? `预算=${budS}U · 估亏=${mxS}U · 出场=预算×${ooRewardRatio}${
riskPreview.option_qty_eth != null
? ` · 单腿≈${riskPreview.option_qty_eth}ETH`
: ""
}${mgS}`
: `k=${pk ?? "—"} · 预算=${budS}U · 估亏=${mxS}U · 永续=${perp ?? "—"} · 期权=${opt ?? "—"} · 出场=${exit ?? "—"}${basisS}${mgS}`;
})()}
</div>
</div>
{!isOo ? (
<>
<div className="field">
<label htmlFor="riskPerpU">k=1</label>
<input
@@ -1172,8 +1155,12 @@ export default function SettingsPage() {
}}
/>
</div>
</>
) : null}
</>
) : null}
{!isOo ? (
<>
<div className="field">
<label htmlFor="perp">
ETH
@@ -1220,6 +1207,8 @@ export default function SettingsPage() {
onChange={(e) => setOptQty(Number(e.target.value))}
/>
</div>
</>
) : null}
</div>
</section>
) : null}
@@ -1228,6 +1217,66 @@ export default function SettingsPage() {
<section className="settings-section">
<h3></h3>
<div className="settings-fields">
{isOo ? (
<>
<div className="field">
<label htmlFor="ooAmp">%</label>
<input
id="ooAmp"
className="mono"
type="number"
step="0.1"
min="0.1"
value={ooAmpPct}
onChange={(e) => setOoAmpPct(Number(e.target.value))}
/>
</div>
<div className="field">
<label htmlFor="ooAmpH"></label>
<input
id="ooAmpH"
className="mono"
type="number"
step="1"
min="1"
value={ooAmpHours}
onChange={(e) =>
setOoAmpHours(Number(e.target.value))
}
/>
</div>
<div className="field">
<label htmlFor="ooMinH"></label>
<input
id="ooMinH"
className="mono"
type="number"
step="1"
min="1"
value={ooMinHours}
onChange={(e) =>
setOoMinHours(Number(e.target.value))
}
/>
</div>
<div className="field">
<label htmlFor="ooLev"></label>
<input
id="ooLev"
className="mono"
type="number"
step="1"
min="1"
value={ooMinLev}
onChange={(e) => setOoMinLev(Number(e.target.value))}
/>
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
Call Put 使 ATM/
</p>
</div>
</>
) : (
<>
<div className="field">
<label htmlFor="hours"></label>
<input
@@ -1309,6 +1358,8 @@ export default function SettingsPage() {
onChange={(e) => setMaxAtmOff(Number(e.target.value))}
/>
</div>
</>
)}
</div>
</section>
) : null}
@@ -1317,6 +1368,26 @@ export default function SettingsPage() {
<section className="settings-section">
<h3></h3>
<div className="settings-fields">
{isOo ? (
<div className="field">
<label htmlFor="ooRRExit"></label>
<input
id="ooRRExit"
className="mono"
type="number"
step="0.1"
min="0.5"
value={ooRewardRatio}
onChange={(e) =>
setOoRewardRatio(Number(e.target.value))
}
/>
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
×
</p>
</div>
) : (
<>
<div className="field">
<label htmlFor="exitMode"></label>
<select
@@ -1387,6 +1458,8 @@ export default function SettingsPage() {
onChange={(e) => setPremMult(Number(e.target.value))}
/>
</div>
)}
</>
)}
<div className="field">
<label htmlFor="closeDev">/%</label>
@@ -1402,7 +1475,9 @@ export default function SettingsPage() {
</div>
<div className="field">
<label htmlFor="residualPrem">
/ %
{isOo
? "亏损腿残留回收:当前权利金 / 初始权利金 ≥(%)"
: "残留期权回收:当前权利金 / 初始权利金 ≥(%)"}
</label>
<input
id="residualPrem"
@@ -1532,13 +1607,25 @@ export default function SettingsPage() {
10000
</li>
) : null}
<li>
/OKX
/cash
</li>
{isOo ? (
<li>
+ % 1:1 使//k
</li>
) : (
<li>
/OKX
/cash
</li>
)}
</>
) : null}
{stratSub === "select" ? (
isOo ? (
<li>
Call
Put
</li>
) : (
<>
<li>
Put
@@ -1552,6 +1639,7 @@ export default function SettingsPage() {
ATM
</li>
</>
)
) : null}
{stratSub === "exit" ? (
<>
@@ -1560,8 +1648,9 @@ export default function SettingsPage() {
LIVE
</li>
<li>
IOC 20%
{isOo
? "残留回收:达标只平盈利腿后,亏损腿权利金回升到初始比例及以上时可尝试平仓;否则到期结算。"
: "残留期权回收比例:只平永续后,当买一权利金回升到初始权利金的该比例及以上时,按最新买一 IOC 限价卖掉归档期权(不扫市价);默认 20%。未达标或未完全成交则等到下次巡检或到期结算。"}
</li>
</>
) : null}