"""CONFERMA su feed PURO Binance spot — la fade ha edge reale o era artefatto-print?

Il clean close-aware ha spliciato barre Binance-spot dentro la serie Deribit-perp:
il crollo del backtest potrebbe (a) rivelare la verita' (l'edge era print) o (b) essere
un artefatto dello splice (basis perp/spot ai punti di giunzione). Test decisivo:
girare lo STESSO engine fade su una serie 100% Binance spot (sorgente coerente, niente
splice). Se anche qui la fade e' negativa -> edge confermato finto.
"""
from __future__ import annotations
import sys
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT))
import numpy as np, pandas as pd, ccxt
from scripts.analysis.risk_management import build_trades, strats_for

EX = ccxt.binance({"enableRateLimit": True})
SYM = {"BTC": "BTC/USDT", "ETH": "ETH/USDT"}
START = "2020-06-01"   # warmup per EMA200/ATR; il report usa 2021+
YEARS = [2021, 2022, 2023, 2024, 2025, 2026]


def fetch(asset, tf="15m"):
    start_ms = int(pd.Timestamp(START, tz="UTC").timestamp() * 1000)
    end_ms = int(pd.Timestamp("2026-05-26", tz="UTC").timestamp() * 1000)
    tf_ms = 15 * 60 * 1000
    rows = []
    since = start_ms
    while since <= end_ms:
        r = EX.fetch_ohlcv(SYM[asset], tf, since=since, limit=1000)
        if not r:
            break
        rows += r
        nxt = int(r[-1][0]) + tf_ms
        if nxt <= since:
            break
        since = nxt
    df = pd.DataFrame(rows, columns=["timestamp", "open", "high", "low", "close", "volume"])
    df = df.drop_duplicates("timestamp").sort_values("timestamp").reset_index(drop=True)
    return df[df["timestamp"] <= end_ms]


def yearly(rows_by_year_ret, ts, trades, pos=0.15):
    # per-anno compound
    yr = {y: 1000.0 for y in YEARS}
    # ricostruisco compound per anno separato (reset capitale ogni anno per ret% annuo)
    by = {y: [] for y in YEARS}
    for i, j, r in trades:
        y = ts.iloc[i].year
        if y in by:
            by[y].append(r)
    out = {}
    for y in YEARS:
        cap = 1000.0
        for r in by[y]:
            cap = max(cap + cap * pos * r, 10.0)
        out[y] = (cap / 1000 - 1) * 100
    return out


def full_oos(ts, trades, pos=0.15, split_date="2024-10-12"):
    sd = pd.Timestamp(split_date, tz="UTC")
    def comp(sub):
        cap = 1000.0; rets = []
        for i, j, r in sub:
            cap = max(cap + cap * pos * r, 10.0); rets.append(r * pos)
        return cap, rets
    capF, rF = comp(trades)
    oos = [(i, j, r) for i, j, r in trades if ts.iloc[i] >= sd]
    capO, rO = comp(oos)
    shF = float(np.mean(rF) / np.std(rF) * np.sqrt(len(rF))) if len(rF) > 1 and np.std(rF) > 0 else 0.0
    shO = float(np.mean(rO) / np.std(rO) * np.sqrt(len(rO))) if len(rO) > 1 and np.std(rO) > 0 else 0.0
    return (capF / 1000 - 1) * 100, shF, (capO / 1000 - 1) * 100, shO


def main():
    print(f"Fetch Binance 15m (da {START})...\n")
    data = {a: fetch(a) for a in ("BTC", "ETH")}
    print("=" * 92)
    print("  FADE su PURO Binance spot 15m | RET% per anno (pos 0.15, leva 3x, trend 3.0)")
    print("=" * 92)
    print(f"  {'sleeve':<12s}" + "".join(f"{y:>9d}" for y in YEARS) + "   |   FULL%   Shrp |  OOS%  Shrp")
    print("  " + "-" * 88)
    for asset in ("BTC", "ETH"):
        df = data[asset].copy()
        df = df[pd.to_datetime(df["timestamp"], unit="ms", utc=True).dt.year >= 2021].reset_index(drop=True) \
             if False else df  # tengo il warmup, filtro nei trade
        ts = pd.to_datetime(df["timestamp"], unit="ms", utc=True)
        for code in ("MR01", "MR02", "MR07"):
            fn, params = strats_for(asset)[code]
            trades = build_trades(fn(df, **params), df, trend_max=3.0)
            trades = [(i, j, r) for i, j, r in trades if ts.iloc[i].year >= 2021]
            yr = yearly(None, ts, trades)
            fF, shF, fO, shO = full_oos(ts, trades)
            print(f"  {code+'_'+asset:<12s}" + "".join(f"{yr[y]:>+9.0f}" for y in YEARS) +
                  f"   | {fF:>+8.0f} {shF:>5.2f} | {fO:>+6.0f} {shO:>5.2f}")


if __name__ == "__main__":
    main()
