bcccfde9a0
Crea gli artefatti accorpati e migliorati: - PORT02_fade_master: 3 fade (MR01/MR02/MR07) x BTC/ETH = 6 sleeve, filtro trend, equal-weight daily. DD 8.2% full / 5.9% OOS, Sharpe 3.95/4.09, CAGR ~46%. - PORT03_all_master: portafoglio MASTER fade+honest (9 sleeve), varianti equal (max Sharpe: DD 5.2%/4.7% OOS, Sharpe 3.95/4.42) e 50/50 (min DD 5.1%/4.3%). Sposta in scripts/waste/ le due peggiori: - MR03 keltner_fade: fade piu' debole (BTC Sharpe 1.22), ridondante con MR01, il filtro trend la peggiorava; rimuoverla MIGLIORA il portafoglio fade. - ROT01 xsect_rotation: strettamente dominata da ROT02 (stesso meccanismo, ROT02 meglio su tutto), non usata da alcun portafoglio. Sganciata MR03 da strategy_loader, strategies.yml e dal motore portafogli (risk_management.STRATS). La funzione keltner_fade resta in strategy_research_v2 come record. CLAUDE.md aggiornato. 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()
|