"""Validazione FINALE delle 3 strategie oneste selezionate.
Per ciascuna: per-asset FULL/OOS/DD/anni-positivi + sweep fee (0/0.05/0.10/0.20% RT).
Tutto NETTO, ingresso eseguibile, OOS = ultimo 30%, leva 3x.

S1 DIP   — long-only dip-buy z-score reversion (1h)         [regime: reversione]
S2 TREND — long-only EMA 20/100 trend-following (4h)        [regime: momentum singolo]
S3 ROT   — rotazione cross-sectional momentum sul paniere (1d) [regime: forza relativa]
"""
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.honest_lab import atr, ema, get_df, simulate, oos_split, available_assets
from scripts.analysis.honest_trend import simulate_position, ema_dual_signal, oos as trend_oos
from scripts.analysis.honest_rotation import build_panel, simulate_rotation

FEES = [0.0, 0.0005, 0.001, 0.002]


# ---- S1 DIP ----
def dip_entries(df, n=50, z_in=2.5, sl_atr=2.5, max_bars=24):
    c = df["close"].values
    ma = pd.Series(c).rolling(n).mean().values
    sd = pd.Series(c).rolling(n).std().values
    a = atr(df, 14)
    z = (c - ma) / np.where(sd == 0, np.nan, sd)
    ents = []
    for i in range(n + 14, len(c)):
        if np.isnan(z[i]) or np.isnan(a[i]):
            continue
        if z[i] <= -z_in and z[i - 1] > -z_in:
            ents.append({"i": i, "d": 1, "tp": ma[i], "sl": c[i] - sl_atr * a[i], "max_bars": max_bars})
    return ents


def validate_dip(assets):
    print("\n" + "=" * 100)
    print("  S1 DIP — long-only dip-buy z-score reversion | 1h | n=50 z=2.5 sl=2.5ATR mb=24")
    print("=" * 100)
    print(f"  {'Asset':<6s}{'Trd':>6s}{'Win%':>7s}{'FULL%':>9s}{'OOS%':>9s}{'DD%':>6s}{'Exp%':>6s}{'AnniP':>8s}"
          f"{'  fee-sweep OOS% (0/0.05/0.10/0.20)':<40s}")
    ok = 0
    for a in assets:
        df = get_df(a, "1h"); ents = dip_entries(df)
        if len(ents) < 30:
            continue
        full = simulate(ents, df); _, oe = oos_split(ents, df); oos = simulate(oe, df)
        sweep = "  ".join(f"{simulate(oe, df, fee_rt=f).ret:+.0f}" for f in FEES)
        good = full.ret > 0 and oos.ret > 0
        ok += good
        print(f"  {a:<6s}{full.trades:>6d}{full.win:>7.1f}{full.ret:>+9.0f}{oos.ret:>+9.0f}"
              f"{full.dd:>6.0f}{full.exposure:>6.0f}{f'{full.pos_years}/{full.n_years}':>8s}   [{sweep}]"
              f"{'  OK' if good else ''}")
    print(f"  -> robusto (FULL+OOS>0) su {ok}/{len(assets)} asset")


def validate_trend(assets):
    print("\n" + "=" * 100)
    print("  S2 TREND — long-only EMA 20/100 trend | 4h")
    print("=" * 100)
    print(f"  {'Asset':<6s}{'Flip':>6s}{'FULL%':>9s}{'OOS%':>9s}{'DD%':>6s}{'Exp%':>6s}{'AnniP':>8s}")
    ok = 0
    for a in assets:
        df = get_df(a, "4h"); sig = ema_dual_signal(df, 20, 100, long_only=True)
        full = simulate_position(sig, df); oos = trend_oos(sig, df)
        good = full["ret"] > 0 and oos["ret"] > 0
        ok += good
        print(f"  {a:<6s}{full['flips']:>6d}{full['ret']:>+9.0f}{oos['ret']:>+9.0f}"
              f"{full['dd']:>6.0f}{full['exposure']:>6.0f}{(str(full['pos_years'])+'/'+str(full['n_years'])):>8s}"
              f"{'  OK' if good else ''}")
    print(f"  -> robusto su {ok}/{len(assets)} asset")


def validate_rot(assets):
    print("\n" + "=" * 100)
    print("  S3 ROT — rotazione cross-sectional momentum | 1d | lb=60 top2 su tutto il paniere")
    print("=" * 100)
    panel = build_panel(assets, "1d")
    print(f"  Paniere {list(panel.columns)}  {panel.shape[0]} barre {panel.index[0].date()}->{panel.index[-1].date()}")
    print(f"  {'fee RT':<10s}{'FULL%':>9s}{'OOS%':>9s}{'DD%':>6s}{'AnniP':>8s}")
    for f in FEES:
        full = simulate_rotation(panel, lookback=60, top_k=2, fee_rt=f)
        oos = simulate_rotation(panel, lookback=60, top_k=2, fee_rt=f, oos_frac=0.30)
        anni = str(full['pos_years']) + '/' + str(full['n_years'])
        print(f"  {f*100:>5.2f}%RT  {full['ret']:>+9.0f}{oos['ret']:>+9.0f}{full['dd']:>6.0f}{anni:>8s}")
    # per-anno alla fee reale
    full = simulate_rotation(panel, lookback=60, top_k=2, fee_rt=0.001)
    print("  per-anno (fee 0.10%): " + "  ".join(f"{y}:{v:+.0f}%" for y, v in sorted(full["yearly"].items())))


if __name__ == "__main__":
    assets = available_assets()
    print(f"VALIDAZIONE FINALE — asset disponibili: {assets}")
    validate_dip(assets)
    validate_trend(assets)
    validate_rot(assets)
