"""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): DIP01_BTC +322% DD 15% CAGR 31% TR01_basket +591% DD 27% CAGR 43% ROT02_dualmom +771% DD 40% CAGR 49% PORTAFOGLIO +642% DD 12% CAGR 45% <-- DD piu' basso di ogni sleeve Per-anno: 2021 +203 · 2022 -1 · 2023 +47 · 2024 +50 · 2025 +14 · 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()