Add dual exit modes: fixed USDT or premium multiple.

Net PnL (after estimated close fees) drives auto close; Plan/Settings expose the choice.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-25 09:17:50 +08:00
parent 9fd2a842af
commit cce26e87b5
13 changed files with 282 additions and 72 deletions
+54 -13
View File
@@ -21,7 +21,11 @@ export default function SettingsPage() {
const [loading, setLoading] = useState(false);
const [fee, setFee] = useState(0.0005);
const [exitPct, setExitPct] = useState(2);
const [exitMode, setExitMode] = useState<"fixed_usdt" | "premium_multiple">(
"fixed_usdt",
);
const [netTarget, setNetTarget] = useState(15);
const [premMult, setPremMult] = useState(1);
const [rest, setRest] = useState(300);
const [leverage, setLeverage] = useState(3);
const [minHours, setMinHours] = useState(12);
@@ -35,7 +39,9 @@ export default function SettingsPage() {
apiFetch<StrategySettings>("/api/settings/strategy")
.then((s) => {
setFee(s.fee_rate);
setExitPct(s.exit_move_pct ?? 2);
setExitMode(s.exit_mode === "premium_multiple" ? "premium_multiple" : "fixed_usdt");
setNetTarget(s.net_profit_target ?? 15);
setPremMult(s.premium_exit_multiple ?? 1);
setRest(s.rest_seconds);
setLeverage(s.leverage ?? 3);
setMinHours(s.min_option_hours ?? 12);
@@ -87,7 +93,9 @@ export default function SettingsPage() {
method: "PUT",
body: JSON.stringify({
fee_rate: fee,
exit_move_pct: exitPct,
exit_mode: exitMode,
net_profit_target: netTarget,
premium_exit_multiple: premMult,
rest_seconds: rest,
leverage,
min_option_hours: minHours,
@@ -126,7 +134,7 @@ export default function SettingsPage() {
{tab === "strategy" ? (
<div className="card">
<p style={{ color: "var(--muted)", marginTop: 0 }}>
</p>
{stratOk ? <div style={{ color: "var(--up)", marginBottom: 12 }}>{stratOk}</div> : null}
{err && tab === "strategy" ? <div className="err">{err}</div> : null}
@@ -171,17 +179,50 @@ export default function SettingsPage() {
/>
</div>
<div className="field">
<label htmlFor="exit">%</label>
<input
id="exit"
<label htmlFor="exitMode"></label>
<select
id="exitMode"
className="mono"
type="number"
step="0.1"
min="0.1"
value={exitPct}
onChange={(e) => setExitPct(Number(e.target.value))}
/>
value={exitMode}
onChange={(e) =>
setExitMode(
e.target.value === "premium_multiple"
? "premium_multiple"
: "fixed_usdt",
)
}
>
<option value="fixed_usdt">USDT</option>
<option value="premium_multiple"></option>
</select>
</div>
{exitMode === "fixed_usdt" ? (
<div className="field">
<label htmlFor="netTarget">USDT</label>
<input
id="netTarget"
className="mono"
type="number"
step="0.1"
min="0.1"
value={netTarget}
onChange={(e) => setNetTarget(Number(e.target.value))}
/>
</div>
) : (
<div className="field">
<label htmlFor="premMult">1 = </label>
<input
id="premMult"
className="mono"
type="number"
step="0.1"
min="0.1"
value={premMult}
onChange={(e) => setPremMult(Number(e.target.value))}
/>
</div>
)}
<div className="field">
<label htmlFor="closeDev">/%</label>
<input