"""
================================================================================
Strategy **D022** — ``s022``
================================================================================

Theme
-----
**Monthly OPEX week calendar + mild vol decline (short strangle).**

Economic idea
-------------
Index **pinning / reduced macro surprise** hypotheses around monthly expiry are testable
only with a calendar rule. This sleeve sells a **35 DTE** strangle **only** in
``is_op_exp_week`` when **VIX has drifted down** modestly (``vix_chg_5 in (-3, -0.25)``),
avoiding both sharp ramps and dead markets.

Entry
-----
1. ``is_op_exp_week`` is true.
2. ``-3.0 < vix_chg_5 < -0.25``.
3. ``14 < VIX < 24``.
4. ``n_contracts[i] >= 100``.

Exit
----
Short strangle 35 DTE, put **-0.24**, call **0.17**, 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": "D022", "theme": "calendar_opex", "title": "OPEX week + gentle VIX fade short strangle"}

HOLD_SESSIONS = 4
TRADE_KIND = "sg"
TRADE_PARAMS = (35, -0.24, 0.17)


def wants_entry(i: int, row: pd.Series, ch: OptionChain, spy: float, ctx: ResearchContext) -> bool:
    fl = row.get("is_op_exp_week")
    if fl is None or pd.isna(fl) or not bool(fl):
        return False
    dv = row.get("vix_chg_5")
    if dv is None or pd.isna(dv):
        return False
    dvf = float(dv)
    if dvf <= -3.0 or dvf >= -0.25:
        return False
    vx = ctx.vix(i)
    if not math.isfinite(vx) or vx <= 14.0 or vx >= 24.0:
        return False
    if ctx.chain_contracts(i) < 100:
        return False
    if not ch.contracts:
        return False
    _ = spy
    return True
