Allow risk-based 永期 exits via premium multiple as well as base×k.

Settings UI picks 基数 or 权利金×n; sizing preview and control monitor follow.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-07 18:13:11 +08:00
parent ab612df818
commit 06f612aa52
5 changed files with 161 additions and 28 deletions
+5 -1
View File
@@ -216,7 +216,11 @@ export default function PlanPage() {
}${fmt(ooRatio, 1)}`
: `净盈≥预算×${fmt(ooRatio, 1)}(达标只平盈利腿)`
: exitMode === "premium_multiple"
? `权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
? riskBased
? exitTarget != null
? `${riskLocked ? "锁定 " : ""}净盈≥${fmt(exitTarget)} U(权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
: `权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}(开仓后锁定)`
: `权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
: riskBased
? exitTarget != null
? `${riskLocked ? "锁定 " : "固定 "}${fmt(exitTarget)} U(基数${fmt(plan?.risk_exit_unit ?? 15)}`
+96 -14
View File
@@ -376,8 +376,7 @@ export default function SettingsPage() {
try {
const body: Record<string, unknown> = {
fee_rate: fee,
exit_mode:
oo || sizingMode === "risk_based" ? "fixed_usdt" : exitMode,
exit_mode: oo ? "fixed_usdt" : exitMode,
premium_exit_multiple: premMult,
rest_seconds: rest,
live_order_interval_sec: orderInterval,
@@ -1029,10 +1028,23 @@ export default function SettingsPage() {
pk != null
? Number((riskOptUnit * pk).toFixed(4))
: riskPreview.option_qty_eth;
const premEst = Number(riskPreview.premium_est);
const exit =
pk != null
? Number((riskExitUnit * pk).toFixed(2))
: riskPreview.net_profit_target;
exitMode === "premium_multiple"
? Number.isFinite(premEst)
? Number(
(
premEst * Number(premMult || 1)
).toFixed(2),
)
: riskPreview.net_profit_target
: pk != null
? Number((riskExitUnit * pk).toFixed(2))
: riskPreview.net_profit_target;
const exitDisp =
exitMode === "premium_multiple"
? `权利金×${Number(premMult || 1)}${exit ?? "—"}`
: String(exit ?? "—");
const budS = Number.isFinite(bud)
? bud.toFixed(2)
: "—";
@@ -1076,7 +1088,7 @@ export default function SettingsPage() {
} · Put≈${
riskPreview.put_qty_eth ?? "—"
} · 出场=预算×${ooRewardRatio}${mgS}`
: `k=${pk ?? "—"} · 预算=${budS}U · 估亏=${mxS}U · 永续=${perp ?? "—"} · 期权=${opt ?? "—"} · 出场=${exit ?? "—"}${basisS}${mgS}`;
: `k=${pk ?? "—"} · 预算=${budS}U · 估亏=${mxS}U · 永续=${perp ?? "—"} · 期权=${opt ?? "—"} · 出场=${exitDisp}${basisS}${mgS}`;
})()}
</div>
</div>
@@ -1120,9 +1132,72 @@ export default function SettingsPage() {
}}
/>
</div>
<div className="field">
<label htmlFor="riskExitKind"></label>
<select
id="riskExitKind"
className="mono"
value={
exitMode === "premium_multiple"
? "premium_multiple"
: "fixed_usdt"
}
onChange={(e) =>
setExitMode(
e.target.value === "premium_multiple"
? "premium_multiple"
: "fixed_usdt",
)
}
>
<option value="fixed_usdt">×k</option>
<option value="premium_multiple"></option>
</select>
</div>
{exitMode === "premium_multiple" ? (
<div className="field">
<label htmlFor="riskPremMult">
</label>
<select
id="riskPremMultQuick"
className="mono"
value={
[1, 1.5, 2, 3].some(
(x) => Math.abs(x - Number(premMult)) < 1e-9,
)
? String(Number(premMult))
: "custom"
}
onChange={(e) => {
if (e.target.value === "custom") return;
setPremMult(Number(e.target.value));
}}
>
<option value="1">1 </option>
<option value="1.5">1.5 </option>
<option value="2">2 </option>
<option value="3">3 </option>
<option value="custom"></option>
</select>
<input
id="riskPremMult"
className="mono"
style={{ marginTop: 6 }}
type="number"
step="0.1"
min="0.1"
value={premMult}
onChange={(e) =>
setPremMult(Number(e.target.value))
}
/>
</div>
) : (
<>
<div className="field">
<label htmlFor="riskExitU">
k=1
k=1
</label>
<input
id="riskExitU"
@@ -1178,6 +1253,8 @@ export default function SettingsPage() {
}}
/>
</div>
</>
)}
</>
) : null}
</>
@@ -1399,10 +1476,7 @@ export default function SettingsPage() {
<select
id="exitMode"
className="mono"
disabled={sizingMode === "risk_based"}
value={
sizingMode === "risk_based" ? "fixed_usdt" : exitMode
}
value={exitMode}
onChange={(e) =>
setExitMode(
e.target.value === "premium_multiple"
@@ -1411,15 +1485,19 @@ export default function SettingsPage() {
)
}
>
<option value="fixed_usdt">USDT</option>
<option value="fixed_usdt">
{sizingMode === "risk_based"
? "基数(×k"
: "固定净盈利(USDT"}
</option>
<option value="premium_multiple"></option>
</select>
</div>
{sizingMode === "risk_based" || exitMode === "fixed_usdt" ? (
{exitMode === "fixed_usdt" ? (
<div className="field">
<label htmlFor="netTarget">
{sizingMode === "risk_based"
? "出场资金k=1 基数"
? "出场基数k=1"
: "净盈利出场目标(USDT"}
</label>
<input
@@ -1635,6 +1713,10 @@ export default function SettingsPage() {
k便便
k
</li>
<li>
×k 1
/2
</li>
</>
)}
<li>