"""Test della rivalutazione del peso live (scripts/research/r0726_reeval_live_weight.py). Il punto del file non e' il numero: e' che il peso live resti **dentro il plateau** e che ogni proposta di cambio passi da `weights_tilt_null`. Se un domani qualcuno alza SKH01 senza il gate, questi test lo dicono. """ from __future__ import annotations import sys from pathlib import Path import numpy as np import pandas as pd import pytest ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT / "scripts" / "research")) import r0726_reeval_live_weight as RW # noqa: E402 def test_il_peso_live_e_nella_griglia_valutata(): """Una griglia che non contiene il peso corrente non puo' dire se cambiarlo.""" assert RW.W_LIVE in RW.W_GRID def test_la_griglia_copre_entrambi_i_lati_del_peso_live(): """Se la griglia fosse solo verso l'alto, l'argmax sarebbe garantito >= live per costruzione.""" assert min(RW.W_GRID) < RW.W_LIVE < max(RW.W_GRID) def test_il_peso_della_griglia_coincide_col_book_di_produzione(): """W_LIVE deve essere il peso VERO del book Deribit, non una costante scollegata.""" from src.live.book import W_SKH, W_TP01 assert RW.W_LIVE == pytest.approx(W_SKH) assert W_TP01 + W_SKH == pytest.approx(1.0) def test_la_statistica_e_la_mediana_delle_differenze_appaiate(): """Lezione 26/07: fra offset si usa la mediana delle DIFFERENZE, non la differenza delle mediane (che confronta offset diversi). Su dati costruiti le due risposte divergono.""" # Serve che l'ORDINAMENTO differisca fra le due serie, altrimenti le due statistiche # coincidono per caso (prima stesura di questo test: coincidevano, e non provava niente). a = np.array([1.0, 5.0, 6.0]) b = np.array([4.0, 2.0, 3.0]) appaiata = float(np.median(a - b)) # [-3, +3, +3] -> +3 delle_mediane = float(np.median(a) - np.median(b)) # 5 - 3 -> +2 assert appaiata == pytest.approx(3.0) assert delle_mediane == pytest.approx(2.0) assert appaiata != pytest.approx(delle_mediane) def test_gate_tilt_null_rifiuta_un_cambio_che_perde_in_sample(): """Controllo POSITIVO sul gate: un tilt costruito per perdere pre-holdout deve fallire. Un gate che approva tutto e' inutile quanto uno che rifiuta tutto.""" from src.portfolio.portfolio import weights_tilt_null idx = pd.date_range("2019-01-01", periods=1500, freq="D", tz="UTC") rng = np.random.default_rng(7) buona = pd.Series(rng.normal(0.0008, 0.01, len(idx)), index=idx) cattiva = pd.Series(rng.normal(-0.0008, 0.02, len(idx)), index=idx) res = weights_tilt_null({"BUONA": buona, "CATTIVA": cattiva}, {"BUONA": 0.75, "CATTIVA": 0.25}, {"BUONA": 0.35, "CATTIVA": 0.65}, k_seen=9) assert res["gate_pass"] is False def test_promemoria_fee_coerente_con_la_regola_gia_decisa(): """La soglia d'azione sulla fee vive in un solo posto: se cambia li', questo test la segue.""" src = (ROOT / "scripts" / "research" / "r0726_reeval_live_weight.py").read_text() assert "taker <=5bps" in src and ">10bps" in src