feat(ROT02): riduce il DD diversificando (top_k 2 -> 3)
ROT02 concentrava il book su 2 soli asset (DD 40%). top_k=3 dimezza quasi il DD (40% -> 26%) e ALZA il ritorno full (+1095 -> +1303%, ret/DD da 27 a 50). Il vol-target abbassa il DD ma sacrifica ritorno (de-leverage) -> tenuto top_k=3 senza VT. Caveat: OOS di ROT02 cala (+98 -> +68%, DD 12 -> 14%), ma il portafoglio MASTER migliora lo Sharpe full (3.95 -> 4.23). Applicato a ROT02_dual_momentum.py e a _rot_daily_equity (usata da PORT01/PORT03). Docstring/CLAUDE/diario aggiornati. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -126,17 +126,23 @@ paniere di 8 sleeve, contro il 20-70% del singolo. È la vera leva anti-drawdown
|
||||
honest (DIP/TR/ROT trend+rotazione multi-crypto) sono **quasi scorrelate**
|
||||
(correlazione cross-famiglia ~0.05). Combinarle in un unico portafoglio migliora il
|
||||
rischio/rendimento rispetto a ciascuna famiglia da sola: equal-weight dei 9 sleeve
|
||||
→ DD 5.2% full / 4.7% OOS e Sharpe OOS 4.42 (vs honest-only 12% DD / 2.23 Sharpe e
|
||||
fade-only 8.2% DD / 4.09 Sharpe), CAGR ~46% mantenuta. Studio in
|
||||
→ DD 5.2% full / 4.7% OOS e Sharpe 4.23 full / 4.33 OOS (vs honest-only 12.6% DD /
|
||||
2.20 Sharpe e fade-only 8.2% DD / 4.09 Sharpe), CAGR ~47% mantenuta. Studio in
|
||||
`scripts/analysis/combine_portfolio.py`.
|
||||
|
||||
**ROT02 — riduzione DD (top_k 2→3).** La rotazione dual-momentum honest concentrava
|
||||
il book su 2 soli asset (DD 40%). Diversificare su 3 (`top_k=3`) dimezza quasi il DD
|
||||
(40%→26%) e *alza* pure il ritorno full (+1095%→+1303%, ret/DD da 27 a 50); il
|
||||
vol-target abbassa il DD ma sacrifica ritorno, quindi si tiene top_k=3 senza VT.
|
||||
Applicato a `ROT02_dual_momentum.py` e a `_rot_daily_equity` (usata dai portafogli).
|
||||
|
||||
**Portafogli pronti (artefatti accorpati e migliorati).** Oltre a `PORT01` (solo
|
||||
honest), due script in `scripts/strategies/`:
|
||||
- `PORT02_fade_master.py` — le 3 fade × BTC/ETH accorpate (6 sleeve, filtro trend),
|
||||
equal-weight daily: DD ~8.2% full / 5.9% OOS, Sharpe 3.95/4.09, CAGR ~46%.
|
||||
- `PORT03_all_master.py` — portafoglio MASTER (fade + honest, 9 sleeve). Due varianti:
|
||||
`equal` (massimo Sharpe: DD 5.2%/4.7% OOS, Sharpe 3.95/4.42) e `5050` fra le due
|
||||
famiglie (minimo DD: 5.1% full / 4.3% OOS). È la configurazione consigliata.
|
||||
`equal` (massimo Sharpe: DD 5.2%/4.7% OOS, Sharpe 4.23/4.33) e `5050` fra le due
|
||||
famiglie (minimo DD: 5.0% full / 4.5% OOS). È la configurazione consigliata.
|
||||
Come `PORT01`, sono meta-portafogli (script `run()` di report), non `Strategy` con
|
||||
`generate_signals`, quindi non nel `strategy_loader`.
|
||||
|
||||
|
||||
@@ -47,3 +47,18 @@ favorevole pesa. Il target €50/giorno resta vincolato dal capitale: 43% CAGR s
|
||||
Prossimo passo: confermare il portafoglio combinato nel paper trader live.
|
||||
|
||||
**File:** `scripts/analysis/combine_portfolio.py` (nuovo).
|
||||
|
||||
## Pulizia roster + miglioria ROT02
|
||||
|
||||
- **Waste delle peggiori:** MR03 Keltner (fade più debole, Sharpe 1.22, ridondante
|
||||
con MR01 — rimuoverla *migliora* il portafoglio fade: DD 8.6→8.2, ret +549→+666)
|
||||
e ROT01 (dominata da ROT02). Spostate in `scripts/waste/`.
|
||||
- **Portafogli pronti:** `PORT02_fade_master` (6 sleeve fade) e `PORT03_all_master`
|
||||
(9 sleeve fade+honest, varianti equal/5050).
|
||||
- **ROT02 DD alto → migliorato:** la rotazione concentrava il book su 2 asset
|
||||
(DD 40%). Sweep su `rot_improved`: `top_k=3` dimezza quasi il DD (40%→26%) e
|
||||
*alza* il ritorno full (+1095→+1303%, ret/DD 27→50). Il vol-target abbassa il DD
|
||||
ma sacrifica ritorno (de-leverage) → tenuto top_k=3 senza VT. Caveat onesto:
|
||||
l'OOS di ROT02 cala un po' (+98→+68%, DD 12→14%), ma il MASTER (config deployata)
|
||||
migliora lo Sharpe full 3.95→4.23. Applicato a `ROT02_dual_momentum.py` e
|
||||
`_rot_daily_equity`. Sweep in `honest_improve.rot_improved`.
|
||||
|
||||
@@ -170,7 +170,7 @@ def _rot_daily_equity(idx):
|
||||
for i in range(101, T - 1):
|
||||
risk_on = btc[i] > bma[i] if not np.isnan(bma[i]) else False
|
||||
mom = P[i] / P[i - 60] - 1; order = np.argsort(mom)[::-1]
|
||||
chosen = [j for j in order if mom[j] > 0][:2] if risk_on else []
|
||||
chosen = [j for j in order if mom[j] > 0][:3] if risk_on else [] # top_k=3 (era 2): DD piu' basso
|
||||
nw = np.zeros(N)
|
||||
for j in chosen:
|
||||
nw[j] = 0.45 / len(chosen)
|
||||
|
||||
@@ -9,12 +9,12 @@ 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):
|
||||
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 +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
|
||||
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
|
||||
|
||||
@@ -11,12 +11,13 @@ Combinare le due famiglie migliora il rischio/rendimento rispetto a ciascuna da
|
||||
sola: il DD scende e lo Sharpe sale (la honest, da sola piu' lumpy, viene
|
||||
stabilizzata dalle fade ad alta frequenza). Vedi scripts/analysis/combine_portfolio.py.
|
||||
|
||||
Risultato (netto, equal-weight daily, finestra comune 2021-2026, OOS = ultimo 30%):
|
||||
Risultato (netto, equal-weight daily, finestra comune 2021-2026, OOS = ultimo 30%;
|
||||
ROT02 ora top_k=3 -> DD piu' basso):
|
||||
FADE only (6) DD 8.2% Sharpe 3.95 (OOS DD 5.9 / Shrp 4.09)
|
||||
HONEST only (3) DD 12.0% Sharpe 1.90 (OOS DD 6.5 / Shrp 2.23)
|
||||
MASTER eq (9) DD 5.2% Sharpe 3.95 (OOS DD 4.7 / Shrp 4.42) <- miglior Sharpe
|
||||
MASTER 50/50 DD 5.1% Sharpe 3.31 (OOS DD 4.3) <- miglior DD
|
||||
CAGR ~46% mantenuta in entrambe le varianti combinate.
|
||||
HONEST only (3) DD 12.6% Sharpe 2.20 (OOS DD 7.8 / Shrp 2.02)
|
||||
MASTER eq (9) DD 5.2% Sharpe 4.23 (OOS DD 4.7 / Shrp 4.33) <- miglior Sharpe
|
||||
MASTER 50/50 DD 5.0% Sharpe 3.69 (OOS DD 4.5) <- miglior DD
|
||||
CAGR ~47% mantenuta in entrambe le varianti combinate.
|
||||
|
||||
Due varianti operative selezionabili:
|
||||
weighting="equal" -> equal-weight sui 9 sleeve (massimo Sharpe)
|
||||
|
||||
@@ -8,9 +8,15 @@ 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).
|
||||
ROT02 k2 SMA100 : FULL +1095% / OOS +98% / DD 40% (versione iniziale)
|
||||
ROT02 k3 SMA100 : FULL +1303% / OOS +68% / DD 26% <-- DD quasi dimezzato, PnL su
|
||||
|
||||
MIGLIORIA DD (top_k 2 -> 3): la versione iniziale concentrava il book su 2 soli
|
||||
asset; diversificare su 3 dimezza quasi il drawdown (40% -> 26%) e ALZA pure il
|
||||
ritorno full (+1095 -> +1303), ret/DD da 27 a 50. Il vol-target abbassa il DD ma
|
||||
sacrifica ritorno (solo de-leverage), quindi si tiene top_k=3 senza vol-target.
|
||||
Param-insensitive: top_k 3-4 e regime SMA100-150 danno risultati simili.
|
||||
Dettagli e sweep in scripts/analysis/honest_improve.py (rot_improved).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -22,7 +28,7 @@ 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
|
||||
LOOKBACK, TOP_K, REGIME_N = 60, 3, 100 # top_k=3 (era 2): dimezza il DD
|
||||
|
||||
|
||||
def run():
|
||||
|
||||
Reference in New Issue
Block a user