"""
Exactly **100** distinct literature-style strategy specifications for batch evaluation.

Each spec is a unique (signal economics × execution structure × parameters) tuple.
See ``literature_search_agent.py`` for batch run + correlation critique.

Quota note (v3 diversification): fewer redundant **short_rr** / **putwrite** / short-vol
straddle grids; more **low_iv** long straddle, **downtrend** bear-call, **mid-VIX** put
verticals, and **high-VIX** VRP sleeves so passers can include non-dominant families.
"""
from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class StrategySpec:
    """One runnable configuration for :mod:`research_literature_theta_strategies`."""

    sid: str
    family: str
    description: str
    hold: int
    sig_kind: str
    sig_params: tuple
    trade_kind: str
    trade_params: tuple


def build_catalog_100() -> list[StrategySpec]:
    """Return exactly 100 strategy specs across diversified families."""
    out: list[StrategySpec] = []

    def push(
        family: str,
        desc: str,
        hold: int,
        sk: str,
        sp: tuple,
        tk: str,
        tp: tuple,
    ) -> None:
        sid = f"S{len(out):03d}"
        out.append(StrategySpec(sid, family, desc, hold, sk, sp, tk, tp))

    # 10 — VRP short straddle (trimmed; avoid grid dominance)
    for thr in (0.35, 0.50, 0.65):
        for dte in (28, 38):
            for h in (3, 5):
                if len(out) >= 10:
                    break
                push(
                    "vrp_short_straddle",
                    f"IV>RV+{thr}·RV DTE≈{dte} H={h}d",
                    h,
                    "vrp",
                    (float(thr), int(dte)),
                    "ss",
                    (int(dte),),
                )
            if len(out) >= 10:
                break
        if len(out) >= 10:
            break

    # 8 — Low-VIX short strangle
    for vx in (12.5, 13.5, 14.5, 15.5):
        for dte in (35, 45):
            for pdel, cdel in ((-0.20, 0.15), (-0.24, 0.17)):
                if len(out) >= 18:
                    break
                push(
                    "low_vix_strangle",
                    f"VIX<{vx} ΔP={pdel} ΔC={cdel} DTE≈{dte} H=5d",
                    5,
                    "lowvix",
                    (float(vx), float(pdel), float(cdel)),
                    "sg",
                    (int(dte), float(pdel), float(cdel)),
                )
            if len(out) >= 18:
                break
        if len(out) >= 18:
            break

    # 10 — Post-shock long straddle
    for chg in (0.09, 0.12, 0.15, 0.18, 0.22):
        for dte in (10, 14):
            for h in (3, 5):
                if len(out) >= 28:
                    break
                push(
                    "post_shock_long_straddle",
                    f"VIX spike +{int(chg*100)}%/5d DTE≈{dte} H={h}d",
                    h,
                    "spike",
                    (float(chg),),
                    "sl",
                    (int(dte),),
                )
            if len(out) >= 28:
                break
        if len(out) >= 28:
            break

    # 16 — Low-IV long straddle (long gamma; expanded grid)
    for vix_cap in (11.5, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0):
        for iv_mult in (0.88, 0.95):
            if len(out) >= 44:
                break
            push(
                "low_iv_long_straddle",
                f"VIX<{vix_cap} & IV<{iv_mult}·RV DTE≈12 H=4d",
                4,
                "lowiv",
                (float(vix_cap), float(iv_mult), 12),
                "sl",
                (12,),
            )
        if len(out) >= 44:
            break

    # 6 — VIX decline short straddle
    for dv in (-1.0, -1.5, -2.0):
        for dte in (30, 40):
            if len(out) >= 50:
                break
            push(
                "vix_fall_short_straddle",
                f"VIX 5d drop<{dv} DTE≈{dte} H=5d",
                5,
                "vixfall",
                (float(dv),),
                "ss",
                (int(dte),),
            )
        if len(out) >= 50:
            break

    # 6 — PUTWrite (minimal grid; family diversity elsewhere)
    for use50 in (False, True):
        for delt in (-0.20, -0.22, -0.26):
            if len(out) >= 56:
                break
            ma = "SMA50" if use50 else "SMA200"
            push(
                "putwrite",
                f"SPY>{ma} δ={delt} DTE≈35 H=10d",
                10,
                "putwrite",
                (float(delt), bool(use50), 22.0),
                "put",
                (35, float(delt)),
            )
        if len(out) >= 56:
            break

    # 4 — Short RR skew
    for gap in (0.035, 0.045):
        for dte in (35, 40):
            if len(out) >= 60:
                break
            push(
                "short_rr",
                f"IVput−IVcall>{gap} ΔP=-0.18 ΔC=0.12 DTE≈{dte} H=5d",
                5,
                "rr",
                (float(gap), int(dte), -0.18, 0.12),
                "rr",
                (int(dte), -0.18, 0.12),
            )
        if len(out) >= 60:
            break

    # 14 — Downtrend bear-call vertical (spot-below-trend sleeve)
    for use50 in (False, True):
        for dte in (25, 35):
            for delt in (0.18, 0.24):
                for wing in (5.0, 10.0):
                    if len(out) >= 74:
                        break
                    ma = "SMA50" if use50 else "SMA200"
                    push(
                        "downtrend_bear_call",
                        f"SPY<{ma} 17<VIX<36 call vert δ={delt} wing={wing} DTE≈{dte} H=7d",
                        7,
                        "downtrend",
                        (bool(use50), 17.0, 36.0),
                        "vtc",
                        (int(dte), float(delt), float(wing)),
                    )
                if len(out) >= 74:
                    break
            if len(out) >= 74:
                break
        if len(out) >= 74:
            break

    # 6 — VVIX filter + short straddle
    for vvr in (1.03, 1.07, 1.10):
        for dte in (30, 40):
            if len(out) >= 80:
                break
            push(
                "vvix_filter_ss",
                f"VVIX/VIX<{vvr} mild VRP DTE≈{dte} H=5d",
                5,
                "vvix",
                (float(vvr), int(dte)),
                "ss",
                (int(dte),),
            )
        if len(out) >= 80:
            break

    # 4 — RV compression
    for gap in (0.025, 0.04):
        for dte in (30, 40):
            if len(out) >= 84:
                break
            push(
                "rv_compression_ss",
                f"RV21−RV5>{gap} DTE≈{dte} H=7d",
                7,
                "rvcomp",
                (float(gap), int(dte)),
                "ss",
                (int(dte),),
            )
        if len(out) >= 84:
            break

    # 8 — Mild-VIX put vertical (defined risk)
    for delt in (-0.22, -0.26):
        for wing in (5.0, 10.0):
            for dte in (28, 32, 35):
                if len(out) >= 92:
                    break
                push(
                    "mild_vix_put_spread",
                    f"mid-VIX put vert δ={delt} wing={wing} DTE≈{dte} H=12d",
                    12,
                    "midvx_vert",
                    (),
                    "vert",
                    (int(dte), float(delt), float(wing)),
                )
            if len(out) >= 92:
                break
        if len(out) >= 92:
            break

    # 8 — High-VIX VRP short straddle
    for vx0 in (21.0, 23.0, 25.0, 27.0):
        for thr in (0.15, 0.25):
            if len(out) >= 100:
                break
            push(
                "high_vix_vrp_ss",
                f"VIX>{vx0} IV>RV+{thr}·RV DTE≈40 H=5d",
                5,
                "hivix",
                (float(vx0), float(thr), 40),
                "ss",
                (40,),
            )
        if len(out) >= 100:
            break

    assert len(out) == 100, len(out)
    return out
