4b4dca9e3c
Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
"""对冲计划与单独期权开仓互斥门控.
|
|
|
|
默认开启:有进行中对冲计划时禁止单独开期权;有纯期权持仓时禁止启动对冲计划.
|
|
关闭 HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE 后两边可同时开.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from typing import Any, Callable, Optional
|
|
|
|
|
|
def _env_bool(key: str, default: bool = False) -> bool:
|
|
v = (os.getenv(key) or "").strip().lower()
|
|
if not v:
|
|
return default
|
|
return v in ("1", "true", "yes", "on")
|
|
|
|
|
|
def mutual_exclusive_enabled() -> bool:
|
|
return _env_bool("HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE", True)
|
|
|
|
|
|
def block_standalone_option_open_msg(conn: Any) -> Optional[str]:
|
|
"""若应拦截单独开期权,返回中文原因;否则 None."""
|
|
if not mutual_exclusive_enabled():
|
|
return None
|
|
try:
|
|
from lib.hedge_plan.hedge_plan_db import count_active_plans, init_hedge_plan_tables
|
|
|
|
init_hedge_plan_tables(conn)
|
|
if count_active_plans(conn) > 0:
|
|
return "存在进行中对冲计划,禁止单独开期权(可在 env「对冲与期权互斥门控」关闭)"
|
|
except Exception:
|
|
return "互斥门控校验失败,暂禁止单独开期权"
|
|
return None
|
|
|
|
|
|
def _pos_nonzero(raw: dict[str, Any]) -> bool:
|
|
try:
|
|
return abs(float(raw.get("pos") or 0)) > 1e-12
|
|
except (TypeError, ValueError):
|
|
return False
|
|
|
|
|
|
def has_standalone_option_position(conn: Any, raw_positions: list[dict[str, Any]] | None) -> bool:
|
|
"""交易所期权持仓中,是否存在未挂在进行中对冲计划腿上的仓位."""
|
|
if not raw_positions:
|
|
return False
|
|
from lib.instance.instance_dashboard_lib import _resolve_options_source
|
|
|
|
for p in raw_positions:
|
|
if not isinstance(p, dict) or not _pos_nonzero(p):
|
|
continue
|
|
inst = str(p.get("instId") or p.get("inst_id") or "").strip()
|
|
if not inst:
|
|
continue
|
|
source, _, _ = _resolve_options_source(conn, inst)
|
|
if source == "option":
|
|
return True
|
|
return False
|
|
|
|
|
|
def block_hedge_plan_start_msg(
|
|
conn: Any,
|
|
*,
|
|
fetch_positions: Optional[Callable[[Any], Any]] = None,
|
|
exchange: Any = None,
|
|
raw_positions: list[dict[str, Any]] | None = None,
|
|
) -> Optional[str]:
|
|
"""若应拦截启动对冲计划,返回中文原因;否则 None."""
|
|
if not mutual_exclusive_enabled():
|
|
return None
|
|
rows = raw_positions
|
|
if rows is None:
|
|
if fetch_positions is None or exchange is None:
|
|
return None
|
|
try:
|
|
rows = fetch_positions(exchange) or []
|
|
except Exception:
|
|
return "获取期权持仓失败,暂禁止启动对冲计划"
|
|
try:
|
|
if has_standalone_option_position(conn, rows):
|
|
return "存在单独期权持仓,禁止启动对冲计划(可在 env「对冲与期权互斥门控」关闭)"
|
|
except Exception:
|
|
return "互斥门控校验失败,暂禁止启动对冲计划"
|
|
return None
|