Files
PythagorasGoal/Old/scripts/analysis/mainnet_fade_check.py
Adriano Dal Pastro 14522262e6 chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita
Reset del progetto su fondamenta verificate dopo la scoperta che l'intera
libreria "validata OOS" era artefatto di feed contaminato (print fantasma del
feed Cerbero TESTNET + storico Binance/USDT).

- Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e
  CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia
  (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample
  (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE
  50-82% barre flat; XRP/BNB non certificabili).
- Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni
  portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST
  con segnale residuo, da ri-validare in isolamento.
- Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio,
  runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/
  portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/
  (preservati, non cancellati). Diario consolidato in un unico documento.
- Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal +
  src/backtest/engine + load_data; tool dati certificati (rebuild_history,
  certify_feed, audit_feed, multi_source_check).
- Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico
  (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:20:59 +00:00

124 lines
4.9 KiB
Python

"""VERIFICA DEFINITIVA — la fade ha edge sul perp Deribit MAINNET REALE?
Testnet feed = print fantasma (edge finto). Binance spot = fade morta. Resta da
escludere che la fade viva sulla microstruttura del perp Deribit MAINNET reale (dove
ESEGUE davvero). Scarico lo storico 15m reale (BTC/ETH-PERPETUAL mainnet via Cerbero v2,
token .env.mainnet) e giro lo STESSO engine. Cache in data/raw/_mainnet_*.parquet
(NON tocca i file canonici).
"""
from __future__ import annotations
import sys
from pathlib import Path
from datetime import datetime, timedelta
PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT))
import requests, numpy as np, pandas as pd
from src.live.cerbero_client import TESTNET_TOKEN
from scripts.analysis.risk_management import build_trades, strats_for
URL = "https://cerbero-mcp.tielogic.xyz/mcp/tools/get_historical"
START, END = "2020-06-01", "2026-05-26"
YEARS = [2021, 2022, 2023, 2024, 2025, 2026]
INSTR = {"BTC": "BTC-PERPETUAL", "ETH": "ETH-PERPETUAL"}
def _token():
env = {}
for ln in (PROJECT_ROOT / ".env.mainnet").read_text().splitlines():
ln = ln.strip()
if ln and not ln.startswith("#") and "=" in ln:
k, v = ln.split("=", 1); env[k] = v.strip()
assert env["CERBERO_TOKEN"] != TESTNET_TOKEN, "token e' TESTNET, non mainnet!"
return env["CERBERO_TOKEN"], env.get("CERBERO_BOT_TAG", "pythagoras-verify")
def fetch_mainnet(asset, tf="15m"):
cache = PROJECT_ROOT / "data" / "raw" / f"_mainnet_{asset.lower()}_{tf}.parquet"
if cache.exists():
return pd.read_parquet(cache)
tok, tag = _token()
H = {"Authorization": f"Bearer {tok}", "X-Bot-Tag": tag, "Content-Type": "application/json"}
cur, end = datetime.fromisoformat(START), datetime.fromisoformat(END)
step = timedelta(days=30)
rows = []
while cur < end:
ce = min(cur + step, end)
for attempt in range(3):
try:
r = requests.post(URL, headers=H, json={
"exchange": "deribit", "instrument": INSTR[asset], "interval": tf,
"start_date": cur.strftime("%Y-%m-%d"), "end_date": ce.strftime("%Y-%m-%d")},
timeout=40)
r.raise_for_status()
rows += r.json().get("candles", [])
break
except Exception as e:
if attempt == 2:
print(f" SKIP {cur.date()}->{ce.date()}: {str(e)[:60]}")
cur = ce
df = pd.DataFrame(rows)
if len(df) == 0:
return df
df["timestamp"] = df["timestamp"].astype("int64")
df = df.drop_duplicates("timestamp").sort_values("timestamp").reset_index(drop=True)
df.to_parquet(cache, index=False)
return df
def yearly(ts, trades, pos=0.15):
by = {y: [] for y in YEARS}
for i, j, r in trades:
y = ts.iloc[i].year
if y in by: by[y].append(r)
out = {}
for y in YEARS:
cap = 1000.0
for r in by[y]: cap = max(cap + cap * pos * r, 10.0)
out[y] = (cap / 1000 - 1) * 100
return out
def full_oos(ts, trades, pos=0.15, split_date="2024-10-12"):
sd = pd.Timestamp(split_date, tz="UTC")
def comp(sub):
cap = 1000.0; rets = []
for i, j, r in sub:
cap = max(cap + cap * pos * r, 10.0); rets.append(r * pos)
return cap, rets
capF, rF = comp(trades)
capO, rO = comp([(i, j, r) for i, j, r in trades if ts.iloc[i] >= sd])
shF = float(np.mean(rF)/np.std(rF)*np.sqrt(len(rF))) if len(rF) > 1 and np.std(rF) > 0 else 0.0
shO = float(np.mean(rO)/np.std(rO)*np.sqrt(len(rO))) if len(rO) > 1 and np.std(rO) > 0 else 0.0
return (capF/1000-1)*100, shF, (capO/1000-1)*100, shO
def main():
print(f"Fetch Deribit MAINNET 15m REALE ({START}->{END})...\n")
data = {}
for a in ("BTC", "ETH"):
df = fetch_mainnet(a)
ts = pd.to_datetime(df["timestamp"], unit="ms", utc=True)
print(f" {INSTR[a]}: {len(df)} candele {ts.min()} -> {ts.max()} "
f"(anni: {sorted(ts.dt.year.unique().tolist())})")
data[a] = df
print("\n" + "=" * 94)
print(" FADE su perp Deribit MAINNET REALE 15m | RET% per anno (pos 0.15, leva 3x, trend 3.0)")
print("=" * 94)
print(f" {'sleeve':<12s}" + "".join(f"{y:>9d}" for y in YEARS) + " | FULL% Shrp | OOS% Shrp")
print(" " + "-" * 90)
for asset in ("BTC", "ETH"):
df = data[asset]
ts = pd.to_datetime(df["timestamp"], unit="ms", utc=True)
for code in ("MR01", "MR02", "MR07"):
fn, params = strats_for(asset)[code]
trades = build_trades(fn(df, **params), df, trend_max=3.0)
trades = [(i, j, r) for i, j, r in trades if ts.iloc[i].year >= 2021]
yr = yearly(ts, trades)
fF, shF, fO, shO = full_oos(ts, trades)
print(f" {code+'_'+asset:<12s}" + "".join(f"{yr[y]:>+9.0f}" for y in YEARS) +
f" | {fF:>+8.0f} {shF:>5.2f} | {fO:>+6.0f} {shO:>5.2f}")
if __name__ == "__main__":
main()