83ce50b24e
Env OKX_TRADE_MODE selects standalone options, perp hedge, or OO hedge; hide the other module UI and use group or position limits per mode. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
2.8 KiB
Python
104 lines
2.8 KiB
Python
"""OKX 期权/对冲三选一模式(env: OKX_TRADE_MODE).
|
|
|
|
options → 仅单独期权(隐藏对冲导航与对冲 env 配置)
|
|
perp_options → 仅永期对冲(不可单独开期权;对冲组数上限 MAX_ACTIVE_HEDGE_PLANS)
|
|
options_options → 仅期期对冲(同上)
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from typing import Optional
|
|
|
|
MODE_OPTIONS = "options"
|
|
MODE_PERP = "perp_options"
|
|
MODE_OO = "options_options"
|
|
VALID_MODES = frozenset({MODE_OPTIONS, MODE_PERP, MODE_OO})
|
|
|
|
_ALIASES = {
|
|
"option": MODE_OPTIONS,
|
|
"standalone": MODE_OPTIONS,
|
|
"期权": MODE_OPTIONS,
|
|
"单独期权": MODE_OPTIONS,
|
|
"po": MODE_PERP,
|
|
"perp": MODE_PERP,
|
|
"永期": MODE_PERP,
|
|
"永期对冲": MODE_PERP,
|
|
"oo": MODE_OO,
|
|
"期期": MODE_OO,
|
|
"期期对冲": MODE_OO,
|
|
}
|
|
|
|
|
|
def _env_bool(name: str, default: bool = False) -> bool:
|
|
raw = os.getenv(name)
|
|
if raw is None or str(raw).strip() == "":
|
|
return default
|
|
return str(raw).strip().lower() in ("1", "true", "yes", "on")
|
|
|
|
|
|
def normalize_okx_trade_mode(raw: Optional[str]) -> str:
|
|
s = str(raw or "").strip().lower()
|
|
if s in VALID_MODES:
|
|
return s
|
|
if s in _ALIASES:
|
|
return _ALIASES[s]
|
|
return ""
|
|
|
|
|
|
def legacy_infer_okx_trade_mode() -> str:
|
|
"""未配置 OKX_TRADE_MODE 时,按旧开关推断,避免已有部署行为突变."""
|
|
if not _env_bool("HEDGE_PLAN_ENABLED", False):
|
|
return MODE_OPTIONS
|
|
show_po = _env_bool("HEDGE_PLAN_SHOW_PERP_OPTIONS", True)
|
|
show_oo = _env_bool("HEDGE_PLAN_SHOW_OPTIONS_OPTIONS", True)
|
|
if show_po and not show_oo:
|
|
return MODE_PERP
|
|
if show_oo and not show_po:
|
|
return MODE_OO
|
|
if show_po:
|
|
return MODE_PERP
|
|
if show_oo:
|
|
return MODE_OO
|
|
return MODE_OPTIONS
|
|
|
|
|
|
def get_okx_trade_mode() -> str:
|
|
m = normalize_okx_trade_mode(os.getenv("OKX_TRADE_MODE"))
|
|
if m:
|
|
return m
|
|
return legacy_infer_okx_trade_mode()
|
|
|
|
|
|
def hedge_module_enabled() -> bool:
|
|
return get_okx_trade_mode() in (MODE_PERP, MODE_OO)
|
|
|
|
|
|
def show_perp_options() -> bool:
|
|
return get_okx_trade_mode() == MODE_PERP
|
|
|
|
|
|
def show_options_options() -> bool:
|
|
return get_okx_trade_mode() == MODE_OO
|
|
|
|
|
|
def standalone_options_open_allowed() -> bool:
|
|
return get_okx_trade_mode() == MODE_OPTIONS
|
|
|
|
|
|
def mode_label(mode: Optional[str] = None) -> str:
|
|
m = mode or get_okx_trade_mode()
|
|
return {
|
|
MODE_OPTIONS: "单独期权",
|
|
MODE_PERP: "永期对冲",
|
|
MODE_OO: "期期对冲",
|
|
}.get(m, m or "—")
|
|
|
|
|
|
def block_standalone_open_by_mode_msg() -> Optional[str]:
|
|
if standalone_options_open_allowed():
|
|
return None
|
|
return (
|
|
f"当前交易模式为「{mode_label()}」,不可单独开期权;"
|
|
"请在 env「交易模式」切换为「单独期权」"
|
|
)
|