Add ATM open-offset toggle default off.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -31,6 +31,7 @@ KEYS = (
|
|||||||
"leverage",
|
"leverage",
|
||||||
"min_option_hours",
|
"min_option_hours",
|
||||||
"min_option_leverage",
|
"min_option_leverage",
|
||||||
|
"atm_open_offset_enabled",
|
||||||
"max_atm_open_offset",
|
"max_atm_open_offset",
|
||||||
"close_bid_mark_max_pct",
|
"close_bid_mark_max_pct",
|
||||||
"perp_qty_eth",
|
"perp_qty_eth",
|
||||||
@@ -50,6 +51,7 @@ class StrategySettingsBody(BaseModel):
|
|||||||
leverage: float | None = Field(default=None, ge=1, le=125)
|
leverage: float | None = Field(default=None, ge=1, le=125)
|
||||||
min_option_hours: float | None = Field(default=None, ge=1, le=720)
|
min_option_hours: float | None = Field(default=None, ge=1, le=720)
|
||||||
min_option_leverage: float | None = Field(default=None, ge=1, le=10000)
|
min_option_leverage: float | None = Field(default=None, ge=1, le=10000)
|
||||||
|
atm_open_offset_enabled: bool | None = None
|
||||||
max_atm_open_offset: float | None = Field(default=None, ge=0, le=100)
|
max_atm_open_offset: float | None = Field(default=None, ge=0, le=100)
|
||||||
close_bid_mark_max_pct: float | None = Field(default=None, ge=1, le=100)
|
close_bid_mark_max_pct: float | None = Field(default=None, ge=1, le=100)
|
||||||
perp_qty_eth: float | None = Field(default=None, ge=0.01, le=100)
|
perp_qty_eth: float | None = Field(default=None, ge=0.01, le=100)
|
||||||
@@ -102,6 +104,12 @@ def _read_settings() -> dict:
|
|||||||
db.get_setting("min_option_leverage", str(s.min_option_leverage))
|
db.get_setting("min_option_leverage", str(s.min_option_leverage))
|
||||||
or s.min_option_leverage
|
or s.min_option_leverage
|
||||||
),
|
),
|
||||||
|
"atm_open_offset_enabled": _as_bool(
|
||||||
|
db.get_setting(
|
||||||
|
"atm_open_offset_enabled", str(s.atm_open_offset_enabled)
|
||||||
|
),
|
||||||
|
s.atm_open_offset_enabled,
|
||||||
|
),
|
||||||
"max_atm_open_offset": float(
|
"max_atm_open_offset": float(
|
||||||
db.get_setting("max_atm_open_offset", str(s.max_atm_open_offset))
|
db.get_setting("max_atm_open_offset", str(s.max_atm_open_offset))
|
||||||
or s.max_atm_open_offset
|
or s.max_atm_open_offset
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ async def sim_open_group(
|
|||||||
if pick is None:
|
if pick is None:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=409,
|
status_code=409,
|
||||||
detail="无合格期权:请检查剩余时长、ATM距现价(≤开仓偏差上限)与杠杆(现价/卖一)",
|
detail="无合格期权:请检查剩余时长、ATM开仓偏差(若已开启)与杠杆(现价/卖一)",
|
||||||
)
|
)
|
||||||
|
|
||||||
force = (body.force_option_side if body else None) or None
|
force = (body.force_option_side if body else None) or None
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ class Settings(BaseSettings):
|
|||||||
leverage: float = 3.0 # 永续杠杆
|
leverage: float = 3.0 # 永续杠杆
|
||||||
min_option_hours: float = 12.0 # 期权最小剩余小时
|
min_option_hours: float = 12.0 # 期权最小剩余小时
|
||||||
min_option_leverage: float = 100.0 # 现价/卖一权利金 下限
|
min_option_leverage: float = 100.0 # 现价/卖一权利金 下限
|
||||||
max_atm_open_offset: float = 3.0 # 开仓:|ATM行权价−标的| 上限(点)
|
atm_open_offset_enabled: bool = False # 开仓 ATM 偏差限制开关(默认关)
|
||||||
|
max_atm_open_offset: float = 3.0 # 开启后:|ATM行权价−标的| 上限(点)
|
||||||
close_bid_mark_max_pct: float = 30.0 # 平仓:买一相对标记最大偏差%
|
close_bid_mark_max_pct: float = 30.0 # 平仓:买一相对标记最大偏差%
|
||||||
perp_qty_eth: float = 1.0
|
perp_qty_eth: float = 1.0
|
||||||
option_qty_eth: float = 2.0
|
option_qty_eth: float = 2.0
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ class Database:
|
|||||||
"leverage": str(s.leverage),
|
"leverage": str(s.leverage),
|
||||||
"min_option_hours": str(s.min_option_hours),
|
"min_option_hours": str(s.min_option_hours),
|
||||||
"min_option_leverage": str(s.min_option_leverage),
|
"min_option_leverage": str(s.min_option_leverage),
|
||||||
|
"atm_open_offset_enabled": str(s.atm_open_offset_enabled),
|
||||||
"max_atm_open_offset": str(s.max_atm_open_offset),
|
"max_atm_open_offset": str(s.max_atm_open_offset),
|
||||||
"close_bid_mark_max_pct": str(s.close_bid_mark_max_pct),
|
"close_bid_mark_max_pct": str(s.close_bid_mark_max_pct),
|
||||||
"perp_qty_eth": str(s.perp_qty_eth),
|
"perp_qty_eth": str(s.perp_qty_eth),
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ class StrategyEngine:
|
|||||||
min_opt_lev = self.ledger.get_setting_float(
|
min_opt_lev = self.ledger.get_setting_float(
|
||||||
"min_option_leverage", s.min_option_leverage
|
"min_option_leverage", s.min_option_leverage
|
||||||
)
|
)
|
||||||
|
atm_off_on = self.ledger.get_setting_bool(
|
||||||
|
"atm_open_offset_enabled", s.atm_open_offset_enabled
|
||||||
|
)
|
||||||
max_atm_off = self.ledger.get_setting_float(
|
max_atm_off = self.ledger.get_setting_float(
|
||||||
"max_atm_open_offset", s.max_atm_open_offset
|
"max_atm_open_offset", s.max_atm_open_offset
|
||||||
)
|
)
|
||||||
@@ -80,6 +83,7 @@ class StrategyEngine:
|
|||||||
"leverage": leverage,
|
"leverage": leverage,
|
||||||
"min_option_hours": min_hours,
|
"min_option_hours": min_hours,
|
||||||
"min_option_leverage": min_opt_lev,
|
"min_option_leverage": min_opt_lev,
|
||||||
|
"atm_open_offset_enabled": atm_off_on,
|
||||||
"max_atm_open_offset": max_atm_off,
|
"max_atm_open_offset": max_atm_off,
|
||||||
"can_open": allow_open,
|
"can_open": allow_open,
|
||||||
"last_error": last_error,
|
"last_error": last_error,
|
||||||
@@ -310,7 +314,7 @@ class StrategyEngine:
|
|||||||
pick = await get_session().pick_for_open_async()
|
pick = await get_session().pick_for_open_async()
|
||||||
if pick is None:
|
if pick is None:
|
||||||
self._set_state(
|
self._set_state(
|
||||||
last_error="无合格期权:需剩余时长、ATM开仓偏差与杠杆同时满足"
|
last_error="无合格期权:需剩余时长、杠杆(及已开启的ATM偏差)同时满足"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -52,9 +52,15 @@ def atm_open_offset(strike: float, mark_px: float) -> float:
|
|||||||
|
|
||||||
|
|
||||||
def atm_allows_open(
|
def atm_allows_open(
|
||||||
strike: float, mark_px: float, *, max_offset: float
|
strike: float,
|
||||||
|
mark_px: float,
|
||||||
|
*,
|
||||||
|
max_offset: float,
|
||||||
|
enabled: bool = False,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""|strike − mark| ≤ max_offset 才允许开仓。"""
|
"""开启限制时:|strike − mark| ≤ max_offset 才允许开仓;关闭则始终允许。"""
|
||||||
|
if not enabled:
|
||||||
|
return True
|
||||||
if mark_px <= 0 or max_offset < 0:
|
if mark_px <= 0 or max_offset < 0:
|
||||||
return False
|
return False
|
||||||
return atm_open_offset(strike, mark_px) <= float(max_offset) + 1e-9
|
return atm_open_offset(strike, mark_px) <= float(max_offset) + 1e-9
|
||||||
|
|||||||
@@ -36,8 +36,14 @@ def _has_open_position() -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _strategy_floats() -> tuple[float, float, float]:
|
def _as_bool_setting(raw: str | None, default: bool) -> bool:
|
||||||
"""min_hours, min_leverage, max_atm_open_offset"""
|
if raw is None or raw == "":
|
||||||
|
return default
|
||||||
|
return str(raw).strip().lower() in ("1", "true", "yes", "on")
|
||||||
|
|
||||||
|
|
||||||
|
def _strategy_floats() -> tuple[float, float, float, bool]:
|
||||||
|
"""min_hours, min_leverage, max_atm_open_offset, atm_open_offset_enabled"""
|
||||||
s = get_settings()
|
s = get_settings()
|
||||||
try:
|
try:
|
||||||
from ..models.db import get_db
|
from ..models.db import get_db
|
||||||
@@ -55,9 +61,18 @@ def _strategy_floats() -> tuple[float, float, float]:
|
|||||||
db.get_setting("max_atm_open_offset", str(s.max_atm_open_offset))
|
db.get_setting("max_atm_open_offset", str(s.max_atm_open_offset))
|
||||||
or s.max_atm_open_offset
|
or s.max_atm_open_offset
|
||||||
)
|
)
|
||||||
return hours, lev, atm_off
|
atm_on = _as_bool_setting(
|
||||||
|
db.get_setting("atm_open_offset_enabled", str(s.atm_open_offset_enabled)),
|
||||||
|
s.atm_open_offset_enabled,
|
||||||
|
)
|
||||||
|
return hours, lev, atm_off, atm_on
|
||||||
except Exception:
|
except Exception:
|
||||||
return s.min_option_hours, s.min_option_leverage, s.max_atm_open_offset
|
return (
|
||||||
|
s.min_option_hours,
|
||||||
|
s.min_option_leverage,
|
||||||
|
s.max_atm_open_offset,
|
||||||
|
s.atm_open_offset_enabled,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
@@ -142,7 +157,7 @@ class StrategySession:
|
|||||||
mark = self.ex.fetch_mark(s.perp_inst_id) or idx
|
mark = self.ex.fetch_mark(s.perp_inst_id) or idx
|
||||||
if mark is None or mark <= 0:
|
if mark is None or mark <= 0:
|
||||||
raise RuntimeError("无法获取标的标记/指数价格,无法选 ATM")
|
raise RuntimeError("无法获取标的标记/指数价格,无法选 ATM")
|
||||||
min_hours, _, _ = _strategy_floats()
|
min_hours, _, _, _ = _strategy_floats()
|
||||||
contracts = self.ex.list_option_contracts(s.option_inst_family)
|
contracts = self.ex.list_option_contracts(s.option_inst_family)
|
||||||
pair = select_option_pair(contracts, mark_px=float(mark), min_hours=min_hours)
|
pair = select_option_pair(contracts, mark_px=float(mark), min_hours=min_hours)
|
||||||
if pair is None:
|
if pair is None:
|
||||||
@@ -155,7 +170,7 @@ class StrategySession:
|
|||||||
from .signal import decide
|
from .signal import decide
|
||||||
|
|
||||||
s = self.settings
|
s = self.settings
|
||||||
min_hours, min_lev, max_atm_off = _strategy_floats()
|
min_hours, min_lev, max_atm_off, atm_off_on = _strategy_floats()
|
||||||
idx = self.ex.fetch_index(s.index_inst_id)
|
idx = self.ex.fetch_index(s.index_inst_id)
|
||||||
mark = self.ex.fetch_mark(s.perp_inst_id) or idx
|
mark = self.ex.fetch_mark(s.perp_inst_id) or idx
|
||||||
if mark is None or mark <= 0:
|
if mark is None or mark <= 0:
|
||||||
@@ -173,7 +188,10 @@ class StrategySession:
|
|||||||
continue
|
continue
|
||||||
offset = atm_open_offset(pair.strike, underlying)
|
offset = atm_open_offset(pair.strike, underlying)
|
||||||
if not atm_allows_open(
|
if not atm_allows_open(
|
||||||
pair.strike, underlying, max_offset=max_atm_off
|
pair.strike,
|
||||||
|
underlying,
|
||||||
|
max_offset=max_atm_off,
|
||||||
|
enabled=atm_off_on,
|
||||||
):
|
):
|
||||||
logger.info(
|
logger.info(
|
||||||
"skip expiry=%s strike=%.0f atm_offset=%.1f > max=%.1f",
|
"skip expiry=%s strike=%.0f atm_offset=%.1f > max=%.1f",
|
||||||
@@ -281,7 +299,7 @@ class StrategySession:
|
|||||||
def atm_needs_realign(self, mark_px: float | None = None) -> bool:
|
def atm_needs_realign(self, mark_px: float | None = None) -> bool:
|
||||||
if self._pair is None:
|
if self._pair is None:
|
||||||
return True
|
return True
|
||||||
min_hours, _, _ = _strategy_floats()
|
min_hours, _, _, _ = _strategy_floats()
|
||||||
if (
|
if (
|
||||||
hours_until_expiry(self._pair.expiry_ymd, expiry_ms=self._pair.expiry_ms)
|
hours_until_expiry(self._pair.expiry_ymd, expiry_ms=self._pair.expiry_ms)
|
||||||
+ 1e-9
|
+ 1e-9
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ def test_atm_allows_open_offset() -> None:
|
|||||||
from app.strategy.selection import atm_allows_open, atm_open_offset
|
from app.strategy.selection import atm_allows_open, atm_open_offset
|
||||||
|
|
||||||
assert atm_open_offset(1850, 1852.5) == 2.5
|
assert atm_open_offset(1850, 1852.5) == 2.5
|
||||||
assert atm_allows_open(1850, 1852.5, max_offset=3) is True
|
# 默认关闭:不限制
|
||||||
assert atm_allows_open(1850, 1854, max_offset=3) is False
|
assert atm_allows_open(1850, 1860, max_offset=3, enabled=False) is True
|
||||||
assert atm_allows_open(1850, 1860, max_offset=3) is False
|
assert atm_allows_open(1850, 1852.5, max_offset=3, enabled=True) is True
|
||||||
|
assert atm_allows_open(1850, 1854, max_offset=3, enabled=True) is False
|
||||||
|
assert atm_allows_open(1850, 1860, max_offset=3, enabled=True) is False
|
||||||
|
|||||||
+6
-4
@@ -58,7 +58,7 @@
|
|||||||
→ 非周末跳过(若开启)
|
→ 非周末跳过(若开启)
|
||||||
→ 选到期:剩余时长 ≥ min_option_hours(默认 12h)
|
→ 选到期:剩余时长 ≥ min_option_hours(默认 12h)
|
||||||
→ 该到期 ATM 行权价(最接近标的)
|
→ 该到期 ATM 行权价(最接近标的)
|
||||||
→ |ATM − 标的| ≤ max_atm_open_offset(默认 3)否则跳过该到期
|
→ 若开启 atm_open_offset_enabled:|ATM − 标的| ≤ max_atm_open_offset(默认 3)否则跳过
|
||||||
→ 选向:ATM 偏下→Call+空;偏上→Put+多;贴平→卖一比价
|
→ 选向:ATM 偏下→Call+空;偏上→Put+多;贴平→卖一比价
|
||||||
→ 期权杠杆 = 标的价 ÷ 卖一权利金 ≥ min_option_leverage(默认 100)
|
→ 期权杠杆 = 标的价 ÷ 卖一权利金 ≥ min_option_leverage(默认 100)
|
||||||
→ 开永续 + 开期权(一组)
|
→ 开永续 + 开期权(一组)
|
||||||
@@ -71,8 +71,9 @@
|
|||||||
|------|------|------|
|
|------|------|------|
|
||||||
| `min_option_hours` | 12 | 过滤过近到期,减少刚开仓就到期 |
|
| `min_option_hours` | 12 | 过滤过近到期,减少刚开仓就到期 |
|
||||||
| `min_option_leverage` | 100 | 权利金相对标的不能太贵(现价/卖一) |
|
| `min_option_leverage` | 100 | 权利金相对标的不能太贵(现价/卖一) |
|
||||||
| `max_atm_open_offset` | 3 | 开仓:\|ATM 行权价 − 标的\| 超过则不开 |
|
| `atm_open_offset_enabled` | false | 开仓 ATM 偏差限制开关(默认关) |
|
||||||
| ATM | — | 同到期、最接近指数/标记价的行权价(展示可偏离;开仓另受偏差上限约束) |
|
| `max_atm_open_offset` | 3 | 开关开启后:\|ATM − 标的\| 超过则不开 |
|
||||||
|
| ATM | — | 同到期、最接近指数/标记价的行权价 |
|
||||||
|
|
||||||
无合格合约时:状态停留等待,记录「无合格期权…」,不硬开。
|
无合格合约时:状态停留等待,记录「无合格期权…」,不硬开。
|
||||||
|
|
||||||
@@ -240,7 +241,8 @@
|
|||||||
| `skip_weekends` | true | 时间 |
|
| `skip_weekends` | true | 时间 |
|
||||||
| `min_option_hours` | 12 | 选约 |
|
| `min_option_hours` | 12 | 选约 |
|
||||||
| `min_option_leverage` | 100 | 选约 |
|
| `min_option_leverage` | 100 | 选约 |
|
||||||
| `max_atm_open_offset` | 3 | 开仓 ATM 偏差 |
|
| `atm_open_offset_enabled` | false | 开仓 ATM 偏差开关 |
|
||||||
|
| `max_atm_open_offset` | 3 | 开仓 ATM 偏差上限 |
|
||||||
| `close_bid_mark_max_pct` | 30 | 平仓流动性 |
|
| `close_bid_mark_max_pct` | 30 | 平仓流动性 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ export type PlanState = {
|
|||||||
leverage: number;
|
leverage: number;
|
||||||
min_option_hours: number;
|
min_option_hours: number;
|
||||||
min_option_leverage: number;
|
min_option_leverage: number;
|
||||||
|
atm_open_offset_enabled?: boolean;
|
||||||
max_atm_open_offset?: number;
|
max_atm_open_offset?: number;
|
||||||
can_open: boolean;
|
can_open: boolean;
|
||||||
last_error: string | null;
|
last_error: string | null;
|
||||||
@@ -180,6 +181,7 @@ export type StrategySettings = {
|
|||||||
leverage: number;
|
leverage: number;
|
||||||
min_option_hours: number;
|
min_option_hours: number;
|
||||||
min_option_leverage: number;
|
min_option_leverage: number;
|
||||||
|
atm_open_offset_enabled: boolean;
|
||||||
max_atm_open_offset: number;
|
max_atm_open_offset: number;
|
||||||
close_bid_mark_max_pct: number;
|
close_bid_mark_max_pct: number;
|
||||||
perp_qty_eth: number;
|
perp_qty_eth: number;
|
||||||
|
|||||||
@@ -197,8 +197,10 @@ export default function PlanPage() {
|
|||||||
<span>选约条件</span>
|
<span>选约条件</span>
|
||||||
<span className="mono">
|
<span className="mono">
|
||||||
剩余≥{fmt(plan?.min_option_hours, 0)}h · 期权杠杆≥
|
剩余≥{fmt(plan?.min_option_hours, 0)}h · 期权杠杆≥
|
||||||
{fmt(plan?.min_option_leverage, 0)}x · ATM偏差≤
|
{fmt(plan?.min_option_leverage, 0)}x
|
||||||
{fmt(plan?.max_atm_open_offset ?? 3, 0)}
|
{plan?.atm_open_offset_enabled
|
||||||
|
? ` · ATM偏差≤${fmt(plan?.max_atm_open_offset ?? 3, 0)}`
|
||||||
|
: " · ATM偏差关"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="kv">
|
<div className="kv">
|
||||||
@@ -418,9 +420,13 @@ export default function PlanPage() {
|
|||||||
if (strike == null || px == null) return "—";
|
if (strike == null || px == null) return "—";
|
||||||
const abs = Math.abs(strike - px);
|
const abs = Math.abs(strike - px);
|
||||||
const sign = strike - px > 0 ? "+" : "";
|
const sign = strike - px > 0 ? "+" : "";
|
||||||
|
const delta = `${sign}${(strike - px).toFixed(0)}`;
|
||||||
|
if (!plan?.atm_open_offset_enabled) {
|
||||||
|
return `${delta} · 偏差限制关`;
|
||||||
|
}
|
||||||
const lim = plan?.max_atm_open_offset ?? 3;
|
const lim = plan?.max_atm_open_offset ?? 3;
|
||||||
const ok = abs <= lim + 1e-9;
|
const ok = abs <= lim + 1e-9;
|
||||||
return `${sign}${(strike - px).toFixed(0)} · 开仓${ok ? "可" : "不可"}(|Δ|≤${lim})`;
|
return `${delta} · 开仓${ok ? "可" : "不可"}(|Δ|≤${lim})`;
|
||||||
})()}
|
})()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export default function SettingsPage() {
|
|||||||
const [leverage, setLeverage] = useState(3);
|
const [leverage, setLeverage] = useState(3);
|
||||||
const [minHours, setMinHours] = useState(12);
|
const [minHours, setMinHours] = useState(12);
|
||||||
const [minOptLev, setMinOptLev] = useState(100);
|
const [minOptLev, setMinOptLev] = useState(100);
|
||||||
|
const [atmOffOn, setAtmOffOn] = useState(false);
|
||||||
const [maxAtmOff, setMaxAtmOff] = useState(3);
|
const [maxAtmOff, setMaxAtmOff] = useState(3);
|
||||||
const [closeDevPct, setCloseDevPct] = useState(30);
|
const [closeDevPct, setCloseDevPct] = useState(30);
|
||||||
const [perpQty, setPerpQty] = useState(1);
|
const [perpQty, setPerpQty] = useState(1);
|
||||||
@@ -51,6 +52,7 @@ export default function SettingsPage() {
|
|||||||
setLeverage(s.leverage ?? 3);
|
setLeverage(s.leverage ?? 3);
|
||||||
setMinHours(s.min_option_hours ?? 12);
|
setMinHours(s.min_option_hours ?? 12);
|
||||||
setMinOptLev(s.min_option_leverage ?? 100);
|
setMinOptLev(s.min_option_leverage ?? 100);
|
||||||
|
setAtmOffOn(s.atm_open_offset_enabled === true);
|
||||||
setMaxAtmOff(s.max_atm_open_offset ?? 3);
|
setMaxAtmOff(s.max_atm_open_offset ?? 3);
|
||||||
setCloseDevPct(s.close_bid_mark_max_pct ?? 30);
|
setCloseDevPct(s.close_bid_mark_max_pct ?? 30);
|
||||||
setPerpQty(s.perp_qty_eth ?? 1);
|
setPerpQty(s.perp_qty_eth ?? 1);
|
||||||
@@ -109,6 +111,7 @@ export default function SettingsPage() {
|
|||||||
leverage,
|
leverage,
|
||||||
min_option_hours: minHours,
|
min_option_hours: minHours,
|
||||||
min_option_leverage: minOptLev,
|
min_option_leverage: minOptLev,
|
||||||
|
atm_open_offset_enabled: atmOffOn,
|
||||||
max_atm_open_offset: maxAtmOff,
|
max_atm_open_offset: maxAtmOff,
|
||||||
close_bid_mark_max_pct: closeDevPct,
|
close_bid_mark_max_pct: closeDevPct,
|
||||||
perp_qty_eth: perpQty,
|
perp_qty_eth: perpQty,
|
||||||
@@ -260,6 +263,21 @@ export default function SettingsPage() {
|
|||||||
onChange={(e) => setMinOptLev(Number(e.target.value))}
|
onChange={(e) => setMinOptLev(Number(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="field">
|
||||||
|
<label htmlFor="atmoffOn">开仓 ATM 偏差限制</label>
|
||||||
|
<select
|
||||||
|
id="atmoffOn"
|
||||||
|
className="mono"
|
||||||
|
value={atmOffOn ? "1" : "0"}
|
||||||
|
onChange={(e) => setAtmOffOn(e.target.value === "1")}
|
||||||
|
>
|
||||||
|
<option value="0">关闭(默认)</option>
|
||||||
|
<option value="1">开启</option>
|
||||||
|
</select>
|
||||||
|
<p className="settings-hint">
|
||||||
|
关闭时不限制 |ATM − 现价|;开启后超过下方点数则不开仓。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label htmlFor="atmoff">开仓 ATM 最大偏差(点)</label>
|
<label htmlFor="atmoff">开仓 ATM 最大偏差(点)</label>
|
||||||
<input
|
<input
|
||||||
@@ -268,11 +286,12 @@ export default function SettingsPage() {
|
|||||||
type="number"
|
type="number"
|
||||||
step="0.5"
|
step="0.5"
|
||||||
min="0"
|
min="0"
|
||||||
|
disabled={!atmOffOn}
|
||||||
value={maxAtmOff}
|
value={maxAtmOff}
|
||||||
onChange={(e) => setMaxAtmOff(Number(e.target.value))}
|
onChange={(e) => setMaxAtmOff(Number(e.target.value))}
|
||||||
/>
|
/>
|
||||||
<p className="settings-hint">
|
<p className="settings-hint">
|
||||||
|ATM 行权价 − 标的价| 超过该值则不开仓。默认 3;币安行权价步进较粗时可能长时间无开仓机会。
|
仅在上方开关开启时生效。默认 3;币安行权价步进较粗时可能长时间无开仓机会。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user