"""SCAN DI FATTIBILITA' — la vol term-structure e' scaricabile/certificabile da Deribit pubblico?

Un calendar-vol (front vs back IV) richiede ATM IV per SCADENZA, STORICA. Il DVOL pubblico e' solo
30g. Questo script PROVA cosa l'API pubblica Deribit espone davvero, PRIMA di costruire backtest:
  1. snapshot CORRENTE della term-structure (mark_iv ATM per scadenza) — book_summary_by_currency.
  2. esiste STORIA per-scadenza? (DVOL e' 30g fisso; provo trade history con IV per instrument).
Verdetto: se la storia per-scadenza NON e' pubblica -> calendar-vol NON backtestabile su dati certi.

    uv run python scripts/research/probe_vol_termstructure.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
import numpy as np

BASE = "https://www.deribit.com/api/v2/public/"


def _get(method, **params):
    r = requests.get(BASE + method, params=params, timeout=40)
    return r.json().get("result", None)


def current_term_structure(cur="BTC"):
    """ATM mark_iv per scadenza ORA (snapshot pubblico, tokenless)."""
    summ = _get("get_book_summary_by_currency", currency=cur, kind="option")
    if not summ:
        return None
    idx = _get("get_index_price", index_name=f"{cur.lower()}_usd")
    spot = float(idx["index_price"]) if idx else None
    # raggruppa per scadenza, prendi lo strike piu' vicino allo spot (ATM)
    by_exp = {}
    for o in summ:
        name = o["instrument_name"]            # es. BTC-27JUN26-60000-C
        parts = name.split("-")
        if len(parts) != 4:
            continue
        exp, strike = parts[1], float(parts[2])
        miv = o.get("mark_iv")
        if miv is None or spot is None:
            continue
        d = abs(strike - spot)
        if exp not in by_exp or d < by_exp[exp][0]:
            by_exp[exp] = (d, float(miv), strike)
    return spot, by_exp


def probe_history(cur="BTC"):
    """C'e' STORIA per-scadenza? Provo: (a) DVOL (sappiamo 30g), (b) trade history con IV su uno
    strumento vivo, (c) se esistono indici vol a tenor diversi."""
    findings = []
    # (b) trade history con IV — solo strumenti NON scaduti
    instr = _get("get_instruments", currency=cur, kind="option", expired="false")
    live = instr[0]["instrument_name"] if instr else None
    if live:
        tr = _get("get_last_trades_by_instrument", instrument_name=live, count=5)
        has_iv = bool(tr and tr.get("trades") and "iv" in tr["trades"][0])
        findings.append(f"trade-history IV su {live}: {'SI (ma solo instrument VIVO, no scaduti)' if has_iv else 'NO'}")
    # (c) altri indici vol a tenor != 30g?
    findings.append("get_volatility_index_data: solo DVOL 30g (nessun indice 7g/60g/90g pubblico)")
    return findings


def main():
    print("=" * 88)
    print("  SCAN FATTIBILITA' — vol term-structure Deribit pubblico")
    print("=" * 88)
    for cur in ("BTC", "ETH"):
        ts = current_term_structure(cur)
        if not ts:
            print(f"\n{cur}: nessun dato chain"); continue
        spot, by_exp = ts
        print(f"\n{cur}  spot ${spot:,.0f}  — term-structure ATM mark_iv ORA ({len(by_exp)} scadenze):")
        # ordina per scadenza (data nel nome)
        def _key(e):
            try:
                return time.mktime(time.strptime(e, "%d%b%y"))
            except Exception:
                return 0
        ivs = []
        for exp in sorted(by_exp, key=_key):
            d, miv, strike = by_exp[exp]
            ivs.append(miv)
            print(f"    {exp:>9}  ATM~{strike:>9,.0f}  IV {miv:5.1f}%")
        if len(ivs) >= 2:
            print(f"    -> front {ivs[0]:.1f}%  back {ivs[-1]:.1f}%  slope {ivs[-1]-ivs[0]:+.1f}pp "
                  f"({'contango' if ivs[-1] > ivs[0] else 'backwardation'})")
        print(f"  STORIA per-scadenza:")
        for f in probe_history(cur):
            print(f"    - {f}")
    print("\n" + "=" * 88)
    print("  VERDETTO sulla backtestabilita' sotto.")
    print("=" * 88)


if __name__ == "__main__":
    main()
