"""S2-06: Iron Condor simulato + Variance Risk Premium harvesting.
Vendi un range: se il prezzo sta dentro il range a scadenza → profitto.
Più sofisticato del vol selling puro:
- Calcolo IV vs RV (variance risk premium)
- Selezione larghezza condor in base a IV/RV ratio
- Dynamic position sizing: più capital quando IV/RV ratio è alto
- Ingresso giornaliero, scadenze 24h e 48h
- Include: tail risk protection (chiudi se move > 2 ATR)
"""
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 = 0.001
INITIAL = 1000


def realized_vol_ann(close: np.ndarray, window: int) -> np.ndarray:
    log_ret = np.diff(np.log(np.where(close == 0, 1e-10, close)))
    result = np.full(len(close), 0.5)
    for i in range(window, len(log_ret)):
        result[i + 1] = np.std(log_ret[i - window : i]) * np.sqrt(24 * 365)
    return result


def run_iron_condor(asset, tf="1h"):
    print(f"\n{'#'*60}")
    print(f"  {asset} {tf} — IRON CONDOR / VARIANCE PREMIUM")
    print(f"{'#'*60}")

    df = load_data(asset, tf)
    close = df["close"].values
    high = df["high"].values
    low = df["low"].values
    n = len(close)
    split = int(n * 0.7)
    timestamps = pd.to_datetime(df["timestamp"], unit="ms", utc=True)

    rv_24 = realized_vol_ann(close, 24)
    rv_48 = realized_vol_ann(close, 48)
    rv_168 = realized_vol_ann(close, 168)  # 1 week

    IV_PREMIUM = 1.25  # IV typically 1.2-1.3x RV in crypto

    configs = [
        # (dte_hours, condor_width_mult, max_loss_pct, vrp_min, pos_pct, name)
        (24, 1.0, 0.03, 1.10, 0.15, "24h_1x_std"),
        (24, 1.5, 0.04, 1.10, 0.12, "24h_1.5x_safe"),
        (24, 0.8, 0.025, 1.15, 0.18, "24h_0.8x_aggr"),
        (48, 1.0, 0.035, 1.10, 0.15, "48h_1x_std"),
        (48, 1.5, 0.05, 1.10, 0.12, "48h_1.5x_safe"),
        (48, 0.7, 0.025, 1.20, 0.20, "48h_0.7x_highVRP"),
        (72, 1.2, 0.04, 1.10, 0.12, "72h_1.2x"),
        (24, 1.0, 0.03, 1.30, 0.20, "24h_veryHighVRP"),
        (24, 1.2, 0.035, 1.10, 0.15, "24h_1.2x_balanced"),
    ]

    for dte, width_mult, max_loss, vrp_min, pos_pct, name in configs:
        capital = float(INITIAL)
        correct = 0
        total = 0
        daily_trades = {}
        max_dd = 0
        peak = capital

        for i in range(max(split, 170), n - dte):
            day = timestamps.iloc[i].strftime("%Y-%m-%d")
            if daily_trades.get(day, 0) >= 1:
                continue

            hour = timestamps.iloc[i].hour
            if hour != 8:
                continue

            rv_short = rv_24[i]
            rv_long = rv_168[i]

            if rv_short <= 0 or rv_long <= 0:
                continue

            iv_est = rv_long * IV_PREMIUM
            vrp_ratio = iv_est / rv_short

            if vrp_ratio < vrp_min:
                continue

            spot = close[i]
            t_years = dte / (24 * 365)

            # Condor range: spot ± width * daily_std * sqrt(t)
            daily_std = rv_short / np.sqrt(365)
            range_width = width_mult * daily_std * np.sqrt(dte / 24) * spot

            upper_strike = spot + range_width
            lower_strike = spot - range_width

            # Premium collected (simplified BS for condor)
            # Premium ≈ IV * sqrt(t) * (width factor)
            premium_pct = iv_est * np.sqrt(t_years) * 0.4 * (1 / width_mult)

            # Check if price stays in range
            exit_idx = min(i + dte, n - 1)
            price_path = close[i : exit_idx + 1]
            max_move = max(np.max(price_path) - spot, spot - np.min(price_path))
            final_price = close[exit_idx]

            in_range = lower_strike <= final_price <= upper_strike
            breached_hard = max_move > spot * max_loss

            if breached_hard:
                pnl_pct = -max_loss * pos_pct
            elif in_range:
                pnl_pct = premium_pct * pos_pct
            else:
                # Partial loss: exceeded range but not catastrophic
                excess = max(0, final_price - upper_strike, lower_strike - final_price)
                loss = min(excess / spot, max_loss)
                pnl_pct = (premium_pct - loss) * pos_pct

            fee_cost = FEE * 2 * pos_pct
            net_pnl = pnl_pct - fee_cost

            capital += capital * net_pnl
            capital = max(capital, 0)

            if capital > peak:
                peak = capital
            dd = (peak - capital) / peak if peak > 0 else 0
            max_dd = max(max_dd, dd)

            total += 1
            if net_pnl > 0:
                correct += 1
            daily_trades[day] = daily_trades.get(day, 0) + 1

        if total < 20:
            continue

        acc = correct / total * 100
        ret = (capital - INITIAL) / INITIAL * 100
        test_days = (n - split) / 24
        test_years = test_days / 365.25
        ann = ((capital / INITIAL) ** (1 / test_years) - 1) * 100 if test_years > 0 and capital > 0 else -100
        dpnl = (capital - INITIAL) / test_days if test_days > 0 else 0
        days_active = len(daily_trades)

        tag = "✅✅" if acc >= 70 and ann >= 50 else "✅" if acc >= 65 and ann >= 30 else ""
        print(f"  {name:22s}: trades={total:4d} acc={acc:.1f}% ret={ret:+.1f}% ann={ann:+.1f}% dd={max_dd*100:.1f}% €/day={dpnl:.2f} active={days_active} {tag}")


for asset in ["ETH", "BTC"]:
    run_iron_condor(asset)

# === COMBINAZIONE: Iron Condor + Funding + Gap Fade ===
print(f"\n{'#'*60}")
print(f"  COMBINAZIONE: MULTI-STRATEGY PORTFOLIO")
print(f"{'#'*60}")

# Simula portafoglio: 50% iron condor ETH, 25% iron condor BTC, 25% gap fade ETH
print("  (Dettagli nel prossimo script con backtest combinato)")
