"""FETCH storia DVOL (Deribit Volatility Index) — input IV per lo sleeve opzioni VRP.

DVOL = vol implicita 30d annualizzata di Deribit (l'IV "ATM" del mercato). Public API, no auth.
Limite 1000 punti/richiesta -> paginazione all'indietro. Salva data/raw/dvol_<asset>.parquet
(colonne: timestamp ms, close = DVOL%). Usato come IV per prezzare BS le opzioni nel backtest VRP;
la RV viene dai nostri prezzi certificati. VRP = IV - RV.

    uv run python scripts/research/fetch_dvol.py
"""
from __future__ import annotations
import sys, time
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT))
import requests, pandas as pd

URL = "https://www.deribit.com/api/v2/public/get_volatility_index_data"
RAW = PROJECT_ROOT / "data" / "raw"


def fetch(cur, res=86400):
    end = int(time.time() * 1000)
    floor = int(pd.Timestamp("2020-06-01", tz="UTC").timestamp() * 1000)
    rows = {}
    guard = 0
    while end > floor and guard < 60:
        guard += 1
        r = requests.get(URL, params={"currency": cur, "start_timestamp": floor,
                                       "end_timestamp": end, "resolution": res}, timeout=40)
        data = r.json().get("result", {}).get("data", [])
        if not data:
            break
        for ts, o, h, l, c in data:
            rows[int(ts)] = float(c)
        earliest = min(int(x[0]) for x in data)
        if earliest >= end:
            break
        end = earliest - 1
    if not rows:
        return pd.DataFrame()
    df = pd.DataFrame(sorted(rows.items()), columns=["timestamp", "close"])
    return df


def main():
    for cur in ("BTC", "ETH"):
        df = fetch(cur)
        if df.empty:
            print(f"{cur}: VUOTO"); continue
        ts = pd.to_datetime(df["timestamp"], unit="ms", utc=True)
        df.to_parquet(RAW / f"dvol_{cur.lower()}.parquet", index=False)
        print(f"{cur}: {len(df)} giorni  [{ts.iloc[0].date()} -> {ts.iloc[-1].date()}]  "
              f"DVOL media {df['close'].mean():.1f}  range [{df['close'].min():.1f}, {df['close'].max():.1f}]  "
              f"-> data/raw/dvol_{cur.lower()}.parquet")


if __name__ == "__main__":
    main()
