Files
PythagorasGoal/docs/diary/2026-07-01-alt-breadth-internals.md
T
Adriano Dal Pastro 491411ac77 research(wave-0701): 6 filoni multi-agente — 0 nuovi sleeve, pesi confermati, gate weights_tilt_null
Ondata onesta su angoli non coperti: funding-TS (chiude il filone funding su 3
lati), breadth alt (non-ridondante ma DSR 0.43, rivisitabile con storia),
XS-residmom (REDUNDANT), pesi+guardia-DD (EW-STR refutato dallo scettico come
selezione-sull'hold-out di 2° ordine, firma best-of-15), VRP-refine (filone
esaurito), stagionalità-XS (morta allo step statistico).

Lezione codificata: weights_tilt_null + combine_outer in src/portfolio
(ogni cambio-pesi vs null di tilt casuali cap-respecting + delta in-sample>=0);
5 test nuovi, suite 165/165.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-01 23:21:59 +00:00

6.3 KiB
Raw Blame History

2026-07-01 — Breadth / market-internals del mercato ALT come segnale su BTC/ETH — SCARTATO

Tesi. Gli "internals" del mercato crypto — la partecipazione degli alt — come segnale direzionale o gate di de-risk su BTC/ETH perp (2 gambe, eseguibile a ~$600): % di alt sopra la propria SMA(N), advance/decline, % di alt che battono BTC (risk-appetite relativo), breadth-thrust. Script scripts/research/r0701_breadth_internals.py (non committato per policy del filone; harness altlib). Dati: i 51 parquet certificati data/raw/hl_*_1d.parquet → panel di 49 alt (esclusi hl_btc/hl_eth dalla breadth; hl_btc solo come riferimento per la famiglia RS), barre a volume 0 mascherate (lezione backfill 2026-06-20; il fetch le aveva già ripulite: vol0=0 su tutti i file, gate comunque attivo).

Limite strutturale dichiarato in partenza: l'universo HL parte dal 2024-01 → dopo il warmup (max 120g) la finestra comune è 2024-05-05 → 2026-07-01 (~2.2 anni) e l'in-sample pre-HOLDOUT è ~8 mesi del toro 2024. Qualunque esito poteva essere al massimo un lead.

Famiglie e griglia (108 celle, tutte contate nel deflated Sharpe)

4 famiglie × N∈{20,50,100} × soglia∈{0.3,0.5,0.7} × forma∈{LS, long-flat, gate-su-TP01}:

  • FAM-MA: % di alt validi con close > SMA(N) (breadth classica).
  • FAM-AD: frazione di advancers (ret 1g>0), SMA(N).
  • FAM-RS: % di alt che battono BTC sul ritorno a N giorni (≈ market-neutral, l'angolo più ortogonale).
  • FAM-TH: breadth-thrust = Δ a N giorni della breadth MA20 (thrust/collapse), score 0.5+Δ.

Tutte causali (rolling/shift soltanto), MIN_VALID=20 asset per data (osservato: 42-49). LS/LF vol-target 20% cap 2x (sizing TP01-style); GATE = posizione TP01 × gate binario. Fee 0.10% RT + sweep 0-0.30%. Procedura onesta = mirror di study_family_honest sulla finestra comune (il padding pre-2024 avrebbe contaminato il ranking full-history: le celle GATE con gate=1 pre-storia erediterebbero lo Sharpe 2019-2024 di TP01): cella scelta col SOLO Sharpe in-sample, DSR su tutti i trial, marginal_vs_tp01 di altlib sulla cella scelta.

⚠️ Bug trovato e corretto: allineamento merge_asof su indice non-ns

La prima versione di _align usava b.index.view("int64")//10**6 per i timestamp della breadth: su un DatetimeIndex tz-aware a risoluzione non-ns (pandas 2.x) la scala esce sbagliata → merge_asof backward matchava OGNI barra BTC/ETH all'ultimo valore della breadth = il futuro broadcast su tutta la storia. Sintomo: decine di celle con lo stesso identico Sharpe (il segnale era una costante). causality_ok NON lo vede — la serie breadth è un input esterno fisso, quindi il target sul prefisso troncato coincide col target full per costruzione. Fix: epoca esplicita (idx - Timestamp(1970, tz=UTC)) // Timedelta(1ms) (come resample_tf). Lezione harness: ogni allineamento di un panel esterno via merge_asof va fatto con epoch-ms esplicita, e il sintomo "molte celle con Sharpe identico" è un red-flag di allineamento rotto (gemella dell'osservazione merge_asof del 2026-06-20).

Esito (procedura onesta, finestra comune 2024-05+)

104/108 celle valutabili (4 degeneri flat), 47 con FULL>0. Cella scelta in-sample (IS 2.11, la selezione non tocca mai l'hold-out): TH N=100 thr=0.7 long-flat — long solo dopo un breadth-thrust (+0.2 di breadth MA20 in 100g), attiva il 32% dei giorni.

metrica valore
standalone finestra comune IS +2.11 → FULL +0.99, HOLD +0.41
assoluto (per-asset, trimmed) PASS — minFull +0.68, minHold +0.38, fee-survive 0.30%RT, DD 7-11%
marginale vs TP01 ADDS — corr full 0.401/hold 0.358, resid Sharpe 0.87, multicut {2025:+0.076, 2026:+0.366} persistente, is_hedge=False
robust_oos False — jackknife drop-best-month 0.068 (l'uplift hold-out sta in piedi su UN mese)
deflated Sharpe 0.433 su 104 trial (null-max atteso 1.10) — lontanissimo dal PASS ≥0.95
earns_slot / earns_slot_honest False / False
causality_ok True (post-fix)
smallcap $600 haircut ≈ 0.00 (BTC 0.01, ETH +0.00; 137-152 trade) — eseguibile

Ridondanza col trend (il rischio n.1, lezione macro-gate): qui NON è la modalità di morte. corr(pos, TP01pos) 0.15-0.30 e il segnale "lavora" (off mentre TP01 non è flat) nel 24-32% dei giorni (il macro-gate lavorava nel 2-3%). Le forme direzionali LS/LF sono genuinamente diverse da TP01 (corr→TP01 0.1-0.4). La forma gate-su-TP01 invece sì: best gate = NEUTRAL a corr 0.803, e i gate a soglia bassa = REDUNDANT corr 1.0 (gate mai off → TP01 identico). La breadth come gate di de-risk non aggiunge nulla; come segnale direzionale è diversa dal trend ma l'edge non è dimostrabile.

Il gemello in hindsight (trasparenza, NON selezionabile). TH N=100 thr=0.7 LS fa FULL 1.13 / HOLD 1.06, corr→TP01 0.26, marginal ADDS con robust_oos=True e jackknife +0.46. MA il suo in-sample (1.30) è sotto quello della cella lf (2.11): sceglierlo = selezione-sull'hold-out (esattamente il falso positivo ERM del 2026-06-29). E comunque DSR 0.518 < 0.95: anche la lettura più caritatevole muore sulla deflazione multiple-testing.

Verdetto: SCARTATO (niente sleeve, niente forward-monitor cablato)

  1. La cella scelta onestamente è ADDS ma robust_oos=False (uplift a un mese) e DSR 0.433 su 104 trial: su ~8 mesi di in-sample (toro 2024) un IS di 2.1 è indistinguibile dal massimo atteso per caso (1.10) e non regge.
  2. Il candidato migliore col senno di poi (TH-LS) sarebbe selezione-sull'hold-out e fallisce comunque il DSR (0.518) — il gate study_family_honest fa esattamente il suo lavoro.
  3. Il limite è la storia: 2.2 anni totali, 8 mesi di in-sample. Non c'è modo onesto di dimostrare l'edge oggi.

Cosa resta. (a) La famiglia breadth-thrust (TH) è l'unico angolo con celle OOS-positive e bassa/negativa corr a TP01 — rivisitabile quando il panel HL avrà ≥1-2 anni di storia nativa in più (in-sample multi-regime, DSR ricalcolabile); nessun cablaggio forward oggi, il costo dell'attesa è zero. (b) Il breadth-gate su TP01 va in bacino con macro-gate e DVOL-gate: terza conferma che TP01 non ha bisogno di de-risk esterno (long-flat, già flat nei crash). (c) Il fix _align (epoch esplicita) è la lezione riusabile per ogni futuro panel esterno.