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:
+269
-180
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user