Files
PythagorasGoal/docs/diary/2026-06-07-pairspos-gate.md
T
Adriano Dal Pastro 6097205694 feat(pairs): position_size per-famiglia, PAIRS 0.5->0.20 (gate PORT06)
Punto 8 roadmap sweep. La famiglia pairs (SENZA stop, validata a pos 0.15 lev 3 =
esposizione 0.45) girava col position_size globale 0.5 a leva 2 = esposizione 1.0,
~2.2x il validato (ETH/BTC DD grezzo 78% a quella taglia; live: ADA/ETH -4.26%
sleeve in un trade il 2026-06-05).

Gate pairspos_port06_impact.py (pairs_sim alla leva live 2x, parita' canonica
1.00000 5/5, PORT06 pesi cap): griglia pos {0.5, 0.25, 0.20, 0.15}. Il gate
meccanico boccia ogni riduzione (costa OOS Sharpe — il compounding in-sample a 0.5
e' fantasia: +2.6e9% ETH/BTC), ma 0.20 e' il ginocchio del trade-off: OOS DD
3.40->1.26% (meglio anche di 0.15), famiglia DD 14->5.8%, costo OOS Sharpe
9.05->8.43. Decisione assicurativa (utente), come il precedente cap SHAPE.

- runner.pos_for_spec(sid, global, family_overrides): override per-famiglia
  (chiave weighting.family_of), plumbato in build_worker_for.
- portfolios.yml: position_size_family {PAIRS: 0.20} (globale 0.5 invariato).
- Test: pos_for_spec mapping + PairsWorker.position_size (74/74 verdi).

Nota transizione: la posizione LTC/ETH aperta verra' chiusa col pos nuovo
(one-time). Diario docs/diary/2026-06-07-pairspos-gate.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 10:44:15 +00:00

2.4 KiB
Raw Blame History

2026-06-07 — Gate position_size PAIRS: 0.5 → 0.20 (assicurazione, come il cap SHAPE)

Punto 8 della roadmap improvement-sweep: i pairs giravano col position_size GLOBALE 0.5 a leva 2 (esposizione 1.0 della fetta) mentre TUTTA la validazione PR01 è a pos 0.15 lev 3 (esposizione 0.45) — ~2.2x il validato su una famiglia senza stop (exit solo |z|≤z_exit o max_bars). Scelta deliberata (commento yml) ma mai gateata. Evidenza live: ADA/ETH 2026-06-05 net 8.52% = 4.26% di sleeve in un trade.

Metodo

scripts/analysis/pairspos_port06_impact.py: le 5 equity pairs ricostruite con pairs_sim alla leva live (2x) su griglia pos {0.50, 0.25, 0.20, 0.15}, innestate nel PORT06 canonico (pesi cap PAIRS 0.33 + SHAPE 0.0588). Parità verificata: pairs_sim(0.15, lev3) == equity canoniche (corr 1.00000, 5/5).

Risultati

pos esp. FULL Sh / DD CAGR OOS Sh / DD fam DD worst pair DD grezzo
0.50 (live) 1.00 6.69 / 4.77% 130% 9.05 / 3.40% 14.0% ETH/BTC 78%
0.25 0.50 6.50 / 4.04% 67% 8.69 / 1.54% 7.2% 51%
0.20 0.40 6.33 / 3.90% 57% 8.43 / 1.26% 5.8% 44%
0.15 0.30 6.03 / 3.78% 47% 7.99 / 1.33% 4.3% 35%

Letture:

  • Il gate meccanico (OOS Sharpe non peggiora) boccia ogni riduzione: ovvio — ridurre l'esposizione di una famiglia che in-sample non è mai esplosa costa sempre Sharpe. Ma il +130% CAGR / +2.6e9% compounded di ETH/BTC a pos 0.5 è fantasia da compounding: dice solo che il tail event non è ancora successo in-sample.
  • 0.20 è il ginocchio: OOS DD 1.26% batte anche 0.15 (1.33% — oltre il ginocchio si taglia ritorno senza guadagnare DD); esposizione 0.40 ≈ il validato 0.45.
  • Decisione di tipo assicurativo, identica al precedente cap SHAPE (adottato pagando 0.24 OOS Sharpe).

Decisione (utente): pos PAIRS = 0.20

Implementazione:

  • runner.pos_for_spec(sid, global_ps, family_overrides) — override per-famiglia (chiave = weighting.family_of), plumbato in build_worker_for.
  • portfolios.yml: position_size_family: {PAIRS: 0.20} (globale 0.5 invariato per fade/dip/shape).
  • Test: test_pos_for_spec_family_override, test_build_pairs_worker_position_size.

Nota di transizione: la posizione LTC/ETH aperta al deploy (entrata a sizing 0.5) verrà chiusa col pos nuovo 0.20 → il pnl % sleeve di quel singolo trade è bookato alla taglia nuova (one-time, conservativo).