Try all OTM strikes in offset when nearest fails leverage.
Closest Call@1920 at 152x no longer blocks 1930/1940 that already clear 200x. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -46,18 +46,19 @@ def pick_atm_strike(strikes: list[float], mark_px: float) -> float | None:
|
||||
return min(strikes, key=lambda s: (abs(s - mark_px), s))
|
||||
|
||||
|
||||
def pick_otm_strike(
|
||||
def list_otm_strikes(
|
||||
strikes: list[float],
|
||||
mark_px: float,
|
||||
*,
|
||||
option_side: str,
|
||||
max_offset: float,
|
||||
) -> float | None:
|
||||
) -> list[float]:
|
||||
"""
|
||||
虚值:Call K>S、Put K<S;取最接近标的且 |K−S|≤max_offset 的一档。
|
||||
虚值候选:Call K>S、Put K<S 且 |K−S|≤max_offset;
|
||||
按靠近标的优先排序(近→远)。
|
||||
"""
|
||||
if not strikes or mark_px <= 0:
|
||||
return None
|
||||
return []
|
||||
side = (option_side or "").strip().lower()
|
||||
spot = float(mark_px)
|
||||
cap = max(0.0, float(max_offset))
|
||||
@@ -74,10 +75,25 @@ def pick_otm_strike(
|
||||
if float(s) < spot - 1e-9 and spot - float(s) <= cap + 1e-9
|
||||
]
|
||||
else:
|
||||
return None
|
||||
if not cands:
|
||||
return None
|
||||
return min(cands, key=lambda s: (abs(s - spot), s))
|
||||
return []
|
||||
return sorted(cands, key=lambda s: (abs(s - spot), s))
|
||||
|
||||
|
||||
def pick_otm_strike(
|
||||
strikes: list[float],
|
||||
mark_px: float,
|
||||
*,
|
||||
option_side: str,
|
||||
max_offset: float,
|
||||
) -> float | None:
|
||||
"""虚值:取最接近标的且 |K−S|≤max_offset 的一档。"""
|
||||
cands = list_otm_strikes(
|
||||
strikes,
|
||||
mark_px,
|
||||
option_side=option_side,
|
||||
max_offset=max_offset,
|
||||
)
|
||||
return cands[0] if cands else None
|
||||
|
||||
|
||||
def is_otm(*, option_side: str, strike: float, mark_px: float) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user