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>
66 lines
2.8 KiB
Python
66 lines
2.8 KiB
Python
"""PORT01 — Portafoglio combinato delle 3 strategie oneste (equal-weight, daily rebal).
|
|
|
|
Sleeve (meccanismi anti-correlati):
|
|
DIP01 dip-buy reversion su BTC (1h) regime: reversione
|
|
TR01 EMA 20/100 trend su paniere (4h) regime: momentum singolo
|
|
ROT02 dual-momentum rotation (1d) regime: forza relativa + risk-off
|
|
|
|
La diversificazione e' il vero motore di risk-reduction: il DD del portafoglio
|
|
scende SOTTO quello della sleeve meno rischiosa, mantenendo una CAGR alta e
|
|
azzerando quasi gli anni negativi (il 2022 bear passa da -30% di ROT a -1%).
|
|
|
|
Risultato (netto, 2021-2026, leva 3x pos 15% per sleeve; ROT02 ora top_k=3):
|
|
DIP01_BTC +322% DD 15% CAGR 31%
|
|
TR01_basket +591% DD 27% CAGR 43%
|
|
ROT02_dualmom +984% DD 26% CAGR 56% (top_k=3: DD 40->26, PnL su)
|
|
PORTAFOGLIO +676% DD 13% CAGR 46% <-- DD piu' basso di ogni sleeve
|
|
Per-anno: 2021 +224 · 2022 +1 · 2023 +48 · 2024 +48 · 2025 +10 · 2026 -2
|
|
Logica e ricostruzione: scripts/analysis/honest_improve2.py.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pandas as pd
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from scripts.analysis.honest_improve import _dd # noqa: E402
|
|
from scripts.analysis.honest_improve2 import ( # noqa: E402
|
|
dip_market_gated, _daily_equity, _norm, _tr_basket_daily, _rot_daily_equity,
|
|
)
|
|
|
|
|
|
def run():
|
|
idx = pd.date_range("2021-01-01", "2026-05-26", freq="1D", tz="UTC")
|
|
d = dip_market_gated("BTC", market_n=0, return_equity=True)
|
|
members = {
|
|
"DIP01_BTC": _norm(_daily_equity(d["eq_ts"], d["eq_v"], idx)),
|
|
"TR01_basket": _norm(_tr_basket_daily(["BNB", "BTC", "DOGE", "SOL", "XRP"], idx)),
|
|
"ROT02_dualmom": _norm(_rot_daily_equity(idx)),
|
|
}
|
|
drets = pd.DataFrame({k: v.pct_change().fillna(0) for k, v in members.items()})
|
|
port_ret = drets.mean(axis=1)
|
|
combo = (1 + port_ret).cumprod()
|
|
yrs = (idx[-1] - idx[0]).days / 365.25
|
|
|
|
print("=" * 80)
|
|
print(f" PORT01 — portafoglio equal-weight (daily rebal) | {idx[0].date()} -> {idx[-1].date()}")
|
|
print("=" * 80)
|
|
print(f" {'sleeve':<16s}{'ret%':>9s}{'DD%':>7s}{'CAGR%':>8s}")
|
|
for name, s in members.items():
|
|
r = (s.iloc[-1] / s.iloc[0] - 1) * 100
|
|
cagr = ((s.iloc[-1] / s.iloc[0]) ** (1 / yrs) - 1) * 100
|
|
print(f" {name:<16s}{r:>+9.0f}{_dd(s.values):>7.0f}{cagr:>8.0f}")
|
|
r = (combo.iloc[-1] / combo.iloc[0] - 1) * 100
|
|
cagr = ((combo.iloc[-1] / combo.iloc[0]) ** (1 / yrs) - 1) * 100
|
|
print(f" {'PORTAFOGLIO':<16s}{r:>+9.0f}{_dd(combo.values):>7.0f}{cagr:>8.0f}")
|
|
pa = port_ret.groupby(port_ret.index.year).apply(lambda x: ((1 + x).prod() - 1) * 100)
|
|
print(" Per-anno: " + " ".join(f"{y}:{v:+.0f}%" for y, v in pa.items()))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|