Add fixed-direction switch for perp/option open side.
When enabled, lock perp long→buy Put or short→buy Call with ITM/ATM only; off keeps ATM/ask rules. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -234,6 +234,8 @@ export type PlanState = {
|
||||
min_option_leverage: number;
|
||||
atm_open_offset_enabled?: boolean;
|
||||
max_atm_open_offset?: number;
|
||||
fixed_direction_enabled?: boolean;
|
||||
fixed_perp_side?: "long" | "short";
|
||||
can_open: boolean;
|
||||
open_capacity?: {
|
||||
leverage?: number;
|
||||
@@ -299,6 +301,29 @@ export type PlanState = {
|
||||
live_ready_reason?: string;
|
||||
};
|
||||
|
||||
export type StrategySettings = {
|
||||
fee_rate: number;
|
||||
exit_mode: "fixed_usdt" | "premium_multiple";
|
||||
net_profit_target: number;
|
||||
premium_exit_multiple: number;
|
||||
rest_seconds: number;
|
||||
live_order_interval_sec?: number;
|
||||
skip_weekends?: boolean;
|
||||
initial_equity?: number;
|
||||
leverage?: number;
|
||||
min_option_hours?: number;
|
||||
min_option_leverage?: number;
|
||||
atm_open_offset_enabled?: boolean;
|
||||
max_atm_open_offset?: number;
|
||||
fixed_direction_enabled?: boolean;
|
||||
fixed_perp_side?: "long" | "short";
|
||||
close_bid_mark_max_pct?: number;
|
||||
perp_qty_eth?: number;
|
||||
option_qty_eth?: number;
|
||||
show_manual_trade_buttons?: boolean;
|
||||
exchange?: string;
|
||||
};
|
||||
|
||||
export type RuntimeSettings = {
|
||||
mode: "SIM" | "LIVE";
|
||||
exchange: string;
|
||||
|
||||
@@ -130,9 +130,13 @@ export default function PlanPage() {
|
||||
|
||||
const bias = snap?.ask_compare?.bias;
|
||||
const biasTag =
|
||||
bias === "strike_below_spot" || bias === "call_ask_gt_put" ? (
|
||||
bias === "strike_below_spot" ||
|
||||
bias === "call_ask_gt_put" ||
|
||||
bias === "fixed_short_call" ? (
|
||||
<span className="tag up">买 Call + 永续空</span>
|
||||
) : bias === "strike_above_spot" || bias === "put_ask_gt_call" ? (
|
||||
) : bias === "strike_above_spot" ||
|
||||
bias === "put_ask_gt_call" ||
|
||||
bias === "fixed_long_put" ? (
|
||||
<span className="tag down">买 Put + 永续多</span>
|
||||
) : (
|
||||
<span className="tag">等待 / 相等</span>
|
||||
@@ -149,9 +153,13 @@ export default function PlanPage() {
|
||||
? `权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
|
||||
: `固定 ${fmt(plan?.net_profit_target ?? 15)} U`;
|
||||
const phaseLabel = PHASE_ZH[plan?.phase || ""] || plan?.phase || "—";
|
||||
const atmRule = plan?.atm_open_offset_enabled
|
||||
? `ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
|
||||
: "ATM偏差关";
|
||||
const atmRule = plan?.fixed_direction_enabled
|
||||
? plan?.fixed_perp_side === "short"
|
||||
? "固定:永续空+买Call(实/平)"
|
||||
: "固定:永续多+买Put(实/平)"
|
||||
: plan?.atm_open_offset_enabled
|
||||
? `ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
|
||||
: "ATM偏差关";
|
||||
const exitDetail =
|
||||
exitMode === "premium_multiple"
|
||||
? `净盈利≥初始权利金×${fmt(plan?.premium_exit_multiple ?? 1, 2)}`
|
||||
@@ -337,9 +345,13 @@ export default function PlanPage() {
|
||||
<span className="mono">
|
||||
剩余≥{fmt(plan?.min_option_hours, 0)}h · 期权杠杆≥
|
||||
{fmt(plan?.min_option_leverage, 0)}x
|
||||
{plan?.atm_open_offset_enabled
|
||||
? ` · ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
|
||||
: " · ATM偏差关"}
|
||||
{plan?.fixed_direction_enabled
|
||||
? plan?.fixed_perp_side === "short"
|
||||
? " · 固定空+Call(实/平)"
|
||||
: " · 固定多+Put(实/平)"
|
||||
: plan?.atm_open_offset_enabled
|
||||
? ` · ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
|
||||
: " · ATM偏差关"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="kv">
|
||||
|
||||
@@ -74,6 +74,8 @@ export default function SettingsPage() {
|
||||
const [minOptLev, setMinOptLev] = useState(100);
|
||||
const [atmOffOn, setAtmOffOn] = useState(false);
|
||||
const [maxAtmOff, setMaxAtmOff] = useState(3);
|
||||
const [fixedDirOn, setFixedDirOn] = useState(false);
|
||||
const [fixedPerpSide, setFixedPerpSide] = useState<"long" | "short">("long");
|
||||
const [closeDevPct, setCloseDevPct] = useState(30);
|
||||
const [perpQty, setPerpQty] = useState(1);
|
||||
const [optQty, setOptQty] = useState(2);
|
||||
@@ -158,6 +160,8 @@ export default function SettingsPage() {
|
||||
setMinOptLev(s.min_option_leverage ?? 100);
|
||||
setAtmOffOn(s.atm_open_offset_enabled === true);
|
||||
setMaxAtmOff(s.max_atm_open_offset ?? 3);
|
||||
setFixedDirOn(s.fixed_direction_enabled === true);
|
||||
setFixedPerpSide(s.fixed_perp_side === "short" ? "short" : "long");
|
||||
setCloseDevPct(s.close_bid_mark_max_pct ?? 30);
|
||||
setPerpQty(s.perp_qty_eth ?? 1);
|
||||
setOptQty(s.option_qty_eth ?? 2);
|
||||
@@ -302,6 +306,8 @@ export default function SettingsPage() {
|
||||
min_option_leverage: minOptLev,
|
||||
atm_open_offset_enabled: atmOffOn,
|
||||
max_atm_open_offset: maxAtmOff,
|
||||
fixed_direction_enabled: fixedDirOn,
|
||||
fixed_perp_side: fixedPerpSide,
|
||||
close_bid_mark_max_pct: closeDevPct,
|
||||
perp_qty_eth: perpQty,
|
||||
option_qty_eth: optQty,
|
||||
@@ -610,11 +616,41 @@ export default function SettingsPage() {
|
||||
onChange={(e) => setMinOptLev(Number(e.target.value))}
|
||||
/>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label htmlFor="fixedDirOn">固定方向</label>
|
||||
<select
|
||||
id="fixedDirOn"
|
||||
className="mono"
|
||||
value={fixedDirOn ? "1" : "0"}
|
||||
onChange={(e) => setFixedDirOn(e.target.value === "1")}
|
||||
>
|
||||
<option value="0">关闭(默认,按现有规则)</option>
|
||||
<option value="1">开启</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label htmlFor="fixedPerp">固定永续方向</label>
|
||||
<select
|
||||
id="fixedPerp"
|
||||
className="mono"
|
||||
disabled={!fixedDirOn}
|
||||
value={fixedPerpSide}
|
||||
onChange={(e) =>
|
||||
setFixedPerpSide(
|
||||
e.target.value === "short" ? "short" : "long",
|
||||
)
|
||||
}
|
||||
>
|
||||
<option value="long">永续多 · 买 Put(实值/平值)</option>
|
||||
<option value="short">永续空 · 买 Call(实值/平值)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label htmlFor="atmoffOn">开仓 ATM 偏差限制</label>
|
||||
<select
|
||||
id="atmoffOn"
|
||||
className="mono"
|
||||
disabled={fixedDirOn}
|
||||
value={atmOffOn ? "1" : "0"}
|
||||
onChange={(e) => setAtmOffOn(e.target.value === "1")}
|
||||
>
|
||||
@@ -630,7 +666,7 @@ export default function SettingsPage() {
|
||||
type="number"
|
||||
step="0.5"
|
||||
min="0"
|
||||
disabled={!atmOffOn}
|
||||
disabled={!atmOffOn || fixedDirOn}
|
||||
value={maxAtmOff}
|
||||
onChange={(e) => setMaxAtmOff(Number(e.target.value))}
|
||||
/>
|
||||
@@ -803,11 +839,15 @@ export default function SettingsPage() {
|
||||
{stratSub === "select" ? (
|
||||
<>
|
||||
<li>
|
||||
开仓 ATM 偏差限制:关闭时不限制 |ATM −
|
||||
固定方向:默认关。开启后固定永续多→买 Put,或永续空→买
|
||||
Call;期权只选实值或平值,不买虚值。关闭时仍按 ATM/卖一比价规则。
|
||||
</li>
|
||||
<li>
|
||||
开仓 ATM 偏差限制:固定方向开启时不适用。关闭时不限制 |ATM −
|
||||
现价|;开启后超过下方点数则不开仓。
|
||||
</li>
|
||||
<li>
|
||||
开仓 ATM 最大偏差:仅开关开启时生效。币安行权价较粗时可能长时间无开仓机会。
|
||||
开仓 ATM 最大偏差:仅开关开启且未开固定方向时生效。币安行权价较粗时可能长时间无开仓机会。
|
||||
</li>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user