from __future__ import annotations from dataclasses import dataclass @dataclass(slots=True) class Signal: bias: str # strike_below_spot | strike_above_spot | call_ask_gt_put | put_ask_gt_call option_side: str # call | put perp_side: str # long | short call_ask: float put_ask: float def decide( call_ask: float | None, put_ask: float | None, *, strike: float | None = None, mark_px: float | None = None, ) -> Signal | None: """ 开仓方向: - 行权价 < 标的 → 买 Call + 永续空(ATM 偏下) - 行权价 > 标的 → 买 Put + 永续多(ATM 偏上) - 行权价 ≈ 标的 → 回退 Call/Put 卖一比价 """ if call_ask is None or put_ask is None: return None ca = float(call_ask) pa = float(put_ask) if strike is not None and mark_px is not None and float(mark_px) > 0: diff = float(strike) - float(mark_px) if diff < -1e-9: return Signal( bias="strike_below_spot", option_side="call", perp_side="short", call_ask=ca, put_ask=pa, ) if diff > 1e-9: return Signal( bias="strike_above_spot", option_side="put", perp_side="long", call_ask=ca, put_ask=pa, ) if ca > pa: return Signal( bias="call_ask_gt_put", option_side="call", perp_side="short", call_ask=ca, put_ask=pa, ) if pa > ca: return Signal( bias="put_ask_gt_call", option_side="put", perp_side="long", call_ask=ca, put_ask=pa, ) return None