"""GATE PORT06 — ETH/BTC pairs a 15m (origine: gioco "Blind Traders", vincitore #43).

Domanda onesta sollevata dal gioco: la coppia ETH/BTC (gia' deployata in PR01 a 1h,
config UNIV n=50 z_in=2.0 z_exit=0.75 max_bars=72) MIGLIORA se girata a 15m con la
config trovata dal gioco (n=66 z_in=1.67 z_exit=1.0 max_bars=35), oppure e' solo una
variante piu' veloce, correlata, dello STESSO spread?

Metodo (engine di PRODUZIONE pairs_sim, NON il motore-giocattolo del gioco):
  [1] PARITA': pairs_sim ETH/BTC 1h UNIV (pos0.15 lev3) == sleeve canonico PR_ETHBTC.
  [2] CORRELAZIONE 1h vs 15m (rendimenti giornalieri): se ~1 e' ridondante.
  [3] STANDALONE 1h vs 15m (+ griglia robustezza n x z_in su 15m, + stress fee 2x).
  [4] GATE PORT06: baseline(1h) vs SWAP(15m) vs BLEND(0.5*1h+0.5*15m) per la sleeve
      ETH/BTC; promosso se vs baseline l'OOS Sharpe non peggiora E il DD scende
      (PORT06 e famiglia), come gli altri gate del progetto.

    uv run python scripts/analysis/pairs15m_port06_gate.py
"""
from __future__ import annotations

import sys
from pathlib import Path

import numpy as np
import pandas as pd

PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT))

from scripts.analysis.combine_portfolio import port_returns, metrics, SPLIT, OOS_DATE, IDX
from scripts.analysis.pairs_research import pairs_sim, OOS_FRAC
from scripts.analysis.report_families import daily_from
from scripts.portfolios._defs import PORTFOLIOS
from src.portfolio import weighting as W

POS, LEV = 0.15, 3.0                       # config CANONICA (== build_everything)
UNIV_1H = dict(tf="1h", n=50, z_in=2.0, z_exit=0.75, max_bars=72)
GAME_15M = dict(tf="15m", n=66, z_in=1.674, z_exit=1.0, max_bars=35)   # vincitore gioco


def eth_btc_daily(cfg):
    r = pairs_sim("ETH", "BTC", **{**cfg, "pos": POS, "lev": LEV})
    return daily_from(r["eq_ts"], r["eq_v"]), r


def std_metrics(cfg, fee_rt=0.001):
    f = pairs_sim("ETH", "BTC", **{**cfg, "pos": POS, "lev": LEV, "fee_rt": fee_rt})
    o = pairs_sim("ETH", "BTC", **{**cfg, "pos": POS, "lev": LEV, "fee_rt": fee_rt,
                                   "split_frac": 1 - OOS_FRAC})
    yrs = f["yearly"]; pos_y = sum(1 for v in yrs.values() if v > 0)
    return f, o, pos_y, len(yrs)


def port_metrics(members, p):
    ids = p.sleeve_ids
    dr = pd.DataFrame({i: members[i].pct_change().fillna(0.0) for i in ids})
    w = W.weight_vector(p.weighting, ids, dr, weights=p.weights,
                        caps=p.caps, clusters=p.clusters, lookback=p.vol_lookback)
    drp = port_returns({i: members[i] for i in ids}, w)
    return metrics(drp), metrics(drp, lo=SPLIT)


def fam_metrics(eqs):
    dr = port_returns(eqs)
    return metrics(dr), metrics(dr, lo=SPLIT)


def blend(e1, e2, w1=0.5):
    """Sleeve combinata: media pesata dei rendimenti giornalieri (ribilancio 1D)."""
    r1 = e1.reindex(IDX).ffill().bfill().pct_change().fillna(0.0)
    r2 = e2.reindex(IDX).ffill().bfill().pct_change().fillna(0.0)
    rb = w1 * r1 + (1 - w1) * r2
    eq = (1 + rb).cumprod()
    return eq / eq.iloc[0]


def main():
    p = PORTFOLIOS["PORT06"]
    pair_ids = [s.sid for s in p.sleeves if s.sid.startswith("PR_")]
    print("=" * 100)
    print("  GATE PORT06 — ETH/BTC pairs 15m (vincitore gioco) vs 1h deployato")
    print(f"  pos={POS} lev={LEV} (canonico) | OOS da {OOS_DATE} | coppie PORT06: {pair_ids}")
    print("=" * 100)

    from src.portfolio.sleeves import all_sleeve_equities
    eq_base = dict(all_sleeve_equities())

    # [1] PARITA'
    print("\n[1] PARITA' pairs_sim ETH/BTC 1h UNIV (pos0.15 lev3) == sleeve canonico PR_ETHBTC:")
    e1h, r1h = eth_btc_daily(UNIV_1H)
    base = eq_base["PR_ETHBTC"]
    corr = base.pct_change().fillna(0).corr(e1h.pct_change().fillna(0))
    rb = (base.iloc[-1] / base.iloc[0] - 1) * 100
    rr = (e1h.iloc[-1] / e1h.iloc[0] - 1) * 100
    par_ok = corr > 0.999 and abs(rr - rb) <= max(1.0, abs(rb) * 0.01)
    print(f"    corr={corr:.5f}  ret canon {rb:+.0f}% vs replay {rr:+.0f}%  "
          f"{'OK' if par_ok else '<-- MISMATCH (STOP)'}")
    if not par_ok:
        return

    # [2] CORRELAZIONE 1h vs 15m
    e15, r15 = eth_btc_daily(GAME_15M)
    c = e1h.pct_change().fillna(0).corr(e15.pct_change().fillna(0))
    print(f"\n[2] CORRELAZIONE rendimenti giornalieri ETH/BTC 1h vs 15m: {c:.3f}")
    print(f"    {'(quasi-duplicato se >0.8; diversificatore se <0.5)':<60s}")

    # [3] STANDALONE 1h vs 15m
    print("\n[3] STANDALONE ETH/BTC (netto fee 0.20% RT/coppia, leva 3x):")
    print(f"    {'cfg':<10s}{'trd':>6s}{'win%':>6s}{'FULL%':>9s}{'OOS%':>9s}{'CAGR%':>7s}"
          f"{'DD%':>6s}{'oDD%':>7s}{'Shrp':>6s}{'anni+':>7s}{'fee2x FULL%':>12s}")
    for tag, cfg in [("1h UNIV", UNIV_1H), ("15m gioco", GAME_15M)]:
        f, o, py, ny = std_metrics(cfg)
        f2, _, _, _ = std_metrics(cfg, fee_rt=0.002)
        print(f"    {tag:<10s}{f['trades']:>6d}{f['win']:>6.1f}{f['ret']:>+9.0f}{o['ret']:>+9.0f}"
              f"{f['cagr']:>7.0f}{f['dd']:>6.0f}{o['dd']:>7.0f}{f['sharpe']:>6.2f}"
              f"{f'{py}/{ny}':>7s}{f2['ret']:>+12.0f}")

    # robustezza: plateau n x z_in su 15m (Sharpe>1?)
    print("\n    Robustezza 15m (Sharpe full, griglia n x z_in, z_exit=1.0 max_bars=35):")
    ns = [40, 50, 66, 80]; zs = [1.5, 1.7, 2.0, 2.5]
    cells = 0; tot = 0
    hdr = "      n\\z_in " + "".join(f"{z:>7.1f}" for z in zs)
    print(hdr)
    for n in ns:
        row = f"      {n:>6d} "
        for z in zs:
            s = pairs_sim("ETH", "BTC", tf="15m", n=n, z_in=z, z_exit=1.0,
                          max_bars=35, pos=POS, lev=LEV)["sharpe"]
            tot += 1; cells += s > 1
            row += f"{s:>7.2f}"
        print(row)
    print(f"    -> {cells}/{tot} celle Sharpe>1 (plateau se ~tutte; picco se poche)")

    # [4] GATE PORT06
    print("\n[4] GATE PORT06 — sleeve ETH/BTC: baseline(1h) vs SWAP(15m) vs BLEND(50/50):")
    variants = {
        "baseline 1h": e1h,
        "SWAP 15m": e15,
        "BLEND 1h+15m": blend(e1h, e15, 0.5),
    }
    print(f"    {'variante':<14s} | {'FULL Sh':>8s}{'FULL DD%':>9s}{'CAGR':>6s}"
          f" | {'OOS Sh':>7s}{'OOS DD%':>8s} | {'famSh':>6s}{'famDD%':>7s}")
    print("    " + "-" * 78)
    res = {}
    for tag, eth in variants.items():
        members = dict(eq_base)
        members["PR_ETHBTC"] = eth
        f, o = port_metrics(members, p)
        fam_eqs = {sid: (eth if sid == "PR_ETHBTC" else eq_base[sid]) for sid in pair_ids}
        ff, _ = fam_metrics(fam_eqs)
        res[tag] = (f, o, ff)
        print(f"    {tag:<14s} | {f['sharpe']:>8.2f}{f['dd']:>9.2f}{f['cagr']:>5.0f}%"
              f" | {o['sharpe']:>7.2f}{o['dd']:>8.2f} | {ff['sharpe']:>6.2f}{ff['dd']:>7.1f}")

    # VERDETTO
    fb, ob, _ = res["baseline 1h"]
    print("\n" + "=" * 100)
    print("  VERDETTO vs baseline 1h: promosso se OOS Sharpe non peggiora E DD scende (PORT06 e famiglia)")
    print("=" * 100)
    for tag in ("SWAP 15m", "BLEND 1h+15m"):
        f, o, ff = res[tag]
        ok = (o["sharpe"] >= ob["sharpe"] - 0.02 and o["dd"] <= ob["dd"] + 1e-9
              and f["sharpe"] >= fb["sharpe"] - 0.02)
        print(f"  {tag:<14s}: OOS Sh {ob['sharpe']:.2f}->{o['sharpe']:.2f} "
              f"DD {ob['dd']:.2f}->{o['dd']:.2f} | FULL Sh {fb['sharpe']:.2f}->{f['sharpe']:.2f} "
              f"DD {fb['dd']:.2f}->{f['dd']:.2f}  => {'PROMOSSO' if ok else 'bocciato'}")


if __name__ == "__main__":
    main()
