Files
Cerbero-Bite/docs/13-strategia-spiegata.md
root 4ab7590745 feat(entry): IV richness gate (§2.9) + golden config bump 1.0.0 → 1.1.0
Aggiunge il filtro a maggior impatto sul win-rate atteso: l'entry
salta se la IV implicita non sta pagando un margine misurabile sopra
la realized vol. La letteratura short-vol systematic indica che
l'edge sostenibile della strategia esiste solo quando IV30g − RV30g
supera una soglia di alcuni punti vol; senza questo gate il selling
vol nudo è strutturalmente neutro a win-rate 70-72%.

Implementazione end-to-end:

- `EntryConfig`: due nuovi campi `iv_minus_rv_min` e
  `iv_minus_rv_filter_enabled`, con default `0` / `false` per non
  rompere setup pre-calibrazione.
- `validate_entry`: §2.9 hard gate che blocca l'entry se
  `iv_minus_rv < iv_minus_rv_min` (skip silenzioso quando il dato è
  `None`, coerente con il pattern §2.8 dei filtri quant).
- `entry_cycle._gather_snapshot`: nuovo `_safe_iv_minus_rv` che
  legge `deribit.realized_vol("ETH")["iv_minus_rv_30d"]` in
  best-effort e lo propaga via `_MarketSnapshot.iv_minus_rv` →
  `EntryContext.iv_minus_rv` → audit `inputs.snapshot.iv_minus_rv`.
- `tests/unit/test_entry_validator.py`: 5 nuovi casi (default
  permissivo, gate sotto/sopra/uguale soglia, dato mancante).
- `tests/integration/test_entry_cycle.py`: stub `get_realized_vol`
  nel mock helper così tutti gli scenari di happy/edge path
  continuano a passare.

Configurazione di profili coerente con la disciplina:

- `strategy.yaml` (golden 1.1.0) e `strategy.conservativa.yaml`:
  gate `enabled=false, min=0`. Manteniamo i lunedì pre-calibrazione
  per accumulare dati sulla distribuzione di `iv_minus_rv`.
- `strategy.aggressiva.yaml` (1.1.0-aggressiva): gate
  `enabled=true, min=3`. Coerente con la filosofia del profilo —
  size più grande pretende win-rate più alto. La soglia 3 è
  conservativa; la documentazione raccomanda 5 dopo 4-8 settimane di
  calibrazione.

Doc + GUI:

- `docs/13-strategia-spiegata.md` §4-quater: spiega gate, parametri,
  default per profilo, effetto atteso sul P/L (trade/anno scendono
  ma E[trade] sale → APR cresce comunque), roadmap di hardening
  (soglia adattiva, vol-of-vol guard, multi-asset).
- pagina `📚 Strategia`: la riga "IV − RV" passa da informativa a
  pass/fail reale; mostra "filtro DISABILITATO (info-only)" quando
  spento, / contro la soglia di config quando acceso.

Bump versioni e hash di tutti e tre i file YAML
(`config_version: 1.1.0`, hash ricalcolato). Test pinning aggiornato
(`test_load_repo_strategy_yaml`).

Suite: 410 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:32:21 +00:00

29 KiB
Raw Permalink Blame History

13 — Strategia spiegata: dalle regole ai dati

Documento operativo che lega ogni decisione del rule engine al dato osservabile da cui dipende. Pensato per chi guarda il cruscotto e vuole capire a cosa servono le metriche raccolte ogni 15 minuti nella tabella market_snapshots. La versione canonica e immutabile delle regole resta in 01-strategy-rules.md; questo documento è la guida descrittiva da leggere prima di toccare le soglie in strategy.yaml.


TL;DR

Cerbero Bite vende credit spread settimanali su ETH/Deribit quando la volatilità implicita è abbastanza alta da pagare bene, il mercato non è in stress di liquidazione, non ci sono eventi macro forti in finestra, e il bias direzionale è chiaro (bull o bear). Tutto il resto del tempo, l'engine non opera: la disciplina è la strategia.

Ogni 15 minuti raccoglie 1 riga per asset (ETH e BTC) nella tabella market_snapshots. Quei dati alimentano tre obiettivi distinti:

  1. Decisione live — l'entry ciclo del lunedì 14:00 UTC legge i campi più freschi per dire "go/no-go".
  2. Monitoring continuo — il decision loop di gestione attiva confronta la situazione con quella all'apertura.
  3. Calibrazione — la pagina 📐 Calibrazione usa la distribuzione storica di ciascun campo per scegliere soglie basate sui percentili reali del proprio ambiente, non a istinto.

1. Cosa c'è in market_snapshots (1 riga ogni 15 min, per asset)

Campo Unità Sorgente MCP A che serve nella strategia
timestamp UTC ISO scheduler indicizzazione della time-series
asset ETH / BTC scheduler partizionamento (ETH = sottostante operativo, BTC = controllo macro)
spot USD mcp-deribit spot_perp_price trend 30g (§3.1), distanza % strike (§3.2/3.3), context generale
dvol indice 0200 mcp-deribit latest_dvol gate entry §2.3-§2.4 (35 ≤ DVOL ≤ 90), aggiustamento sizing §5.3, vol-stop §7.3
realized_vol_30d % annualizzata mcp-deribit realized_vol confronto con DVOL → mean-reversion edge
iv_minus_rv punti vol derivato richness della IV: > 0 = premio "ricco" da vendere
funding_perp_annualized frazione mcp-hyperliquid funding_rate_annualized gate entry §2.6 (|f| ≤ 80% annualizzato), bias §3.1
funding_cross_annualized frazione mcp-sentiment funding_cross_median_annualized bias direzionale §3.1 (mediana 4 maggiori exchange)
dealer_net_gamma USD mcp-deribit dealer_gamma_profile filtro quant §2.8 (long-gamma regime sopprime la vol → ideale per vendere spread)
gamma_flip_level USD mcp-deribit dealer_gamma_profile livello spot oltre il quale il regime di gamma flippa
oi_delta_pct_4h % mcp-sentiment liquidation_heatmap proxy di accumulo/sgonfiaggio leverage nelle ultime 4h
liquidation_long_risk low / med / high mcp-sentiment liquidation_heatmap rischio long squeeze imminente
liquidation_short_risk low / med / high mcp-sentiment liquidation_heatmap rischio short squeeze imminente
macro_days_to_event giorni mcp-macro next_high_severity_within gate §2.5 (no entry se evento macro entro DTE)
fetch_ok bool scheduler qualità riga (true = tutte le sotto-chiamate sono andate)
fetch_errors_json json o NULL scheduler mappa errori per debugging best-effort

Un campo NULL non invalida la riga: la collezione è best-effort, una MCP giù non blocca le altre. Le distribuzioni si calcolano sui campi disponibili, l'engine entry-cycle invece rifiuta l'entry se il dato che gli serve è NULL (sicurezza: meglio saltare un trade che operare alla cieca).


2. Le sei famiglie di dati e il "perché"

2.1 — Volatilità implicita (DVOL, realized vol, IVRV)

Cosa misura. DVOL è l'indice Deribit della IV ETM 30g. Realized 30g è la deviazione standard annualizzata dei rendimenti spot. La differenza IV RV quantifica quanto le opzioni stanno pagando sopra la volatilità che il mercato ha effettivamente realizzato: questa è la materia prima del credit spread venditore.

Come la usa l'engine.

  • §2.3 / §2.4: dvol_min = 35, dvol_max = 90 — sotto 35 il premio è troppo magro rispetto a fees+slippage, sopra 90 si è in stress-regime (rischio gap > edge).
  • §5.3: dvol_adjustment riduce la size all'aumentare del DVOL (×1.0 sotto 45, ×0.85 fra 4560, ×0.65 fra 6080, no entry > 80).
  • §7.3: vol_stop_dvol_increase = 10 — se durante la posizione DVOL sale di 10 punti rispetto all'entry, si chiude.

Cosa si calibra dai dati raccolti. Un mese di tick ti dà la distribuzione di DVOL nel TUO regime (testnet vs mainnet, bull vs bear). I percentili P25/P50/P75 nella pagina 📐 Calibrazione dicono se 35 è davvero il "fondo" o se andrebbe alzato.

2.2 — Funding rate (perpetual + cross-exchange median)

Cosa misura. Il funding annualizzato del perpetual ETH-PERP (Hyperliquid principalmente) e la mediana dei funding sui 4 maggiori exchange. Il funding è la fee periodica che paga il lato sbilanciato del perp: è il termometro più diretto del posizionamento leveraged del mercato.

Come la usa l'engine.

  • §2.6: funding_perp_abs_max_annualized = 0.80 — funding > 80% annualizzato (in valore assoluto) = liquidazioni a cascata imminenti, no entry.
  • §3.1: il bias direzionale dipende dal funding cross:
    • funding_bull_threshold_annualized = 0.20 ⇒ bias bull se cross-funding ≥ +20%.
    • funding_bear_threshold_annualized = -0.20 ⇒ bias bear se ≤ -20%.
    • In mezzo + trend neutro = candidato Iron Condor.
    • Trend e funding discordi = no entry.

Perché due funding diversi. Il perp di Hyperliquid è il segnale "è esecutibile la chiusura?" (l'ETH-PERP è la sede di hedge pratico). La mediana cross-exchange è il segnale macro "dove sta il mercato globale": più robusta a manipolazioni o picchi locali.

2.3 — Dealer gamma (net gamma + flip level)

Cosa misura. L'esposizione netta di gamma dei dealer di opzioni su Deribit, ricostruita da OI per strike e direzione. Quando dealer_net_gamma > 0 (long gamma), i dealer sopprimono la volatilità realizzata col loro hedge (vendono salendo, comprano scendendo). Quando è negativo, amplificano ogni movimento.

Come la usa l'engine.

  • §2.8: dealer_gamma_min = 0, dealer_gamma_filter_enabled = true — entry solo in regime long-gamma. Vendere credit spread con dealer corto-gamma è statisticamente perdente.
  • gamma_flip_level è il prezzo spot al quale il regime cambierebbe. Se siamo a 1% dal flip, il margine di sicurezza è basso anche se il segno è positivo.

Cosa si calibra dai dati raccolti. La distribuzione di dealer_net_gamma nel proprio universo (qualche miliardo USD su mainnet, ordini di grandezza diversi su testnet) suggerisce se min = 0 è troppo permissivo — su mainnet è frequente che il segno si trovi positivo per molto tempo, qui ha senso una soglia più alta.

2.4 — Liquidation heatmap (OI delta + long/short squeeze risk)

Cosa misura. Da mcp-sentiment:

  • oi_delta_pct_4h: variazione % dell'open interest aggregato nelle ultime 4h. Spike positivo → leverage in entrata (rischio fragile); spike negativo → squeeze appena avvenuta.
  • liquidation_long_risk / liquidation_short_risk: classificazione qualitativa (low / med / high) della densità di livelli di liquidazione vicini allo spot.

Come la usa l'engine.

  • §2.8 (liquidation_filter_enabled = true): l'entry cycle scarta setup con _risk = high sul lato che ci interesserebbe (es. un bull put spread in regime di long_risk = high è esposto a un long-squeeze giù).
  • Anche fuori dall'entry, queste due colonne servono come "filtro di realtà" per il monitoring: se durante la posizione lo squeeze risk cambia da low a high, è un primo segnale di vol-stop in arrivo.

2.5 — Macro calendar (giorni al prossimo evento)

Cosa misura. mcp-macro restituisce il numero di giorni al prossimo evento ad alta severità (FOMC, CPI USA, NFP, ECB, Powell speech) per US/EU. NULL = nessun evento entro la finestra DTE.

Come la usa l'engine.

  • §2.5: se macro_days_to_event ≤ dte_target = 18, no entry. Le uscite macro si trasformano in gap di volatilità che mangiano in un'ora il credito di tre settimane.
  • Le entry sono comunque possibili poco dopo l'evento (vol elevata appena dopo + RV destinata a comprimersi → IVRV alto = setup di scuola).

2.6 — Spot ETH (e BTC come controllo)

Cosa misura. Prezzo last/perp di ETH (e BTC come controllo).

Come la usa l'engine.

  • §3.1: trend 30g calcolato come (spot_now / spot_30g_ago - 1). Soglie ±5% definiscono bias bull / bear / neutro.
  • §3.2: distanza % degli strike short dallo spot (1525% OTM).
  • §7.6: adverse_move_4h_pct = 0.05 — close su movimento contrario ≥ 5% in 4h.

Perché anche BTC. ETH è il sottostante operativo, BTC è il termometro macro crypto: in regimi di alta correlazione, un movimento BTC che ETH non sta seguendo è un segnale di divergenza che spesso precede un riallineamento brusco.


3. Il flusso decisionale, allineato al dato

Quanto segue è la versione "leggibile" delle regole §2-§9 di 01-strategy-rules.md. Ogni passo cita i campi di market_snapshots che lo alimentano.

Fase 1 — Trigger (lunedì 14:00 UTC, festività italiane escluse)

SE NESSUNA posizione aperta
   E capitale ≥ 720 USD
   E 35 ≤ dvol ≤ 90                                    # market_snapshots.dvol
   E |funding_perp_annualized| ≤ 0.80                  # market_snapshots.funding_perp_annualized
   E macro_days_to_event > dte_target  (oppure NULL)   # market_snapshots.macro_days_to_event
   E ETH holdings cerbero-portfolio ≤ 30%
   E (filtri quant: dealer_net_gamma > 0,
       liquidation_*_risk ≠ high)                      # market_snapshots.dealer_net_gamma + liquidation_*
ALLORA
   procedi alla Fase 2
ALTRIMENTI
   no entry, log motivo, ritento la settimana successiva

Fase 2 — Bias e struttura

trend_30g  = spot_now / spot_30g_ago - 1               # market_snapshots.spot
funding_x  = funding_cross_annualized                  # market_snapshots.funding_cross_annualized

SE trend_30g ≥ +5% E funding_x ≥ +20%:
    struttura = Bull Put Spread
SE trend_30g ≤ -5% E funding_x ≤ -20%:
    struttura = Bear Call Spread
SE |trend_30g| < 5% E |funding_x| < 20%
   E dvol ≥ 55 E ADX(14) < 20:
    struttura = Iron Condor
ALTRIMENTI:
    no entry (mercato indeciso o discordante)

Fase 3 — Selezione strike (delta-target + distanza % spot)

Lo strike short è quello a delta target ≈ 0.12 (tolleranza 0.100.15) e OTM 1525%. Lo strike long è a 4% del spot (35% accettabile). Tutti i numeri sono parametrizzati in strategy.yaml > structure. Lo spot corrente per il calcolo viene da market_snapshots.spot.

Fase 4 — Sizing (Kelly frazionario + cap aggregato + DVOL clamp)

risk_target = capitale * 0.13                                # quarter Kelly
risk_target = min(risk_target, 200 EUR)                      # cap per-trade
n           = floor(risk_target / max_loss_per_contract)
n           = min(n, 4, vincolo aggregato 1000 EUR)
n           = round_down(n * dvol_multiplier)                # market_snapshots.dvol → §5.3

Fase 5 — Esecuzione (combo limit GTC al mid)

Limit al mid del combo, riprezzamento +1 tick / 30min fino a 3 step. Su trigger urgenti (CLOSE_STOP / CLOSE_VOL / CLOSE_DELTA) l'engine accetta fino a 5 step di slippage perché l'urgenza prevale sul prezzo.

Fase 6 — Monitoring (cron di gestione attiva, default ogni 12h)

Per ogni posizione aperta, in ordine (primo trigger vince):

# Trigger Dato sorgente
1 Profit take: mark ≤ 50% credito combo mark via deribit
2 Stop loss: mark ≥ 250% credito combo mark via deribit
3 Vol stop: dvol_now ≥ dvol_entry + 10 market_snapshots.dvol
4 Time stop: dte ≤ 7 (skip se ≥ 70% profit) scadenza struttura
5 Delta breach: |delta_short| ≥ 0.30 option chain via deribit
6 Adverse move: |return_4h_ETH| ≥ 5% contro market_snapshots.spot
7 Altrimenti HOLD

Il monitoring NON consulta market_snapshots per i prezzi opzioni (legge live), ma li consulta per dvol e spot con il vantaggio di una serie storica già normalizzata e auditabile.


4. Cosa fa OGGI il bot in modalità "data-only"

Il bot oggi è in modalità raccolta dati (ENABLE_DATA_ANALYSIS=true, ENABLE_STRATEGY=false). Vuol dire:

  • Il job market_snapshot (cron */15) gira: scrive nuove righe in SQLite, alimenta calibrazione e monitoring storico.
  • Il job health (*/5) verifica disponibilità MCP e ambiente Deribit; alza il kill switch se qualcosa non torna.
  • Il job backup (0 *) snapshotta lo stato ogni ora.
  • Il job manual_actions (*/1) consuma comandi dalla GUI.
  • I cicli entry e monitor non sono nemmeno schedulati: nessun ordine può partire, nessuno strike viene letto.

Quando si vuole passare alla fase operativa (paper trading o mainnet), basta:

  1. Riempire strategy.yaml con le soglie calibrate sui percentili reali della pagina 📐 Calibrazione (non lasciare i valori default a istinto).
  2. Bumpare config_version + rigenerare config_hash con cerbero-bite config hash --file strategy.yaml.
  3. Settare ENABLE_STRATEGY=true in .env e ricreare il container.
  4. Disarmare il kill switch da GUI o CLI con motivazione esplicita.
  5. Una settimana di paper trading (mainnet con ordini disabilitati o testnet) prima di alzare il flag definitivo.

4-bis. P/L atteso (realistico)

I numeri qui sotto sono stime ex-ante, non promesse. Servono ad allineare le aspettative con la geometria della strategia: capire quanto poco si rischia per trade, quanto raramente si entra, e perché l'edge è strutturalmente sottile.

Domanda onesta che chiunque guardi i numeri dovrebbe farsi: se a win-rate 7072% l'aspettativa per trade è circa zero, che senso ha la strategia?

Risposta: il selling vol nudo è effettivamente neutro a quel win-rate. L'edge della Cerbero Bite non è "vendere vol"; è "vendere vol solo quando i filtri quant alzano il win-rate sopra il 75%". I gate §2 (DVOL band, dealer gamma > 0, no macro entro DTE, liquidation risk ≠ high, bias trend × funding concorde) sono costruiti per saltare proprio le finestre statisticamente perdenti e operare solo in quelle favorevoli. La pagina 📚 Strategia ha una tabella di sensibilità che mostra come l'APR passa da ≈0% (win 0.72) a +3-5% (win 0.780.80): è esattamente la distanza che i filtri devono coprire. Per questo i primi giorni di raccolta dati servono a misurare se i filtri stanno effettivamente alzando il win-rate prima di committare capitale.

Per singolo trade (riferimento: ETH spot ≈ 3000 USD)

Voce Formula / fonte Valore tipico
Larghezza spread 4% × spot 120 USD / contratto
Credito incassato ≥ 30% × larghezza 3648 USD / contratto
Max profit teorico = credito (a scadenza OTM) 3648 USD / contratto
Profit-take §7.1 (50% credito) 0.5 × credito +1824 USD / contratto
Stop-loss §7.2 (mark = 2.5× credito) 1.5 × credito 5472 USD / contratto
Margine bloccato ≈ larghezza 120 USD / contratto
Fees Deribit 0.03% notional × 2 leg ~12 USD / contratto / trade

Su spot più basso (2000 USD) la larghezza scende a 80 USD/contratto e i numeri assoluti seguono proporzionalmente.

Sizing tipico vs capitale

Il sizing è governato dal Quarter-Kelly + cap per-trade 200 EUR (~215 USD). Sopra una certa soglia, il cap domina: alzare il capitale non aumenta i contratti per trade.

Capitale risk_target (Kelly) risk effettivo (post-cap) Contratti tipici (spot=3000)
720 USD (minimo) 94 USD 94 USD 01 (entry spesso saltata per sizing)
1 500 USD 195 USD 195 USD 1
3 000 USD 390 USD 215 USD (cap) 1
10 000 USD 1 300 USD 215 USD (cap) 1
50 000 USD+ 6 500 USD 215 USD (cap) 1 (cap aggregato 1 075 USD = max 4 trade aperti, ma max_concurrent_positions: 1)

Con i cap correnti la strategia è dimensionata per capitale piccolo (1.510 k USD): oltre, il rendimento sul totale scala sotto-lineare e tende a zero.

Frequenza realistica di entry

La regola si valuta una volta a settimana, ma la maggioranza dei lunedì viene saltata per:

Motivo di skip Frequenza tipica
DVOL fuori banda (3590) 2540%
Bias non chiaro (trend × funding discordi o entrambi neutri senza IC) 2535%
Macro entro DTE 1020%
Funding o liquidation risk fuori soglia 515%
Capitale o sizing insufficiente 05%

Risultato netto: 3050% delle settimane finisce in entry effettiva ⇒ 1525 trade / anno (52 lunedì × 3050%). Le altre settimane il bot sta fermo. È il design.

Win-rate atteso (short delta 0.12 + profit-take 50%)

Letteratura e backtest su credit spread short delta 0.100.15 con TP@50% e SL@1.5×:

Esito Probabilità tipica Risultato
Profit-take a 50% credito ~7075% +1824 USD/contratto
Stop-loss a 1.5× credito ~1520% 5472 USD/contratto
Time-stop o exit DTE 7g ~510% piccolo positivo (~+510 USD)
Vol/delta/macro stop ~35% variabile, mediamente neutro

Atteso medio per contratto:

E[trade] ≈ 0.72 × 21 + 0.18 × (-63) + 0.07 × 7 + 0.03 × 0
        ≈ 15.1  11.3 + 0.5 + 0
        ≈ +4.3 USD lordi / contratto

Al netto di fees (~1.5 USD round-trip) e slippage (~5% del credito ≈ 2 USD): E[trade] ≈ +13 USD per contratto.

Proiezione annuale (1 contratto medio per trade)

Scenario Trade/anno E[trade] netto P/L lordo annuo Su capitale 1 500 USD Su capitale 3 000 USD
Pessimistico (vol bassa, regime bear vol) 12 +1 USD +12 USD +0.8% +0.4%
Realistico medio 18 +2.5 USD +45 USD +3% +1.5%
Buono (regime favorevole, IVRV alto) 22 +4 USD +88 USD +5.9% +2.9%
Eccellente (cherry-picking ex-post) 25 +6 USD +150 USD +10% +5%

Realisticamente: +1.5% / +5% APR sul capitale totale, con i cap correnti. È in linea con la letteratura su short-vol systematic con disciplina di stop. Non è una strategia "raddoppia il capitale". È una strategia che vuole guadagnare il premio di rischio della volatilità in modo controllato.

Drawdown e rischio coda

  • Streak realistico di perdite consecutive: 35 stop-loss di fila capitano. Drawdown su 1 contratto: 150 / 300 USD assoluti.
  • Su capitale 1 500 USD = drawdown del 1020% del capitale totale. Aspettarselo, è dentro il design.
  • Tail risk: un evento gap notturno (sentenza SEC, hack exchange, default importante) può portare il mark a 100% della larghezza prima che lo stop sia eseguibile. Perdita massima reale per trade = larghezza intera (width - credit_iniziale), cioè 7296 USD/contratto, non i 5472 USD del modello stop-loss.
  • I filtri quant (dealer_gamma_min, liquidation_filter) e il macro filter sono stati introdotti per ridurre la coda, non per migliorare l'aspettativa media.

Sharpe atteso

Strategie short-vol sistematiche con disciplina hanno:

  • Sharpe 0.81.5 in regimi favorevoli (mercato lento + IV alta).
  • Sharpe 0.30.8 in regimi normali.
  • Sharpe negativo in regimi di vol-of-vol (es. Q1 2020, Maggio 2021, FTX week). I filtri li mitigano, non li annullano.

Cosa cambia con ENABLE_STRATEGY=true

In modalità data-only (oggi) il P/L atteso è 0 — l'engine non opera. Il valore della raccolta di oggi è:

  1. Calibrare soglie su percentili reali → P/L atteso più realistico al go-live.
  2. Validare i filtri quant osservando ex-post quanti tick sarebbero stati filtrati (vedi pagina 📐 Calibrazione, colonna "% bloccato dalla soglia").
  3. Misurare la quota effettiva di lunedì che superano i filtri nel proprio regime, prima di committare capitale.

Suggerimento: 4 settimane di dati = 4 lunedì × probabilità entry = 12 candidate entry effettive. Aspettare almeno 8 settimane prima di tarare le soglie dà uno storico con dispersione sufficiente per decisioni non-rumorose.


4-ter. Due profili: Conservativa vs Aggressiva

Il P/L del §4-bis assume i cap della golden config v1.0.0 (cap_per_trade_eur: 200, max_concurrent_positions: 1, max_contracts_per_trade: 4). Su quel profilo il P/L assoluto è piccolo per design — la strategia è dimensionata come macchina di conservazione del capitale con premio modesto su T-bill.

Per chi vuole rendimenti significativi, il repo include un secondo file di config — strategy.aggressiva.yaml — che deroga esplicitamente alla §11 di 01-strategy-rules.md allargando le tre leve dominanti:

Leva Conservativa Aggressiva Effetto sul P/L
cap_per_trade_eur 200 800 4× la size per trade
cap_aggregate_open_eur 1 000 3 200 4× il rischio aggregato
max_concurrent_positions 1 2 2× le posizioni aperte simultanee
max_contracts_per_trade 4 16 toglie il vincolo aggregato anche su capitali maggiori
kelly_fraction 0.13 0.13 invariato (la disciplina Kelly resta)
Filtri quant (gamma, liquidation, macro) ON ON invariati (l'edge è qui, non si tocca)

Risultato atteso (a parità di filtri e win-rate): P/L ≈ 48× il profilo conservativo. Drawdown atteso scala con lo stesso fattore (2040% del capitale impiegato in streak avverse, contro 1020% del conservativo). La pagina 📚 Strategia ha un pannello affiancato che calcola entrambi sugli stessi slider.

Il rovescio della medaglia.

  • La deroga alla §11 va autorizzata esplicitamente nel commit che switcha la config; tre settimane di paper trading dedicato sono raccomandate.
  • Il drawdown maggiore richiede capitale "growth", non capitale di parcheggio.
  • I filtri quant restano identici — non c'è "più aggressivo" sui trigger di entry, perché lì non c'è alpha da spremere senza peggiorare il win-rate.

Multi-asset (ETH + BTC) — caveat.

L'ulteriore moltiplicatore 2× citato nel §4-bis (multi-asset) non è abilitato dalla sola modifica della config: il rule engine attuale è single-asset (asset.symbol). Per estenderlo servono modifiche in:

  • cerbero_bite/runtime/entry_cycle.py (loop sui simboli)
  • cerbero_bite/state/repository.py (multi-position chiave per asset)
  • cerbero_bite/runtime/orchestrator.py (scheduler one-asset → N)

Il job di raccolta dati è già multi-asset (DEFAULT_ASSETS = ("ETH", "BTC")), quindi tutto il dataset utile per validare l'estensione è già disponibile. È un lavoro di codice ben circoscritto, da fare in un branch dedicato dopo che il dataset di calibrazione è abbondante.

Quando passare dal profilo conservativo all'aggressivo.

Solo se tutte le seguenti sono vere:

  1. ≥ 8 settimane di dati raccolti su mainnet (≥ ~2k snapshot).
  2. Win-rate empirico misurato (paper trading o backtest sui tick raccolti) ≥ 0.75.
  3. APR atteso del profilo aggressivo (vedi pannello GUI) ≥ 8% netto a quel win-rate.
  4. Capitale impegnato è growth capital, non riserva tattica.
  5. Sopporti emotivamente un drawdown a doppia cifra senza disarmare manualmente la strategia in mezzo a una streak.

Se anche solo uno dei 5 manca → resta sulla conservativa, è quella che il sistema parte ad eseguire.


4-quater. IV richness gate (§2.9): il filtro che alza il win-rate

Il filtro a maggior impatto sull'edge è anche il più semplice da descrivere: non vendere vol quando la IV non sta pagando un margine misurabile sopra la RV. È implementato come gate hard nel validate_entry:

if iv_minus_rv_filter_enabled and iv_minus_rv < iv_minus_rv_min:
    skip entry

con due parametri in entry: di strategy.yaml:

Parametro Default Effetto
iv_minus_rv_filter_enabled false (golden) / true (aggressiva) Master switch del gate
iv_minus_rv_min 0 (golden) / 3 (aggressiva) Soglia in punti vol che IV30g RV30g deve eccedere

Il dato è già raccolto in market_snapshots.iv_minus_rv ogni 15 minuti. Il gate consulta l'ultimo tick disponibile al momento dell'entry cycle (non un percentile rolling — quello è il prossimo step di calibrazione, vedi §4-quinquies in roadmap).

Profili di default ragionati.

  • Conservativa / golden config: enabled=false, min=0. Tutti i setup passano questo gate, anche con IV-RV negativa. Motivo: nei primi 8 turni di lunedì non si hanno abbastanza tick per stabilire che soglia ha senso nel proprio regime. Lasciamo la pagina 📐 Calibrazione mostrare la distribuzione e poi alziamo manualmente.
  • Aggressiva: enabled=true, min=3. Il profilo aggressivo già di suo prende size più grande; pretendere IV-RV ≥ 3 vol points come prerequisito è coerente — se stai betting più grosso, vuoi win-rate più alto. La soglia 3 è conservativa; la letteratura short-vol systematic suggerisce 5 dopo calibrazione.

Cosa cambia nel P/L atteso quando attivi il gate.

Il gate riduce il numero di entry (saltiamo settimane con premio magro) ma alza la qualità di quelle che passano (premio ricco = win-rate empirico più alto). Effetto netto sul P/L annuo:

  • Trade/anno: 18 → 12-14 (skip più aggressivo)
  • Win-rate atteso: 0.72 → 0.78-0.80
  • E[trade] netto: +0.6 USD → +4-6 USD per contratto
  • P/L annuo proiettato sale anche se i trade scendono, perché ogni trade ha edge più alto.

La pagina 📚 Strategia ha lo slider win-rate già coerente con questa logica: muovi da 0.72 a 0.78 e vedi l'APR scattare.

Roadmap di hardening (passi successivi al merge di questo PR).

  1. Soglia adattiva: sostituire iv_minus_rv_min: 3 con un valore calcolato a runtime come P25 rolling 60d di market_snapshots.iv_minus_rv.
  2. Vol-of-vol guard: bloccare entry quando dvol è cambiato di ≥5 punti nelle ultime 24h, anche se iv_minus_rv è alto (regime instabile).
  3. Multi-asset (ETH+BTC): come da §4-ter, sblocca il moltiplicatore 2× sulle opportunità a parità di filtri.

5. Come leggere il dato giorno per giorno

Tre euristiche operative sui campi raccolti:

  1. Premio "ricco": iv_minus_rv consistentemente > 5 punti per N giorni → il regime sta pagando bene la vendita di vol. Sono i periodi in cui la strategia ha edge maggiore.
  2. Premio "magro": dvol < 35 per più giorni → la finestra del lunedì viene saltata. Non è un fallimento: è la disciplina che funziona.
  3. Stress imminente: liquidation_*_risk = high o spike di oi_delta_pct_4h (> 5% in valore assoluto) + funding ai limiti → atteso vol stop / time stop attivi nei prossimi cicli, anche se la posizione è in profit.

Nei giorni di eventi macro (macro_days_to_event piccolo) la combinazione utile è: aspettare l'evento, lasciare che dvol scenda quando realized_vol_30d non si è realizzata, e cogliere il setup classico post-evento.


6. Glossario rapido

  • Credit spread: vendita di un'opzione e acquisto di un'opzione più OTM stessa scadenza per cap del rischio. Si incassa un credito, si vince se il sottostante non rompe lo strike short.
  • Bull put / Bear call: credit spread direzionali (rispettivamente bullish / bearish).
  • Iron condor: Bull put + bear call sullo stesso sottostante e scadenza. Si vince in regime laterale.
  • DVOL: indice Deribit della IV ETM 30g, scala 0200.
  • Realized vol 30g: σ annualizzata dei rendimenti spot sui 30g rolling.
  • IV RV: differenza tra IV implicita (DVOL) e RV; > 0 = "premio" positivo per il venditore di vol.
  • Funding annualizzato: funding rate del perp moltiplicato per le finestre standard (di solito 8h × 3 al giorno × 365).
  • Dealer net gamma: somma di gamma per tutti gli strike, pesata per direzione dei dealer (long = riduce vol, short = amplifica).
  • OI delta % 4h: variazione % dell'open interest aggregato nelle ultime 4 ore.
  • DTE: Days To Expiry, giorni alla scadenza dell'opzione.
  • Kill switch: flag persistente che blocca apertura di nuove posizioni; armato automaticamente su mismatch ambiente o failure ripetuti, disarmato solo manualmente con motivazione.

7. Riferimenti incrociati

  • Regole canoniche e immutabili: 01-strategy-rules.md
  • Schema dati persistente: 05-data-model.md
  • Algoritmi (calcolo trend, IVRV, ecc.): 03-algorithms.md
  • Dettaglio integrazioni MCP: 04-mcp-integration.md
  • Pagina GUI di calibrazione: 📐 Calibrazione
  • Sorgente del collector: src/cerbero_bite/runtime/market_snapshot_cycle.py
  • Modello pydantic riga: cerbero_bite.state.models.MarketSnapshotRecord