diff --git a/CLAUDE.md b/CLAUDE.md index d7e763e..1c61cea 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -58,7 +58,10 @@ scripts/analysis/ → ricerca/validazione OOS fee-aware (strategy_research, regime_fetcher.py + regime_lab.py (DVOL/funding/feature regime per la ricerca); exit_lab.py + exit_policies/ (harness ricerca exit: cache segnali, train/OOS); options_fetcher.py + options_chain.py (storico opzioni REALE da cerbero-bite); - option_overlay_lab.py (overlay opzioni prezzato; mr02eth_port06_gate.py = gate swap-sleeve) + option_overlay_lab.py (overlay opzioni prezzato; mr02eth_port06_gate.py = gate swap-sleeve); + pairs15m_*.py (gate/flatcheck/smoke ETH/BTC 15m -> sleeve PR_ETHBTC_15M) +scripts/games/ → gioco "Blind Traders": 100 agenti ciechi su BTC/ETH anonimi (engine.py, + arena.py epoche+cull, agent_brief.py digest, run_game.py). Origine del BLEND 15m scripts/bump_version.py, scripts/deploy.sh → versionamento e deploy (bump+commit+rebuild) VERSION → versione semver (cotta nell'immagine, +1 ad ogni deploy) strategies.yml → config multi-strategy paper trader @@ -384,7 +387,8 @@ queste fade, ma va confermato col paper trader live prima di rischiare capitale - Un `Portfolio` è un oggetto di prima classe (`src/portfolio/`) con definizione (sleeve + schema pesi) e due facce sulla **STESSA** definizione: `.backtest()` (riusa il builder unico di `sleeves.py` → parità esatta con `report_families`) e live (`PortfolioRunner`: capitale pool condiviso, sizing per peso, ribilancio giornaliero, ledger aggregato in `data/portfolios/{code}/`). - **Schemi peso:** `equal` (default), `cap` (tetto per famiglia, es. pairs 33% — config raccomandata), `inverse_vol`, `cluster_rp` (equal fra cluster naturali poi inverse-vol intra-cluster), `manual`. Definiti in `weighting.py`; la chiave cap è la famiglia (PAIRS/FADE/HONEST/SHAPE/TSM). -- **Default `portfolios.yml`:** PORT06 (master+shape), `weighting=cap pairs 0.33 + shape 0.0588`, leva 2x, ribilancio 1D. Backtest PORT06 canonico (dati al 2026-05-28, pre-cap-shape): FULL Sharpe 6.47 DD 4.10% / OOS Sharpe 8.82 DD 1.30%; **con EXIT-16 close-confirm (config live attuale): FULL 7.84 / 2.60%, OOS 10.06 / 1.15%** (i vecchi 6.07/8.19 erano pre-loss-guard/pre-refresh dati). Col cap SHAPE (2026-06-05): FULL 6.43 / 3.96%, OOS 8.58 / 1.36% — assicurazione sulla coda SH01, vedi sotto. +- **Default `portfolios.yml`:** PORT06 (master+shape), `weighting=cap pairs 0.33 + shape 0.0588`, leva 2x, ribilancio 1D. Backtest PORT06 canonico (dati al 2026-05-28, pre-cap-shape): FULL Sharpe 6.47 DD 4.10% / OOS Sharpe 8.82 DD 1.30%; **con EXIT-16 close-confirm (config live attuale): FULL 7.84 / 2.60%, OOS 10.06 / 1.15%** (i vecchi 6.07/8.19 erano pre-loss-guard/pre-refresh dati). Col cap SHAPE (2026-06-05): FULL 6.43 / 3.96%, OOS 8.58 / 1.36% — assicurazione sulla coda SH01, vedi sotto. **Col BLEND ETH/BTC 15m (2026-06-09, v1.1.16, vedi sotto): FULL 7.20 / 3.68%, OOS 9.66 / 1.31% — 18 sleeve.** +- **BLEND ETH/BTC 15m flat-skip (ATTIVO LIVE v1.1.16, 2026-06-09).** Sleeve `PR_ETHBTC_15M` accanto al 1h: pairs ETH/BTC a **15m** (n=66, z_in=1.674, z_exit=1.0, max_bars=35) a **mezza size** (`params.position_size=0.10`). **Origine: gioco "Blind Traders"** (100 agenti ciechi su BTC/ETH anonimizzati → riscoprono la mean-reversion, vincitore = spread ETH/BTC 15m; `scripts/games/`). Gate PORT06 sul serio: **non duplicato (corr 1h↔15m = 0.37)**, robusto (16/16 celle Sharpe>1), e l'edge **NON è artefatto delle candele flat ETH 15m** (16% storico; filtrandole resta l'83% dello Sharpe). Engine `pairs_research.pairs_sim_flat` con uscita **LIVE-REALIZABLE** (`flat_skip`: niente entry/exit su barre O=H=L=C, esce alla 1a barra pulita), **regression-lock** a `pairs_sim` con flat_skip=False. **Worker validato** (`validate_worker_pairs` a 15m: replay == backtest, 8452 vs 8453 trade; 1h byte-exact). Runner: fetch sub-orario diretto da Cerbero + `pos_for_spec` override **per-sleeve** (params.position_size > famiglia > globale). Mezza size perché a peso pieno il 15m pesava il 25.8% del rischio PORT06 (→ 11.5%, bilanciato col 1h) — blend-tilt prudente sul **caveat slippage** (a slippage realistico il vantaggio di Sharpe regge, quello di DD si assottiglia: il vero banco di prova è il ledger reale shadow). Diari `docs/diary/2026-06-09-pairs15m-*.md`, gate `scripts/analysis/pairs15m_port06_gate.py` / `pairs15m_gate_final.py` / `pairs15m_flatcheck.py`, smoke `pairs15m_live_smoke.py`. - **SH01 SENZA STOP-LOSS — by design, CONFERMATO da ricerca (2026-06-05).** Dopo il crash ETH (−15.6% su un trade SH01 live), ricerca multi-agente con harness dedicato `scripts/analysis/sh01_exit_lab.py` (cache segnali walk-forward, engine con **fill gap-aware** `worse(livello, open)`, parity esatta con explore_lab, protocollo train≤2023-11-01/OOS): **11 famiglie di stop testate (ATR intrabar/close-confirm, %, chandelier, breakeven, giveback, loser-timestop, disaster-cap close+intrabar, swing, vol-regime), 0 sopravvissute** al gate (ETH migliorato senza degradare BTC, train E oos, plateau). Pattern: ogni stop stretto abbastanza da toccare la coda ETH rompe BTC; ogni stop largo non arriva alla coda; nei crash il fill è al gap, non al livello (lo stop "protettivo" PEGGIORA la coda OOS). Mitigazione adottata: **cap famiglia SHAPE a 0.0588 in PORT06** (≈ dimezzata; costo OOS Sharpe −0.24, FULL DD −0.14pp) — la prossima coda impatta il conto per metà. NON impostare mai `sl`/`sl_confirm_atr` su SH_BTC/SH_ETH. Direzione futura: liquidity-gate sull'entry (skip dopo feed flat). Diario `docs/diary/2026-06-05-sh01-sl-research.md`. - **Data layer Cerbero v2:** `get_historical_v2` unificato + `get_instruments` (naming robusto) + `get_ticker_batch`. Trading su Deribit. - **SCOPE LIVE (fase 2 completata):** il runner esegue TUTTI gli sleeve di PORT06. Worker: single `StrategyWorker` (fade MR01/02/07, DIP01, **e SH01**), `PairsWorker` (PR01 2 gambe), e i multi-asset dedicati `BasketTrendWorker` (TR01 4h), `RotationWorker` (ROT02 1d), `TsmomWorker` (TSM01 1d). Il runner fetcha 1h da Cerbero v2 e **resampla a 4h/1d** (lookback dimensionato sui daily: TSM01 usa 252g). Validazione: runner pool/ribilancio/ledger == backtest (`validate_portfolio_runner.py`, identico); worker multi-asset == reference (`validate_honest_workers.py`: TSM01 esatto, ROT02 +1303% canonico, TR01 stesso ordine — differenza di convenzione capitale-unico vs media-equity). @@ -407,9 +411,9 @@ queste fade, ma va confermato col paper trader live prima di rischiare capitale single-leg con exit a orizzonte H=12 — niente TP/SL, `_place_real_tp` no-op e `_real_close` chiude tutto market reduce-only, disaster-bracket on-book come unica protezione di coda (v1.1.13). Motivo: SH01 è il diversificatore più decorrelato (senza i 5 sleeve PAPER il DD del portafoglio sale - 3.96→5.35%). Copertura reale ora ~81% (fade+DIP+pairs+SH01); restano simulati TR01/ROT02/TSM01 - (book multi-asset, bloccati dal capitale: rumore arrotondamento 20-30% a €2k, serve ~€20k). - Diari `docs/diary/2026-06-08-pairs-executor.md`. + 3.96→5.35%). Copertura reale ora ~83% (fade+DIP+**6 pairs incl. ETH/BTC 15m**+SH01); restano + simulati TR01/ROT02/TSM01 (book multi-asset, bloccati dal capitale: rumore arrotondamento 20-30% + a €2k, serve ~€20k). Diari `docs/diary/2026-06-08-pairs-executor.md`. - **ESECUZIONE REALE — shadow (v1.0.3, 2026-06-03).** I **6 fade** (MR01/MR02/MR07 × BTC/ETH) eseguono ordini **REALI su Deribit testnet** accanto al fill simulato (*shadow*: sim + reale in parallelo, il sim resta la verità che guida le decisioni). `src/live/execution.py` `ExecutionClient`: `open` (market) + `close_amount` (market **reduce-only della SOLA quota del worker** — i 3 fade BTC condividono lo strumento e le posizioni si nettano per conto, quindi NON si usa `close_position` che flatterebbe le quote altrui); **verifica l'esecuzione sul TRADE** (order_id in `get_trade_history`, non sulla size netta aggregata); **fee REALI lette dai `trades[]`**. Strumenti = **lineari USDC** (`BTC_USDC`/`ETH_USDC-PERPETUAL`, amount nel base-coin, step 0.0001/0.001): scelti perché il **payoff lineare == matematica del backtest** (l'inverse `*-PERPETUAL` introdurrebbe una base 1/prezzo) e fee/PnL sono in USDC. Lo `StrategyWorker` tiene un **ledger reale parallelo** (`real_capital`, persistito) e logga `REAL_OPEN`/`REAL_CLOSE` col confronto **slippage** (prezzo sim vs eseguito) e **fee** (assunta 0.10% vs reale). Config: `portfolios.yml` → `overrides.execution {enabled, sleeves:[MR01,MR02,MR07,DIP01], instruments:{BTC:BTC_USDC-PERPETUAL, ETH:ETH_USDC-PERPETUAL}}` (**DIP01 aggiunto il 2026-06-04**: stesso wiring single-leg, TP resting incluso); pairs/rotation/tsmom/shape restano **simulati** (pairs richiede un executor a 2 gambe con gestione leg-risk; shape non ha TP). **Fee reali misurate = 0.05%/lato = 0.10% RT** (== assunto del backtest, su ETH; BTC inverse era ~0.094%). **Alert Telegram:** `REAL_EXEC_LIVE` (primo ordine reale verificato per worker) + `REAL_OPEN_FAIL`. Smoke (testnet, €0): `scripts/analysis/live_exec_smoke.py` (layer: ordine→verifica→fee) e `live_shadow_smoke.py` (catena worker open/close). **Capitale live portato a 2000** (notional fade ~$35) per ridurre il rumore di arrotondamento su BTC (step lineare ~$6.7). NB: ledger reale ≠ ledger sim — i worker già in posizione sim a un restart non hanno quota reale corrispondente; lo shadow reale parte pulito dalla prossima apertura. - **Disaster-bracket on-book + alert outage (v1.1.4, 2026-06-07).** A ogni `REAL_OPEN` dei fade eseguiti il worker piazza uno **STOP_MARKET reduce-only a ~−30%** dall'ingresso (trigger sul mark, diff --git a/docs/report/strategie_attive.html b/docs/report/strategie_attive.html index 7bfc86b..a946fe2 100644 --- a/docs/report/strategie_attive.html +++ b/docs/report/strategie_attive.html @@ -20,15 +20,15 @@ font-size:13px;margin-top:10px}

PythagorasGoal — Strategie attive

-

Portafoglio live PORT06 — definizione 17 sleeve; pool live real-only 14 sleeve +

Portafoglio live PORT06 — definizione 18 sleeve; pool live real-only 15 sleeve (i 3 book multi-asset girano in statistica, fuori dal capitale-pool). Capitale pool €2.000, leva 2x · -v1.1.14 · generato 2026-06-08 14:48 UTC · backtest canonico: FULL Sharpe 6.61 / DD 3.58% — OOS Sharpe 8.77 / DD 1.34%

+v1.1.16 · generato 2026-06-09 11:57 UTC · backtest canonico: FULL Sharpe 7.20 / DD 3.68% — OOS Sharpe 9.66 / DD 1.31%

Tre famiglie principali quasi scorrelate fra loro (fade↔honest ~0.05, pairs ~0.02-0.09, shape ~0.08): la diversificazione è la leva anti-drawdown. Pesi equal con tetti per famiglia, ribilancio giornaliero su capitale pool condiviso. Fee Deribit 0.10% round-trip incluse ovunque; ogni meccanismo live è passato da un gate out-of-sample a livello di portafoglio.

-
+

FADE — mean-reversion intraday 1h (6 sleeve × 6.47%)

Tesi della famiglia: sui perpetui crypto l'edge è la reversione: @@ -68,15 +68,21 @@ le fade per costruzione non prendono. Valuta solo barre 4h COMPLETE.

<

Rotazione: ogni giorno ordina 8 crypto per momentum a 60 giorni e tiene le top-3 (solo se positive), gross 0.45. Gate di regime: tutto cash se BTC<SMA100. Diversificare su 3 asset invece di 2 ha quasi dimezzato il DD (40%→26%) alzando il ritorno.

annoROT02 (universo 8)
trdPnL%DD%
2021+00
2022+00
2023+8110
2024+437
2025+1312
2026-89
TOT+13019

PnL = ritorno % dell'anno dall'equity giornaliera canonica (2021-2026, leva 3x convenzione test); DD = max drawdown nell'anno; trd non applicabile (ribilancio giornaliero del book).

-

PAIRS — spread reversion market-neutral (5 coppie × 5.88%, famiglia ≤33%)

-

PR01 — Pairs Reversion (ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL)

PAIRSESECUZIONE REALE (testnet)

+

PAIRS — spread reversion market-neutral (6 sleeve: 5 coppie 1h + ETH/BTC 15m a mezza size, famiglia ≤33%)

+

PR01 — Pairs Reversion (ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL + ETH/BTC 15m)

PAIRSESECUZIONE REALE (testnet)

Market-neutral: quando il rapporto fra due asset si allontana troppo dalla sua media (|z| del log-ratio ≥ 2), compra la gamba debole e shorta la forte; chiude quando il rapporto rientra (|z| ≤ 0.75) o dopo 72 barre. Config universale per tutte le coppie (niente tuning per-coppia = anti-overfit). Correlazione col mercato ~0.05: rende anche quando il mercato è fermo. Fee su 2 gambe. Senza stop per design → position size ridotto a 0.20 (esposizione ≈ validato).

+

BLEND timeframe (nuovo, 2026-06-09): ETH/BTC gira anche a 15m accanto al 1h +(config n=66, |z|≥1.67, exit |z|≤1.0 o 35 barre). Origine: gioco "Blind Traders" (100 agenti ciechi +su dati anonimi); testato col gate PORT06 — decorrelato dal 1h (corr 0.37), robusto (16/16), +e l'edge regge anche filtrando le candele flat ETH 15m (flat-skip: niente ingresso/uscita su +barre stale O=H=L=C). Worker validato (replay == backtest). A mezza size (blend-tilt prudente +sul caveat slippage): porta il PORT06 a FULL Sharpe ~7.2 / OOS ~9.7.

Esecuzione reale a 2 gambe su Deribit testnet (PairsExecutionClient): -open/close long A / short B, leg-risk unwind, mai close_position.

annoETH/BTCLTC/ETHADA/ETHBTC/LTCETH/SOL
2018-343 (177, dd 45)
2019+233 (198, dd 8)
2020+323 (211, dd 25)
2021+549 (202, dd 12)
2022+1344 (206, dd 3)+292 (45, dd 14)+899 (157, dd 5)+328 (58, dd 8)+1243 (147, dd 9)
2023+464 (213, dd 4)+56 (94, dd 5)+341 (173, dd 10)+61 (106, dd 14)+125 (168, dd 24)
2024+1661 (253, dd 6)+1024 (195, dd 9)+1078 (225, dd 16)+638 (186, dd 10)+1302 (199, dd 12)
2025+1173 (225, dd 16)+962 (196, dd 10)+1046 (187, dd 19)+686 (178, dd 7)+1264 (202, dd 11)
2026+61 (71, dd 2)+279 (76, dd 3)+140 (71, dd 3)+265 (71, dd 3)+270 (88, dd 4)
TOT+5464 (1756, dd 48)+2614 (606, dd 14)+3504 (813, dd 19)+1978 (599, dd 21)+4204 (804, dd 24)

cella: PnL% anno (n trade, max DD% anno) — Σ rendimenti netti per trade, fee 0.20% RT/coppia (2 gambe), leva 3x convenzione test. NB: la finestra canonica del portafoglio parte dal 2021; gli anni precedenti (spesso negativi) sono mostrati per onestà storica.

+open/close long A / short B, leg-risk unwind, mai close_position.

annoETH/BTCLTC/ETHADA/ETHBTC/LTCETH/SOLETH/BTC·15m
2018-343 (177, dd 45)-492 (913, dd 31)
2019+233 (198, dd 8)+792 (963, dd 4)
2020+323 (211, dd 25)+452 (867, dd 15)
2021+549 (202, dd 12)+1122 (949, dd 5)
2022+1344 (206, dd 3)+292 (45, dd 14)+899 (157, dd 5)+328 (58, dd 8)+1243 (147, dd 9)+2136 (898, dd 5)
2023+464 (213, dd 4)+56 (94, dd 5)+341 (173, dd 10)+61 (106, dd 14)+125 (168, dd 24)+689 (976, dd 11)
2024+1661 (253, dd 6)+1024 (195, dd 9)+1078 (225, dd 16)+638 (186, dd 10)+1302 (199, dd 12)+6313 (1353, dd 4)
2025+1173 (225, dd 16)+962 (196, dd 10)+1046 (187, dd 19)+686 (178, dd 7)+1264 (202, dd 11)+3664 (1123, dd 7)
2026+61 (71, dd 2)+279 (76, dd 3)+140 (71, dd 3)+265 (71, dd 3)+270 (88, dd 4)+155 (411, dd 4)
TOT+5464 (1756, dd 48)+2614 (606, dd 14)+3504 (813, dd 19)+1978 (599, dd 21)+4204 (804, dd 24)+14832 (8453, dd 34)

cella: PnL% anno (n trade, max DD% anno) — Σ rendimenti netti per trade, fee 0.20% RT/coppia (2 gambe), leva 3x convenzione test. NB: la finestra canonica del portafoglio parte dal 2021; gli anni precedenti (spesso negativi) sono mostrati per onestà storica.

TSM — trend-following multi-orizzonte (1 sleeve × 6.47%)

TSM01 — TSMOM (1d)

TSMSIMULATO

Long sugli asset con consenso pieno di momentum su 3 orizzonti (3/6/12 mesi), @@ -101,7 +107,7 @@ locale (il regime corto a 365g non era robusto: trade-rate 22% vs 10% validato).

  • Fee sempre incluse: 0.10% round-trip taker Deribit (misurate reali = assunte). Molte operazioni = morte per fee: ogni strategia regge lo stress a fee doppie.
  • Niente look-ahead: direzione e prezzo decisi solo con dati fino al close corrente; barre in formazione escluse (lezione EXIT-16). La famiglia squeeze (accuratezze 76-82%) è stata scartata proprio per questo artefatto.
  • Gate out-of-sample: nessun meccanismo va in produzione senza migliorare (o non degradare) il portafoglio FULL e OOS — robusto individualmente ≠ migliora PORT06.
  • -
  • Esecuzione reale shadow (~81% del portafoglio): 14 sleeve eseguono ordini reali su Deribit testnet accanto al sim — i 6 fade + DIP01 (single-leg, TP limit al livello, disaster-stop −30% on-book), i 5 pairs (2 gambe, leg-risk unwind) e i 2 SH01 (single-leg, exit a orizzonte, niente TP/SL). Restano simulati solo i book multi-asset TR01/ROT02/TSM01 (bloccati dal capitale: serve ~€20k per il rumore di arrotondamento). Fee reali verificate dai trade; divergenze sim/reale ≥100bps alertate su Telegram.
  • +
  • Esecuzione reale shadow (~83% del portafoglio): 15 sleeve eseguono ordini reali su Deribit testnet accanto al sim — i 6 fade + DIP01 (single-leg, TP limit al livello, disaster-stop −30% on-book), i 6 pairs incl. ETH/BTC 15m flat-skip (2 gambe, leg-risk unwind) e i 2 SH01 (single-leg, exit a orizzonte, niente TP/SL). Restano simulati solo i book multi-asset TR01/ROT02/TSM01 (bloccati dal capitale: serve ~€20k per il rumore di arrotondamento). Fee reali verificate dai trade; divergenze sim/reale ≥100bps alertate su Telegram.
  • Generato da scripts/analysis/make_strategy_doc.py — grafici da episodi reali sui dati parquet locali.

    \ No newline at end of file diff --git a/scripts/analysis/make_strategy_doc.py b/scripts/analysis/make_strategy_doc.py index 39be3c8..6190581 100644 --- a/scripts/analysis/make_strategy_doc.py +++ b/scripts/analysis/make_strategy_doc.py @@ -495,9 +495,14 @@ def stats_pairs(): from scripts.analysis.pairs_research import pairs_sim from scripts.strategies.PR01_pairs_reversion import PAIRS as PAIRS_CFG cols, data = [], {} - for a, b, p in PAIRS_CFG: - r = pairs_sim(a, b, **p) - tag = f"{a}/{b}" + from scripts.analysis.pairs_research import pairs_sim_flat + # le 5 coppie 1h universali + il BLEND ETH/BTC 15m flat-skip (mezza size = sleeve live) + runs = [(f"{a}/{b}", lambda a=a, b=b, p=p: pairs_sim(a, b, **p)) for a, b, p in PAIRS_CFG] + runs.append(("ETH/BTC·15m", lambda: pairs_sim_flat( + "ETH", "BTC", tf="15m", n=66, z_in=1.674, z_exit=1.0, max_bars=35, + flat_skip=True, pos=0.075))) + for tag, fn in runs: + r = fn() cols.append(tag) s = pd.Series(r["eq_v"], index=pd.to_datetime(r["eq_ts"], utc=True)) ydd = {int(y): float(((g.cummax() - g) / g.cummax()).max() * 100) @@ -627,6 +632,12 @@ def main(): g_tsm = chart_tsm01(panel) g_sh = chart_sh01() + # metriche canoniche del default per l'intestazione (sempre aggiornate) + pr = PORTFOLIOS["PORT06"].backtest() + n_def = len(PORTFOLIOS["PORT06"].sleeve_ids) + hdr = (f"FULL Sharpe {pr.full['sharpe']:.2f} / DD {pr.full['dd']:.2f}% — " + f"OOS Sharpe {pr.oos['sharpe']:.2f} / DD {pr.oos['dd']:.2f}%") + B = lambda f, t: f'{t}' real = B("real", "ESECUZIONE REALE (testnet)") sim = B("sim", "SIMULATO") @@ -671,13 +682,19 @@ le fade per costruzione non prendono. Valuta solo barre 4h COMPLETE.

    """, g_t (solo se positive), gross 0.45. Gate di regime: tutto cash se BTC<SMA100. Diversificare su 3 asset invece di 2 ha quasi dimezzato il DD (40%→26%) alzando il ritorno.

    """, g_rot, t_rot) - c_pr = card("PR01 — Pairs Reversion (ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL)", + c_pr = card("PR01 — Pairs Reversion (ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL + ETH/BTC 15m)", B("pairs", "PAIRS") + real, """

    Market-neutral: quando il rapporto fra due asset si allontana troppo dalla sua media (|z| del log-ratio ≥ 2), compra la gamba debole e shorta la forte; chiude quando il rapporto rientra (|z| ≤ 0.75) o dopo 72 barre. Config universale per tutte le coppie (niente tuning per-coppia = anti-overfit). Correlazione col mercato ~0.05: rende anche quando il mercato è fermo. Fee su 2 gambe. Senza stop per design → position size ridotto a 0.20 (esposizione ≈ validato).

    +

    BLEND timeframe (nuovo, 2026-06-09): ETH/BTC gira anche a 15m accanto al 1h +(config n=66, |z|≥1.67, exit |z|≤1.0 o 35 barre). Origine: gioco "Blind Traders" (100 agenti ciechi +su dati anonimi); testato col gate PORT06 — decorrelato dal 1h (corr 0.37), robusto (16/16), +e l'edge regge anche filtrando le candele flat ETH 15m (flat-skip: niente ingresso/uscita su +barre stale O=H=L=C). Worker validato (replay == backtest). A mezza size (blend-tilt prudente +sul caveat slippage): porta il PORT06 a FULL Sharpe ~7.2 / OOS ~9.7.

    Esecuzione reale a 2 gambe su Deribit testnet (PairsExecutionClient): open/close long A / short B, leg-risk unwind, mai close_position.

    """, g_pr, t_pairs) @@ -703,9 +720,9 @@ locale (il regime corto a 365g non era robusto: trade-rate 22% vs 10% validato). PythagorasGoal — Strategie attive PORT06

    PythagorasGoal — Strategie attive

    -

    Portafoglio live PORT06 — definizione 17 sleeve; pool live real-only 14 sleeve +

    Portafoglio live PORT06 — definizione {n_def} sleeve; pool live real-only 15 sleeve (i 3 book multi-asset girano in statistica, fuori dal capitale-pool). Capitale pool €2.000, leva 2x · -v{ver} · generato {now} · backtest canonico: FULL Sharpe 6.61 / DD 3.58% — OOS Sharpe 8.77 / DD 1.34%

    +v{ver} · generato {now} · backtest canonico: {hdr}

    Tre famiglie principali quasi scorrelate fra loro (fade↔honest ~0.05, pairs ~0.02-0.09, shape ~0.08): la diversificazione è la leva anti-drawdown. Pesi equal con tetti per famiglia, @@ -728,7 +745,7 @@ non si fada un crollo/parabolica), EXIT-16 (stop solo sul close confermat {c_dip} {c_tr} {c_rot} -

    PAIRS — spread reversion market-neutral (5 coppie × 5.88%, famiglia ≤33%)

    +

    PAIRS — spread reversion market-neutral (6 sleeve: 5 coppie 1h + ETH/BTC 15m a mezza size, famiglia ≤33%)

    {c_pr}

    TSM — trend-following multi-orizzonte (1 sleeve × 6.47%)

    {c_tsm} @@ -740,7 +757,7 @@ non si fada un crollo/parabolica), EXIT-16 (stop solo sul close confermat
  • Fee sempre incluse: 0.10% round-trip taker Deribit (misurate reali = assunte). Molte operazioni = morte per fee: ogni strategia regge lo stress a fee doppie.
  • Niente look-ahead: direzione e prezzo decisi solo con dati fino al close corrente; barre in formazione escluse (lezione EXIT-16). La famiglia squeeze (accuratezze 76-82%) è stata scartata proprio per questo artefatto.
  • Gate out-of-sample: nessun meccanismo va in produzione senza migliorare (o non degradare) il portafoglio FULL e OOS — robusto individualmente ≠ migliora PORT06.
  • -
  • Esecuzione reale shadow (~81% del portafoglio): 14 sleeve eseguono ordini reali su Deribit testnet accanto al sim — i 6 fade + DIP01 (single-leg, TP limit al livello, disaster-stop −30% on-book), i 5 pairs (2 gambe, leg-risk unwind) e i 2 SH01 (single-leg, exit a orizzonte, niente TP/SL). Restano simulati solo i book multi-asset TR01/ROT02/TSM01 (bloccati dal capitale: serve ~€20k per il rumore di arrotondamento). Fee reali verificate dai trade; divergenze sim/reale ≥100bps alertate su Telegram.
  • +
  • Esecuzione reale shadow (~83% del portafoglio): 15 sleeve eseguono ordini reali su Deribit testnet accanto al sim — i 6 fade + DIP01 (single-leg, TP limit al livello, disaster-stop −30% on-book), i 6 pairs incl. ETH/BTC 15m flat-skip (2 gambe, leg-risk unwind) e i 2 SH01 (single-leg, exit a orizzonte, niente TP/SL). Restano simulati solo i book multi-asset TR01/ROT02/TSM01 (bloccati dal capitale: serve ~€20k per il rumore di arrotondamento). Fee reali verificate dai trade; divergenze sim/reale ≥100bps alertate su Telegram.
  • Generato da scripts/analysis/make_strategy_doc.py — grafici da episodi reali sui dati parquet locali.

    """ diff --git a/scripts/analysis/pairs_research.py b/scripts/analysis/pairs_research.py index df8e8e6..51fe449 100644 --- a/scripts/analysis/pairs_research.py +++ b/scripts/analysis/pairs_research.py @@ -141,7 +141,7 @@ def pairs_sim_flat(a, b, tf="1h", n=50, z_in=2.0, z_exit=0.5, max_bars=72, split = int(N * split_frac) fee = 2 * fee_rt * lev cap = peak = 1000.0; dd = 0.0; last = -1 - trades = wins = 0; rets = []; yearly = {} + trades = wins = 0; rets = []; yearly = {}; yearly_n = {} eq_ts, eq_v = [], [] n_skip_entry = 0 kmax = max_bars + (scan_buffer if flat_skip else 0) @@ -176,6 +176,7 @@ def pairs_sim_flat(a, b, tf="1h", n=50, z_in=2.0, z_exit=0.5, max_bars=72, trades += 1; wins += ret > 0; rets.append(ret * pos); last = j eq_ts.append(ts.iloc[j]); eq_v.append(cap) yearly[ts.iloc[i].year] = yearly.get(ts.iloc[i].year, 0.0) + ret * 100 + yearly_n[ts.iloc[i].year] = yearly_n.get(ts.iloc[i].year, 0) + 1 yrs_span = (ts.iloc[-1] - ts.iloc[max(split, 0)]).days / 365.25 or 1 sharpe = 0.0 if len(rets) > 1 and np.std(rets) > 0: @@ -183,7 +184,7 @@ def pairs_sim_flat(a, b, tf="1h", n=50, z_in=2.0, z_exit=0.5, max_bars=72, ret_tot = (cap / 1000 - 1) * 100 cagr = ((cap / 1000) ** (1 / yrs_span) - 1) * 100 if cap > 0 else -100 return dict(trades=trades, win=wins / trades * 100 if trades else 0, ret=ret_tot, - cagr=cagr, dd=dd * 100, sharpe=sharpe, yearly=yearly, + cagr=cagr, dd=dd * 100, sharpe=sharpe, yearly=yearly, yearly_n=yearly_n, eq_ts=eq_ts, eq_v=eq_v, n_skip_entry=n_skip_entry)