"""
================================================================================
Strategy **D030** — ``s030``  (below SMA20 stretch — long straddle)
================================================================================
**Idea:** Under **SMA20** by >2% can be momentum continuation or washout; this sleeve buys
straddle convexity when **VIX is not** at crisis (``VIX<28``) and **IV is cheap vs RV**.
**Entry:** ``close < 0.98 * sma_20``, ``VIX<28``, ``iv_atm(12) < 0.95*rv21``, ``contracts>=80``.
**Exit:** Long straddle 12 DTE, hold **4**.
================================================================================
"""

from __future__ import annotations

import math

import pandas as pd

from RenTech.core.options_data_loader import OptionChain
from RenTech.strategy_stack.diverse_theta_strategies_v1.context import ResearchContext

META = {"sid": "D030", "theme": "stretch_mean_reversion", "title": "Close <98% SMA20 + IV discount vs RV long straddle"}

HOLD_SESSIONS = 4
TRADE_KIND = "sl"
TRADE_PARAMS = (12,)


def wants_entry(i: int, row: pd.Series, ch: OptionChain, spy: float, ctx: ResearchContext) -> bool:
    s20 = row.get("sma_20")
    if s20 is None or pd.isna(s20):
        return False
    if float(row["close"]) >= 0.98 * float(s20):
        return False
    vx = ctx.vix(i)
    if not math.isfinite(vx) or vx >= 28.0:
        return False
    rv = float(row["rv21"]) if pd.notna(row.get("rv21")) else float("nan")
    if not math.isfinite(rv) or rv <= 0:
        return False
    iv = ctx.iv_atm_dte(i, 12)
    if iv is None or iv >= 0.95 * rv:
        return False
    if ctx.chain_contracts(i) < 80 or not ch.contracts:
        return False
    _ = spy
    return True
