14522262e6
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>
53 lines
2.2 KiB
Python
53 lines
2.2 KiB
Python
"""PORT02 — Portafoglio FADE accorpato e migliorato (6 sleeve, equal-weight daily).
|
|
|
|
Accorpa le 3 strategie fade mean-reversion su BTC e ETH, ciascuna MIGLIORATA con
|
|
il filtro trend (salta i fade contro trend estremi: |close-EMA200|/ATR > 3.0):
|
|
MR01 Bollinger fade · MR02 Donchian fade · MR07 Return-reversal
|
|
x {BTC, ETH} -> 6 sleeve indipendenti, pos 0.15 ciascuna, leva 3x.
|
|
(MR03 Keltner spostata in waste: fade piu' debole e ridondante con MR01.)
|
|
|
|
Le curve sono poco correlate fra loro (corr media intra-fade ~0.18): la
|
|
diversificazione abbatte il DD aggregato ben sotto quello del singolo sleeve.
|
|
|
|
Risultato (netto fee 0.10% RT, equal-weight ribilanciato ogni giorno, finestra
|
|
comune 2021-2026, OOS = ultimo 30%):
|
|
Ret +666% / CAGR 46% / DD 8.2% FULL · OOS DD 5.9% / Sharpe 3.95 FULL / 4.09 OOS.
|
|
Ricostruzione e confronto: scripts/analysis/combine_portfolio.py.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from scripts.analysis.combine_portfolio import ( # noqa: E402
|
|
build_all_sleeves, port_returns, metrics, yearly_returns, SPLIT, OOS_DATE, IDX,
|
|
)
|
|
|
|
|
|
def run():
|
|
sleeves = {k: v for k, v in build_all_sleeves().items() if k.startswith("MR")}
|
|
pr = port_returns(sleeves)
|
|
full, oos = metrics(pr), metrics(pr, lo=SPLIT)
|
|
|
|
print("=" * 84)
|
|
print(f" PORT02 — FADE master (8 sleeve, equal-weight daily) | {IDX[0].date()} -> {IDX[-1].date()}")
|
|
print("=" * 84)
|
|
print(f" {'sleeve':<14s}{'Ret%':>9s}{'DD%':>7s}{'Shrp':>7s}")
|
|
for name, s in sleeves.items():
|
|
m = metrics(s.pct_change().fillna(0.0))
|
|
print(f" {name:<14s}{m['ret']:>+9.0f}{m['dd']:>7.1f}{m['sharpe']:>7.2f}")
|
|
print(" " + "-" * 80)
|
|
print(f" {'PORTAFOGLIO':<14s}{full['ret']:>+9.0f}{full['dd']:>7.1f}{full['sharpe']:>7.2f}"
|
|
f" CAGR {full['cagr']:.0f}%")
|
|
print(f" {' di cui OOS':<14s}{oos['ret']:>+9.0f}{oos['dd']:>7.1f}{oos['sharpe']:>7.2f}"
|
|
f" (da {OOS_DATE})")
|
|
pa = yearly_returns(pr)
|
|
print(" Per-anno: " + " ".join(f"{y}:{v:+.0f}%" for y, v in pa.items()))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|