Files
PythagorasGoal/scripts/strategies/PR01_pairs_reversion.py
T
Adriano 945c2a2db6 feat(explore): 3a ondata - PAIRS a 6 coppie + verdetti su 4 nuove famiglie
Espansione dei meccanismi provati + 2 nuovi sondaggi (agenti paralleli, honest):
- PAIRS espansa a 6 coppie robuste: + BTC/LTC (robusta 1h E 4h, Sharpe 2.21, DD 24-34%),
  ETH/SOL e BNB/ETH (Sharpe 2.4+, solo 1h). Pattern: alt-liquido vs major.
- Fade su 6 alt: 0 robuste (mean-reversion vive solo su BTC/ETH; DOGE = artefatto).
- Low-vol anomaly: invertita in cripto (vince alta vol), ridondante -> scartata.
- Confluenza multi-TF: dimezza il DD di MR01 (ETH same Sharpe a DD 38% vs 63%) ->
  variante low-DD utile, non edge nuovo.

MASTER + 6 pairs (15 sleeve): CAGR 47->71%, OOS DD 4.7->2.3%, Sharpe OOS 4.33->7.71,
tutti gli anni positivi. Bilancio robusti: famiglia PAIRS (6) + TSM01 = 7 strategie nuove.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 01:13:54 +02:00

67 lines
3.4 KiB
Python

"""PR01 — Pairs / Spread Mean-Reversion fra cripto (market-neutral). FAMIGLIA NUOVA.
Distinta da tutto l'esistente (single-asset direzionale): scommette sul RIENTRO del
log-ratio di due cripto verso la sua media. Market-neutral (long A / short B) ->
correlazione ~0.02 col mercato -> diversificatore prezioso.
Logica (engine onesto verificato in scripts/analysis/pairs_research.py):
r[i] = log(closeA[i]/closeB[i]); z[i] = (r[i]-SMA_n(r)[i]) / STD_n(r)[i] (causale)
z <= -z_in -> LONG ratio (long A / short B)
z >= +z_in -> SHORT ratio (short A / long B)
EXIT: |z| <= z_exit (rientro) o time-limit max_bars. Ingresso/uscita a close.
Fee su 2 GAMBE = 2*fee_rt*lev (0.20% RT/coppia). Filtro candele sporche (salto>8%).
Validazione (netto, fee 0.20% RT/coppia reale a 2 gambe, leva 3x, OOS = ultimo 30%,
n=50 z_in=2.0 z_exit=0.5 max_bars=72, 1h):
ETH/BTC : CAGR 144% / OOS DD 17% / Sharpe 4.04 / win 74% / 8/9 anni positivi
LTC/ETH : CAGR 71% / OOS DD 10% / Sharpe 2.52 / 7/8 anni positivi
ADA/ETH : CAGR 77% / OOS DD 11% / Sharpe 2.16 / 7/8 anni positivi
No look-ahead verificato (z[i] invariato perturbando il futuro). Regge fee 0.40% RT/coppia.
Correlazione con BTC daily ~0.02 -> davvero market-neutral.
LIMITE OPERATIVO: e' una strategia a 2 gambe (long un perp + short l'altro), il worker
attuale e' single-leg. Per tradarla serve: (a) eseguibilita' short del perp B su
Deribit/Bybit, (b) gestione 2 ordini + fee doppie. Finche' il worker non supporta
2 gambe, PR01 resta validata in backtest ma non wired nel paper trader.
"""
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.pairs_research import pairs_sim, OOS_FRAC # noqa: E402
# Coppie robuste (config migliore per ognuna). Sempre alt-liquido vs major (mai alt/alt).
# Le prime 3 dal primo lotto; BTC/LTC (anche 4h), ETH/SOL, BNB/ETH dall'espansione.
PAIRS = [
("ETH", "BTC", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)),
("LTC", "ETH", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)),
("ADA", "ETH", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)),
("BTC", "LTC", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)), # NUOVA: robusta 1h E 4h
("ETH", "SOL", dict(n=50, z_in=2.0, z_exit=1.0, max_bars=72)), # NUOVA: solo 1h
("BNB", "ETH", dict(n=30, z_in=2.0, z_exit=1.0, max_bars=72)), # NUOVA: solo 1h
]
def run():
print("=" * 92)
print(" PR01 — PAIRS spread reversion (market-neutral) | netto fee 0.20% RT/coppia, leva 3x")
print("=" * 92)
print(f" {'coppia':<10s}{'trd':>5s}{'win%':>6s}{'CAGR%':>7s}{'OOS DD%':>8s}{'DD%':>6s}{'Shrp':>6s}{'anni+':>7s}")
for a, b, p in PAIRS:
f = pairs_sim(a, b, **p)
o = pairs_sim(a, b, **p, split_frac=1 - OOS_FRAC)
yrs = f["yearly"]; pos_y = sum(1 for v in yrs.values() if v > 0)
print(f" {a+'/'+b:<10s}{f['trades']:>5d}{f['win']:>6.1f}{f['cagr']:>7.0f}{o['dd']:>8.0f}"
f"{f['dd']:>6.0f}{f['sharpe']:>6.2f}{f'{pos_y}/{len(yrs)}':>7s}")
print("\n Market-neutral (corr ~0.02-0.08 col mercato) -> ottimo diversificatore di portafoglio.")
print(" Pattern: solo alt-liquido vs major (BTC/ETH); alt-vs-alt e' rumore.")
print(" NB: 2 gambe (long A / short B), fee doppie. Worker live da estendere prima del live.")
if __name__ == "__main__":
run()