Extend semi-auto with ITM/ATM/OTM, offset, and 1:4 sizing.

Moneyness and perp:option units are plan-only; OTM enforces leverage >=180.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-08 11:42:57 +08:00
parent 4585dba3c3
commit 457838ef64
17 changed files with 428 additions and 41 deletions
+34
View File
@@ -52,6 +52,10 @@ KEYS = (
"semi_perp_exit_unit",
"semi_min_option_hours",
"semi_min_option_leverage",
"semi_moneyness",
"semi_otm_max_offset",
"semi_perp_unit",
"semi_option_unit",
"close_bid_mark_max_pct",
"residual_min_premium_pct",
"residual_close_check_sec",
@@ -109,6 +113,10 @@ class StrategySettingsBody(BaseModel):
semi_perp_exit_unit: float | None = Field(default=None, ge=0.1, le=1_000_000)
semi_min_option_hours: float | None = Field(default=None, ge=1, le=720)
semi_min_option_leverage: float | None = Field(default=None, ge=1, le=10000)
semi_moneyness: str | None = Field(default=None, pattern="^(itm|atm|otm)$")
semi_otm_max_offset: float | None = Field(default=None, ge=1, le=5000)
semi_perp_unit: float | None = Field(default=None, ge=0.01, le=100)
semi_option_unit: float | None = Field(default=None, ge=0.01, le=100)
close_bid_mark_max_pct: float | None = Field(default=None, ge=1, le=100)
residual_min_premium_pct: float | None = Field(default=None, ge=1, le=100)
residual_close_check_sec: int | None = Field(default=None, ge=30, le=86400)
@@ -296,6 +304,28 @@ def _read_settings() -> dict:
)
or s.semi_min_option_leverage
),
"semi_moneyness": (
lambda m: m
if m in ("itm", "atm", "otm")
else "otm"
)(
str(
db.get_setting("semi_moneyness", s.semi_moneyness) or s.semi_moneyness
)
.strip()
.lower()
),
"semi_otm_max_offset": float(
db.get_setting("semi_otm_max_offset", str(s.semi_otm_max_offset))
or s.semi_otm_max_offset
),
"semi_perp_unit": float(
db.get_setting("semi_perp_unit", str(s.semi_perp_unit)) or s.semi_perp_unit
),
"semi_option_unit": float(
db.get_setting("semi_option_unit", str(s.semi_option_unit))
or s.semi_option_unit
),
"close_bid_mark_max_pct": float(
db.get_setting("close_bid_mark_max_pct", str(s.close_bid_mark_max_pct))
or s.close_bid_mark_max_pct
@@ -555,6 +585,10 @@ async def put_strategy_settings(
"semi_perp_exit_unit",
"semi_min_option_hours",
"semi_min_option_leverage",
"semi_moneyness",
"semi_otm_max_offset",
"semi_perp_unit",
"semi_option_unit",
"semi_auto_enabled",
)
hit = [k for k in locked_keys if k in data]