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,100 @@
|
||||
"""CONFERMA su feed PURO Binance spot — la fade ha edge reale o era artefatto-print?
|
||||
|
||||
Il clean close-aware ha spliciato barre Binance-spot dentro la serie Deribit-perp:
|
||||
il crollo del backtest potrebbe (a) rivelare la verita' (l'edge era print) o (b) essere
|
||||
un artefatto dello splice (basis perp/spot ai punti di giunzione). Test decisivo:
|
||||
girare lo STESSO engine fade su una serie 100% Binance spot (sorgente coerente, niente
|
||||
splice). Se anche qui la fade e' negativa -> edge confermato finto.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import sys
|
||||
from pathlib import Path
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
import numpy as np, pandas as pd, ccxt
|
||||
from scripts.analysis.risk_management import build_trades, strats_for
|
||||
|
||||
EX = ccxt.binance({"enableRateLimit": True})
|
||||
SYM = {"BTC": "BTC/USDT", "ETH": "ETH/USDT"}
|
||||
START = "2020-06-01" # warmup per EMA200/ATR; il report usa 2021+
|
||||
YEARS = [2021, 2022, 2023, 2024, 2025, 2026]
|
||||
|
||||
|
||||
def fetch(asset, tf="15m"):
|
||||
start_ms = int(pd.Timestamp(START, tz="UTC").timestamp() * 1000)
|
||||
end_ms = int(pd.Timestamp("2026-05-26", tz="UTC").timestamp() * 1000)
|
||||
tf_ms = 15 * 60 * 1000
|
||||
rows = []
|
||||
since = start_ms
|
||||
while since <= end_ms:
|
||||
r = EX.fetch_ohlcv(SYM[asset], tf, since=since, limit=1000)
|
||||
if not r:
|
||||
break
|
||||
rows += r
|
||||
nxt = int(r[-1][0]) + tf_ms
|
||||
if nxt <= since:
|
||||
break
|
||||
since = nxt
|
||||
df = pd.DataFrame(rows, columns=["timestamp", "open", "high", "low", "close", "volume"])
|
||||
df = df.drop_duplicates("timestamp").sort_values("timestamp").reset_index(drop=True)
|
||||
return df[df["timestamp"] <= end_ms]
|
||||
|
||||
|
||||
def yearly(rows_by_year_ret, ts, trades, pos=0.15):
|
||||
# per-anno compound
|
||||
yr = {y: 1000.0 for y in YEARS}
|
||||
# ricostruisco compound per anno separato (reset capitale ogni anno per ret% annuo)
|
||||
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)
|
||||
oos = [(i, j, r) for i, j, r in trades if ts.iloc[i] >= sd]
|
||||
capO, rO = comp(oos)
|
||||
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 Binance 15m (da {START})...\n")
|
||||
data = {a: fetch(a) for a in ("BTC", "ETH")}
|
||||
print("=" * 92)
|
||||
print(" FADE su PURO Binance spot 15m | RET% per anno (pos 0.15, leva 3x, trend 3.0)")
|
||||
print("=" * 92)
|
||||
print(f" {'sleeve':<12s}" + "".join(f"{y:>9d}" for y in YEARS) + " | FULL% Shrp | OOS% Shrp")
|
||||
print(" " + "-" * 88)
|
||||
for asset in ("BTC", "ETH"):
|
||||
df = data[asset].copy()
|
||||
df = df[pd.to_datetime(df["timestamp"], unit="ms", utc=True).dt.year >= 2021].reset_index(drop=True) \
|
||||
if False else df # tengo il warmup, filtro nei trade
|
||||
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(None, 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