#!/usr/bin/env python3
"""
**Default** Theta option portfolio evaluator: overlapping margin, BP gate, **daily MTM equity**.

Use this for multi-sleeve backtests (literature ``S###``, diverse ``D###``, optional VRP).
Do **not** use ``combine_lit_stack_sleeves`` sum-mode equity for headline max drawdown.

Examples::

    # Production lit stack + VRP (improved VRP flags; use explicit paths so logs land in data/logs/)
    cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 \\
        .venv/bin/python -m RenTech.strategy_stack.diverse_theta_strategies_v1.evaluate_theta_margin \\
        --preset lit4-vrp --capital 100000 --start 2016-01-04 --end 2026-04-02 \\
        --no-pmcc --r2-vix-scale-contracts --r2-term-structure-gate --vrp-overlap-slices 2 \\
        --out-daily RenTech/data/logs/lit_stack_vrp_margin_daily.csv \\
        --out-trades RenTech/data/logs/lit_stack_vrp_margin_trades.csv \\
        --out-meta RenTech/data/logs/lit_stack_vrp_margin_meta.json

    # Top-9 diverse D sleeves
    cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 \\
        .venv/bin/python -m RenTech.strategy_stack.diverse_theta_strategies_v1.evaluate_theta_margin \\
        --preset top9-d --capital 100000 --start 2016-01-04 \\
        --out-prefix RenTech/data/logs/diverse_theta_top9_margin

    # Best Ideas SPY book (lit4 + D095/D081/D039/D018/D041/D065 + VRP)
    cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 \\
        .venv/bin/python -m RenTech.strategy_stack.diverse_theta_strategies_v1.evaluate_theta_margin \\
        --preset best-ideas-spy --capital 100000 --start 2016-01-04 \\
        --out-daily RenTech/data/logs/best_ideas_spy6_margin_daily.csv \\
        --out-trades RenTech/data/logs/best_ideas_spy6_margin_trades.csv \\
        --out-meta RenTech/data/logs/best_ideas_spy6_margin_meta.json

    # Custom literature set
    cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 \\
        .venv/bin/python -m RenTech.strategy_stack.diverse_theta_strategies_v1.evaluate_theta_margin \\
        --sid S055 --sid S057 --with-vrp --capital 100000 \\
        --out-prefix RenTech/data/logs/my_eval

Outputs (from ``--out-prefix`` stem): ``*_daily.csv``, ``*_trades.csv``, ``*_meta.json``.
Meta ``primary_risk_metric`` = ``max_drawdown_frac_mtm``; ``max_drawdown_frac_realized`` is reference only.
"""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

_REPO_ROOT = Path(__file__).resolve().parents[3]
if str(_REPO_ROOT) not in sys.path:
    sys.path.insert(0, str(_REPO_ROOT))

from RenTech.strategy_stack import research_literature_theta_strategies as L
from RenTech.strategy_stack.diverse_theta_strategies_v1.theta_margin_eval import (
    PRESET_SIDS,
    config_from_cli_args,
    default_output_paths,
    json_safe,
    run_theta_margin_evaluation,
    write_theta_margin_eval_outputs,
)


def main() -> None:
    ap = argparse.ArgumentParser(
        description="Theta margin + daily MTM portfolio evaluation (default agent backtest tool)",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=f"Presets: {', '.join(sorted(PRESET_SIDS))}",
    )
    ap.add_argument(
        "--preset",
        type=str,
        default=None,
        choices=sorted(PRESET_SIDS),
        help="Strategy bundle (lit4-vrp includes VRP backtest + MTM replay)",
    )
    ap.add_argument(
        "--sid",
        dest="sids",
        action="append",
        default=[],
        metavar="SID",
        help="Literature S### and/or diverse D### (repeatable; ignored if --preset set)",
    )
    ap.add_argument(
        "--with-vrp",
        action="store_true",
        help="Run VRPBacktester and replay into margin sim (MTM on open VRP legs)",
    )
    ap.add_argument("--theta-dir", type=Path, default=L._DEFAULT_THETA)
    ap.add_argument("--capital", type=float, default=100_000.0)
    ap.add_argument("--start", type=str, default="2016-01-04")
    ap.add_argument("--end", type=str, default="")
    ap.add_argument(
        "--max-days",
        type=int,
        default=0,
        help="Caps days before start/end in precompute; prefer --end for smoke windows",
    )
    ap.add_argument("--regt-short-put-mult", type=float, default=1.0)
    ap.add_argument("--max-margin-utilization", type=float, default=1.0)
    ap.add_argument("--qty-per-trade", type=int, default=1)
    ap.add_argument(
        "--stacking",
        action="store_true",
        help="Allow max_concurrent = hold_sessions per sid (stack-while-signal style)",
    )
    ap.add_argument(
        "--max-concurrent",
        type=int,
        default=None,
        metavar="N",
        help="Override max open trades per sid (default 1, or hold if --stacking)",
    )
    ap.add_argument(
        "--vrp-low-dd-overlap",
        action=argparse.BooleanOptionalAction,
        default=True,
    )
    ap.add_argument("--vrp-overlap-slices", type=int, default=1)
    ap.add_argument(
        "--no-pmcc",
        action="store_true",
        help="VRP: skip R1 weekly strangle (same as vrp_backtest_theta.py)",
    )
    ap.add_argument(
        "--r2-vix-scale-contracts",
        action="store_true",
        help="VRP: scale R2 overlap_slice_contracts by VIX/12",
    )
    ap.add_argument(
        "--r2-term-structure-gate",
        action="store_true",
        help="VRP: block new R2 when VIX9D > VIX (inverted front-end)",
    )
    ap.add_argument(
        "--out-prefix",
        type=Path,
        default=_REPO_ROOT / "RenTech" / "data" / "logs" / "theta_margin_eval",
        help="Output stem or directory (writes *_daily.csv, *_trades.csv, *_meta.json)",
    )
    ap.add_argument("--out-daily", type=Path, default=None)
    ap.add_argument("--out-trades", type=Path, default=None)
    ap.add_argument("--out-meta", type=Path, default=None)
    ap.add_argument("--no-vrp-progress", action="store_true")
    args = ap.parse_args()

    if args.preset and args.sids:
        print("Note: --preset ignores explicit --sid list", flush=True)

    cfg = config_from_cli_args(
        preset=args.preset,
        sids=list(args.sids),
        with_vrp=bool(args.with_vrp),
        capital=float(args.capital),
        start=str(args.start),
        end=str(args.end),
        max_days=int(args.max_days),
        theta_dir=Path(args.theta_dir),
        stacking=bool(args.stacking),
        max_concurrent=args.max_concurrent,
        vrp_low_dd_overlap=bool(args.vrp_low_dd_overlap),
        vrp_overlap_slices=int(args.vrp_overlap_slices),
        vrp_disable_pmcc=bool(args.no_pmcc),
        vrp_r2_vix_scale_contracts=bool(args.r2_vix_scale_contracts),
        vrp_r2_term_structure_gate=bool(args.r2_term_structure_gate),
        regt_short_put_mult=float(args.regt_short_put_mult),
        max_margin_utilization=float(args.max_margin_utilization),
        qty_per_trade=int(args.qty_per_trade),
        show_vrp_progress=not bool(args.no_vrp_progress),
    )

    if args.out_daily and args.out_trades and args.out_meta:
        out_d, out_t, out_m = args.out_daily, args.out_trades, args.out_meta
    else:
        slug = str(args.preset or "custom").replace("-", "_")
        out_d, out_t, out_m = default_output_paths(args.out_prefix, slug=slug)

    print(
        f"Theta margin eval: lit={list(cfg.literature_sids)} diverse={list(cfg.diverse_sids)} "
        f"vrp={cfg.with_vrp} stacking={cfg.stacking} capital=${cfg.capital_usd:,.0f}",
        flush=True,
    )

    result = run_theta_margin_evaluation(cfg)
    paths = write_theta_margin_eval_outputs(
        result,
        out_daily=out_d,
        out_trades=out_t,
        out_meta=out_m,
    )

    safe = json_safe(result.meta)
    print(json.dumps(safe, indent=2), flush=True)
    print(f"\nWrote {paths[0]}\nWrote {paths[1]}\nWrote {paths[2]}", flush=True)


if __name__ == "__main__":
    main()
