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>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user