Prefer open direction from ATM vs spot (below=Call/short, above=Put/long).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -187,7 +187,12 @@ class StrategySession:
|
||||
put_bids, put_asks, _ = self.ex.fetch_book(pair.put_inst_id, depth=5)
|
||||
call_ask = call_asks[0].px if call_asks else None
|
||||
put_ask = put_asks[0].px if put_asks else None
|
||||
sig = decide(call_ask, put_ask)
|
||||
sig = decide(
|
||||
call_ask,
|
||||
put_ask,
|
||||
strike=pair.strike,
|
||||
mark_px=underlying,
|
||||
)
|
||||
if sig is None:
|
||||
continue
|
||||
opt_ask = sig.call_ask if sig.option_side == "call" else sig.put_ask
|
||||
|
||||
@@ -5,30 +5,64 @@ from dataclasses import dataclass
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Signal:
|
||||
bias: str # call_ask_gt_put | put_ask_gt_call
|
||||
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) -> Signal | None:
|
||||
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
|
||||
if call_ask > put_ask:
|
||||
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=float(call_ask),
|
||||
put_ask=float(put_ask),
|
||||
call_ask=ca,
|
||||
put_ask=pa,
|
||||
)
|
||||
if put_ask > call_ask:
|
||||
if pa > ca:
|
||||
return Signal(
|
||||
bias="put_ask_gt_call",
|
||||
option_side="put",
|
||||
perp_side="long",
|
||||
call_ask=float(call_ask),
|
||||
put_ask=float(put_ask),
|
||||
call_ask=ca,
|
||||
put_ask=pa,
|
||||
)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user