"""
================================================================================
Strategy **D008** — ``s008``
================================================================================

Theme
-----
**Aligned short-term / medium-term trend stack (long-dated vol sale).**

Economic idea
-------------
Require ``SMA20 > SMA50 > SMA200`` using panel columns ``sma_20`` and ``sma_50``/``sma_200``.
This is a **triple stack** bull filter, slower than a single MA cross. The trade is a
**short ATM straddle** at 35 DTE: the hypothesis is that in persistent bull stacks, near
ATM implied vol mean-reverts over a **longer** hold than typical event straddles.

Entry
-----
1. ``sma_20``, ``sma_50``, ``sma_200`` all finite.
2. ``sma_20 > sma_50 > sma_200``.
3. ``VIX`` between **14 and 22** (not complacency <14, not crisis >22).
4. ``iv_atm(35) > rv21 + 0.25*rv21`` (explicit VRP threshold, **not** reused from catalog).
5. ``n_contracts[i] >= 80``.

Exit
----
Short straddle ~35 DTE, hold **10** sessions.
================================================================================
"""

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": "D008", "theme": "trend_stack", "title": "SMA20>SMA50>SMA200 + VRP gate short straddle"}

HOLD_SESSIONS = 10
TRADE_KIND = "ss"
TRADE_PARAMS = (35,)


def wants_entry(i: int, row: pd.Series, ch: OptionChain, spy: float, ctx: ResearchContext) -> bool:
    s20 = row.get("sma_20")
    s50 = row.get("sma_50")
    s200 = row.get("sma_200")
    if any(x is None or pd.isna(x) for x in (s20, s50, s200)):
        return False
    a, b, c = float(s20), float(s50), float(s200)
    if not (a > b > c):
        return False
    vx = ctx.vix(i)
    if not math.isfinite(vx) or vx < 14.0 or vx > 22.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, 35)
    if iv is None or iv <= rv * 1.25:
        return False
    if ctx.chain_contracts(i) < 80:
        return False
    if not ch.contracts:
        return False
    _ = spy
    return True
