feat(explore): esplora 9 famiglie alternative -> PAIRS (nuovo edge forte) + TSM01
Esplorazione onesta con agenti paralleli su harness condiviso (explore_lab.py): ingresso close[i], netto fee, OOS, DD basso, attenzione fee. 7 famiglie su 9 sono rumore (stagionalita' oraria/mensile, cross-sectional reversal, opening-range, lead-lag BTC->alt, continuation intraday) e l'harness le rifiuta senza falsi positivi. Due edge reali verificati indipendentemente: - PR01 Pairs: spread reversion market-neutral su log-ratio z-score (ETH/BTC, LTC/ETH, ADA/ETH). ETH/BTC CAGR 144% Sharpe 4.04 OOS DD 17% 8/9 anni, corr mercato ~0.02, no-look-ahead verificato, regge fee 0.40%/coppia. Fee su 2 gambe (worker da estendere). - TSM01: TSMOM multi-orizzonte 3/6/12m + risk-off, distinto da ROT02 (corr 0.53), DD 22%/12% OOS, mai un anno negativo, regge fee 0.40%. Payoff: aggiungere i pairs (quasi scorrelati ~0.05) al MASTER -> CAGR 47->66%, DD 5.2->3.8% full / 4.7->3.3% OOS, Sharpe OOS 4.33->6.86 (combine_v2.py). Fix: explore_lab.get_df ora produce timestamp ms reale per 1d/4h (era placeholder). Diario 2026-05-29-exploration.md + nota CLAUDE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
"""Combina i NUOVI edge (pairs + TSM01) col MASTER esistente: migliora il portafoglio?
|
||||
|
||||
Aggiunge al MASTER a 9 sleeve (6 fade + 3 honest) due nuove fonti scoperte
|
||||
nell'esplorazione, poco correlate:
|
||||
- PAIRS market-neutral (ETH/BTC, LTC/ETH, ADA/ETH) -> corr ~0 col mercato
|
||||
- TSM01 (TSMOM multi-orizzonte + risk-off) -> corr ~0.53 con ROT02
|
||||
|
||||
Misura correlazione delle nuove sleeve vs esistenti e confronta MASTER-9 vs
|
||||
MASTER-esteso su Ret/CAGR/DD/Sharpe, FULL e OOS (finestra comune 2021-2026).
|
||||
"""
|
||||
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.combine_portfolio import (
|
||||
build_all_sleeves, port_returns, metrics, yearly_returns, SPLIT, OOS_DATE, IDX,
|
||||
)
|
||||
from scripts.analysis.honest_improve2 import _daily_equity, _norm
|
||||
from scripts.analysis.pairs_research import pairs_sim
|
||||
from scripts.analysis.tsmom_research import tsmom_sim
|
||||
|
||||
|
||||
def daily_from(eq_ts, eq_v):
|
||||
return _norm(_daily_equity(eq_ts, eq_v, IDX))
|
||||
|
||||
|
||||
def main():
|
||||
print("Costruzione equity (puo' richiedere ~1-2 min)...\n")
|
||||
S = build_all_sleeves() # 9 sleeve esistenti
|
||||
|
||||
# nuove sleeve
|
||||
new = {}
|
||||
for a, b in [("ETH", "BTC"), ("LTC", "ETH"), ("ADA", "ETH")]:
|
||||
r = pairs_sim(a, b, n=50, z_in=2.0, z_exit=0.5, max_bars=72)
|
||||
new[f"PR_{a}{b}"] = daily_from(r["eq_ts"], r["eq_v"])
|
||||
t = tsmom_sim()
|
||||
new["TSM01"] = daily_from(t["eq_ts"], t["eq_v"])
|
||||
|
||||
allS = {**S, **new}
|
||||
|
||||
# --- correlazione nuove vs esistenti ---
|
||||
dr = pd.DataFrame({k: v.pct_change().fillna(0.0) for k, v in allS.items()})
|
||||
corr = dr.corr()
|
||||
old_k = list(S); new_k = list(new)
|
||||
print("=" * 88)
|
||||
print(" CORRELAZIONE rendimenti giornalieri — NUOVE (righe) vs media esistenti")
|
||||
print("=" * 88)
|
||||
for nk in new_k:
|
||||
avg = corr.loc[nk, old_k].mean()
|
||||
mx = corr.loc[nk, old_k].abs().max()
|
||||
print(f" {nk:<12s} corr media col MASTER-9 = {avg:+.2f} |max| = {mx:.2f}")
|
||||
|
||||
# --- confronto portafogli ---
|
||||
def line(label, members):
|
||||
pr = port_returns(members)
|
||||
f, o = metrics(pr), metrics(pr, lo=SPLIT)
|
||||
print(f" {label:<26s}{f['ret']:>+9.0f}{f['cagr']:>7.0f}{f['dd']:>7.1f}{f['sharpe']:>7.2f}"
|
||||
f" | {o['ret']:>+9.0f}{o['dd']:>7.1f}{o['sharpe']:>7.2f}")
|
||||
return pr
|
||||
|
||||
print("\n" + "=" * 96)
|
||||
print(f" MASTER-9 vs MASTER-ESTESO (con pairs+TSM01) | OOS da {OOS_DATE} | equal-weight daily")
|
||||
print("=" * 96)
|
||||
print(f" {'portafoglio':<26s}{'Ret%':>9s}{'CAGR':>7s}{'DD%':>7s}{'Shrp':>7s}"
|
||||
f" | {'oRet%':>9s}{'oDD%':>7s}{'oShrp':>7s}")
|
||||
print(" " + "-" * 92)
|
||||
line("MASTER-9 (base)", S)
|
||||
line("MASTER +pairs (12)", {**S, **{k: v for k, v in new.items() if k.startswith('PR_')}})
|
||||
line("MASTER +TSM01 (10)", {**S, "TSM01": new["TSM01"]})
|
||||
pr_all = line("MASTER-esteso (13)", allS)
|
||||
print(" " + "-" * 92)
|
||||
pa = yearly_returns(pr_all)
|
||||
print(" MASTER-esteso per-anno: " + " ".join(f"{y}:{v:+.0f}%" for y, v in pa.items()))
|
||||
print("\n Se il MASTER-esteso ha DD piu' basso e/o Sharpe piu' alto del MASTER-9, le nuove")
|
||||
print(" famiglie aggiungono valore (diversificazione da fonti scorrelate).")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user