Add option-option hedge mode with SIM/LIVE parity.
Mutual hedge_mode, amplitude OTM selection, 1:1 risk sizing, win-leg/full close, dual audits and docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -108,6 +108,14 @@ export default function SettingsPage() {
|
||||
const [martingaleOn, setMartingaleOn] = useState(false);
|
||||
const [martingaleStartAfter, setMartingaleStartAfter] = useState(2);
|
||||
const [martingaleMaxDoubles, setMartingaleMaxDoubles] = useState(3);
|
||||
const [hedgeMode, setHedgeMode] = useState<"perp_option" | "option_option">(
|
||||
"perp_option",
|
||||
);
|
||||
const [ooAmpPct, setOoAmpPct] = useState(1.5);
|
||||
const [ooAmpHours, setOoAmpHours] = useState(12);
|
||||
const [ooMinHours, setOoMinHours] = useState(24);
|
||||
const [ooMinLev, setOoMinLev] = useState(200);
|
||||
const [ooRewardRatio, setOoRewardRatio] = useState(2);
|
||||
const [riskPreview, setRiskPreview] = useState<Record<string, unknown> | null>(
|
||||
null,
|
||||
);
|
||||
@@ -221,6 +229,14 @@ export default function SettingsPage() {
|
||||
setMartingaleOn(s.martingale_enabled === true);
|
||||
setMartingaleStartAfter(s.martingale_start_after_loss_days ?? 2);
|
||||
setMartingaleMaxDoubles(s.martingale_max_doubles ?? 3);
|
||||
setHedgeMode(
|
||||
s.hedge_mode === "option_option" ? "option_option" : "perp_option",
|
||||
);
|
||||
setOoAmpPct(s.oo_amplitude_pct ?? 1.5);
|
||||
setOoAmpHours(s.oo_amplitude_hours ?? 12);
|
||||
setOoMinHours(s.oo_min_option_hours ?? 24);
|
||||
setOoMinLev(s.oo_min_leverage ?? 200);
|
||||
setOoRewardRatio(s.oo_reward_ratio ?? 2);
|
||||
setRiskPreview(
|
||||
s.risk_sizing_preview && typeof s.risk_sizing_preview === "object"
|
||||
? s.risk_sizing_preview
|
||||
@@ -389,6 +405,12 @@ export default function SettingsPage() {
|
||||
martingaleOn,
|
||||
martingale_start_after_loss_days: martingaleStartAfter,
|
||||
martingale_max_doubles: martingaleMaxDoubles,
|
||||
hedge_mode: hedgeMode,
|
||||
oo_amplitude_pct: ooAmpPct,
|
||||
oo_amplitude_hours: ooAmpHours,
|
||||
oo_min_option_hours: ooMinHours,
|
||||
oo_min_leverage: ooMinLev,
|
||||
oo_reward_ratio: ooRewardRatio,
|
||||
exchange,
|
||||
};
|
||||
// 以损定仓不提交手填名义/出场,避免禁用输入框脏值导致 422
|
||||
@@ -682,12 +704,113 @@ export default function SettingsPage() {
|
||||
<option value="isolated">逐仓</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label htmlFor="hedgeMode">对冲模式</label>
|
||||
<select
|
||||
id="hedgeMode"
|
||||
className="mono"
|
||||
value={hedgeMode}
|
||||
onChange={(e) => {
|
||||
const v =
|
||||
e.target.value === "option_option"
|
||||
? "option_option"
|
||||
: "perp_option";
|
||||
setHedgeMode(v);
|
||||
if (v === "option_option") {
|
||||
setSizingMode("risk_based");
|
||||
setRiskLossMode("percent");
|
||||
setFixedDirOn(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<option value="perp_option">永期对冲(永续+期权)</option>
|
||||
<option value="option_option">期期对冲(双期权)</option>
|
||||
</select>
|
||||
<p className="hint" style={{ margin: "0.35rem 0 0" }}>
|
||||
二选一。期期:近 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>
|
||||
</>
|
||||
) : 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"
|
||||
|
||||
Reference in New Issue
Block a user