Files
PythagorasGoal/scripts/strategies/ROT02_dual_momentum.py
T
Adriano 783fa5546f feat(analysis): miglioramenti - ROT02 dual-momentum + portafoglio (DD 12%)
Obiettivo: alzare Acc, ridurre DD, migliorare PnL. Leve oneste, no tuning per-anno.

- ROT02: overlay absolute-momentum (cash se BTC<SMA100) su ROT01. Domina su tutte
  le metriche: FULL +679->+1095%, OOS +44->+98%, DD 53->40%.
- DIP01 market-gate (variante low-DD): alza Acc (ETH 52->57, SOL 49->52) e dimezza
  il DD (ETH 53->23), al costo di PnL. De-risking opzionale; su BTC il gate va evitato.
- PORT01: portafoglio equal-weight giornaliero delle 3 sleeve anti-correlate
  (DIP01+TR01+ROT02). DD 12% (sotto ogni sleeve), CAGR 45%, 2022 bear -1% (era -30%).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 23:49:14 +02:00

41 lines
1.6 KiB
Python

"""ROT02 — Dual-Momentum Rotation (ROT01 + overlay di absolute momentum).
Evoluzione di ROT01: alla rotazione cross-sectional (forza relativa) aggiunge un
overlay di ABSOLUTE momentum sul mercato: se BTC e' sotto la sua media a `regime_n`
giorni (mercato risk-off), va completamente in CASH. Cosi' si evitano i bear di
sistema (2022, 2026 YTD) che erano gli unici anni rossi di ROT01.
Risultato (netto, fee 0.10% RT, gross 0.45, OOS = ultimo 30%): MIGLIORA TUTTO
rispetto a ROT01.
ROT01 base : FULL +679% / OOS +44% / DD 53%
ROT02 SMA100 : FULL +1095% / OOS +98% / DD 40% <-- PnL su, DD giu'
Param-insensitive sulla finestra di regime (SMA100-150). Dettagli in
scripts/analysis/honest_improve.py (rot_improved).
"""
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.honest_improve import rot_improved # noqa: E402
LOOKBACK, TOP_K, REGIME_N = 60, 2, 100
def run():
print("=" * 90)
print(f" ROT02 DUAL-MOMENTUM | 1d lb={LOOKBACK} top{TOP_K} + cash se BTC<SMA{REGIME_N} | netto fee 0.10% RT")
print("=" * 90)
full = rot_improved(lookback=LOOKBACK, top_k=TOP_K, regime_n=REGIME_N)
oos = rot_improved(lookback=LOOKBACK, top_k=TOP_K, regime_n=REGIME_N, oos_frac=0.30)
print(f" FULL: {full['ret']:+.0f}% DD {full['dd']:.0f}% ({full['pos_years']}/{full['n_years']} anni positivi)")
print(f" OOS : {oos['ret']:+.0f}% DD {oos['dd']:.0f}%")
print(" Per-anno: " + " ".join(f"{y}:{v:+.0f}%" for y, v in sorted(full["yearly"].items())))
if __name__ == "__main__":
run()