"""S2-09: VRP test per-anno — verità nuda.
Test su OGNI anno separatamente per vedere performance durante crash.
Niente compounding — PnL medio per trade in punti percentuali.
Costi realistici Deribit options.
"""
from __future__ import annotations
import sys
sys.path.insert(0, ".")

import numpy as np
import pandas as pd
from src.data.downloader import load_data

FEE_ROUNDTRIP = 0.0052  # 0.52% roundtrip (4 legs × 0.13%)
INITIAL = 1000


def rv_ann(close, window):
    lr = np.diff(np.log(np.where(close == 0, 1e-10, close)))
    r = np.full(len(close), np.nan)
    for i in range(window, len(lr)):
        r[i + 1] = np.std(lr[i - window : i]) * np.sqrt(24 * 365)
    return r


def straddle_prem(iv, dte_h):
    if iv <= 0 or dte_h <= 0:
        return 0
    return iv * np.sqrt(dte_h / (24 * 365)) * 0.8


def run_per_year(asset, dte=24):
    print(f"\n{'='*70}")
    print(f"  {asset} — VRP PER ANNO (DTE={dte}h, NO compounding)")
    print(f"  Fee roundtrip: {FEE_ROUNDTRIP*100:.2f}%")
    print(f"{'='*70}")

    df = load_data(asset, "1h")
    close = df["close"].values
    n = len(close)
    ts = pd.to_datetime(df["timestamp"], unit="ms", utc=True)

    rv_24 = rv_ann(close, 24)
    rv_168 = rv_ann(close, 168)

    # IV/RV premium: conservative estimate per regime
    # Storicamene crypto VRP ≈ 15-30% (IV/RV ≈ 1.15-1.30)
    # Ma durante crash VRP va NEGATIVO (RV > IV)

    years = sorted(set(ts.dt.year))

    print(f"\n  {'Year':>6s} {'Trades':>7s} {'Wins':>5s} {'Acc%':>6s} {'AvgPnL%':>9s} {'TotPnL€':>9s} {'Worst%':>8s} {'MaxMove%':>9s}")
    print(f"  {'-'*70}")

    all_pnls = []
    yearly_stats = []

    for year in years:
        year_mask = ts.dt.year == year
        year_indices = np.where(year_mask.values)[0]

        if len(year_indices) < 200:
            continue

        trades_pnl = []
        trades_detail = []

        for i in year_indices:
            if i < 170 or i + dte >= n:
                continue
            if ts.iloc[i].hour != 8:
                continue

            rv_s = rv_24[i]
            rv_l = rv_168[i]
            if np.isnan(rv_s) or np.isnan(rv_l) or rv_s < 0.05 or rv_l < 0.05:
                continue

            # IV estimate: regime-dependent
            regime = rv_s / rv_l if rv_l > 0 else 1.0

            if regime > 2.0:
                # CRASH: RV esplosa, IV probabilmente = RV o meno
                iv_premium_factor = 0.9
            elif regime > 1.5:
                iv_premium_factor = 1.0
            elif regime > 1.0:
                iv_premium_factor = 1.1
            else:
                # Calm: VRP positivo
                iv_premium_factor = 1.2

            iv = rv_l * iv_premium_factor
            prem = straddle_prem(iv, dte)

            spot = close[i]
            exit_idx = min(i + dte, n - 1)
            actual_move = abs(close[exit_idx] - spot) / spot

            # P&L (senza compounding — flat € su €1000)
            pos_size = INITIAL * 0.10  # 10% fisso, no leverage
            if actual_move <= prem:
                raw_pnl = (prem - actual_move) * pos_size
            else:
                raw_pnl = -(actual_move - prem) * pos_size
                raw_pnl = max(raw_pnl, -pos_size * 0.05)  # cap loss

            cost = FEE_ROUNDTRIP * pos_size
            net_pnl = raw_pnl - cost

            trades_pnl.append(net_pnl)
            trades_detail.append({
                "prem": prem,
                "move": actual_move,
                "regime": regime,
                "rv_s": rv_s,
                "iv": iv,
            })
            all_pnls.append(net_pnl)

        if not trades_pnl:
            continue

        wins = sum(1 for p in trades_pnl if p > 0)
        acc = wins / len(trades_pnl) * 100
        avg_pnl = np.mean(trades_pnl)
        tot_pnl = np.sum(trades_pnl)
        worst = np.min(trades_pnl)
        max_move = max(t["move"] for t in trades_detail) * 100

        tag = ""
        if year in [2020, 2021, 2022]:
            tag = " ← CRASH YEAR"
        if acc >= 70 and avg_pnl > 0:
            tag += " ✅"

        print(f"  {year:>6d} {len(trades_pnl):>7d} {wins:>5d} {acc:>5.1f}% {avg_pnl:>+8.2f}€ {tot_pnl:>+8.0f}€ {worst:>+7.2f}€ {max_move:>8.1f}% {tag}")

        yearly_stats.append({
            "year": year, "trades": len(trades_pnl), "acc": acc,
            "avg_pnl": avg_pnl, "tot_pnl": tot_pnl, "worst": worst,
        })

    # Summary
    if all_pnls:
        total_trades = len(all_pnls)
        total_wins = sum(1 for p in all_pnls if p > 0)
        print(f"\n  {'TOTALE':>6s} {total_trades:>7d} {total_wins:>5d} {total_wins/total_trades*100:>5.1f}% {np.mean(all_pnls):>+8.2f}€ {np.sum(all_pnls):>+8.0f}€ {np.min(all_pnls):>+7.2f}€")

        # Con compounding realistico
        capital = float(INITIAL)
        peak = capital
        max_dd = 0
        for pnl in all_pnls:
            capital += pnl * (capital / INITIAL)  # scala con capitale
            capital = max(capital, 10)
            if capital > peak:
                peak = capital
            dd = (peak - capital) / peak
            max_dd = max(max_dd, dd)

        years_total = (yearly_stats[-1]["year"] - yearly_stats[0]["year"] + 1)
        ann = ((capital / INITIAL) ** (1 / years_total) - 1) * 100 if capital > 0 else -100
        daily_avg = (capital - INITIAL) / (total_trades)  # approx 1 trade/day

        print(f"\n  CON COMPOUNDING:")
        print(f"    Capitale finale: €{capital:,.0f}")
        print(f"    ROI annualizzato: {ann:+.1f}%")
        print(f"    Max Drawdown: {max_dd*100:.1f}%")
        print(f"    €/trade medio: €{daily_avg:.2f}")

        # Worst year
        worst_year = min(yearly_stats, key=lambda x: x["tot_pnl"])
        best_year = max(yearly_stats, key=lambda x: x["tot_pnl"])
        print(f"\n    Anno peggiore: {worst_year['year']} → {worst_year['tot_pnl']:+.0f}€ ({worst_year['acc']:.0f}% acc)")
        print(f"    Anno migliore: {best_year['year']} → {best_year['tot_pnl']:+.0f}€ ({best_year['acc']:.0f}% acc)")


for asset in ["ETH", "BTC"]:
    for dte in [24, 48]:
        run_per_year(asset, dte)
