Files
Cerbero-Bite/docs/01-strategy-rules.md
T
root dabcc8d15b docs: aggiornamento Phase 5 — IV-RV gate, F+D+A, backtest, option chain
- 01-strategy-rules.md:
  * §2.8 (filtri quant: dealer gamma + liquidation risk)
  * §2.9 (IV richness gate, opt-in, default disabled)
  * §3.2 — variante delta_by_dvol step-function
  * §7-bis.1 (vol-collapse harvest D)
  * §7-bis.2 (graduated profit-take C — scaffolding)
  * §7-bis.3 (auto-pause su drawdown F)

- 05-data-model.md:
  * `system_state.auto_pause_until / _reason` (migration 0004)
  * Nuova tabella `option_chain_snapshots` (migration 0005)
  * Tabella migrations completa (1→5)

- 13-strategia-spiegata.md:
  * §4-quinquies — catena opzioni storica (Phase 5):
    cosa raccoglie, cosa sblocca, CLI `option-chain
    trigger|analyze`.

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

12 KiB
Raw Blame History

01 — Regole della strategia (Cerberus Bite)

Le regole qui formalizzate sono la versione canonica e immutabile che il rule engine deve applicare. Modifiche richiedono una review esplicita con Adriano (e una nuova versione di questo documento).

Sorgente teorica: Cerbero_Office/NewStrategy/strategia-credit-spread-eth.md

  • analisi Monte Carlo + cap operativi Cerbero v4.

1. Universo e strumenti

Parametro Valore
Sottostante ETH/USD
Exchange Deribit
Tipo opzioni Europee, cash-settled, USDC-margined
Strutture ammesse Bull Put Spread, Bear Call Spread, (Iron Condor solo in regime laterale, vedere §6)
Strutture vietate Naked options, calendar spread, ratio spread, condor sbilanciati

2. Trigger di apertura (entry)

Il rule engine valuta l'apertura di un nuovo trade una sola volta al giorno, alle 14:00 UTC del lunedì (orario UE pomeridiano stabile, fuori dai picchi di funding statunitensi). Se il lunedì è festività italiana, l'engine ignora la regola e attende il lunedì successivo.

Una nuova posizione viene aperta solo se tutte le seguenti condizioni sono vere:

  1. Nessuna posizione Cerberus Bite già aperta.
  2. Capitale corrente ≥ 720 USD. Sotto questa soglia il sizing in contratti non può raggiungere 1 unità Deribit.
  3. DVOL corrente ≥ 35. Sotto 35 il premio è troppo magro per mantenere il rapporto fees/credit accettabile.
  4. DVOL corrente ≤ 90. Sopra 90 si è in regime di stress, no entry.
  5. Nessun evento macro (FOMC, CPI USA, NFP, ECB, Powell speech) nei prossimi DTE giorni dall'apertura.
  6. Funding rate ETH-PERP in valore assoluto annualizzato ≤ 80% (filtra regimi di liquidazioni a cascata imminenti).
  7. Holdings ETH in cerbero-portfolio non superiori al 30% del patrimonio totale (correlazione direzionale già alta).
  8. Liquidità degli strike candidati entro le soglie del §3.

2.8 Filtri quant (introdotti in Phase 4)

Due gate aggiuntivi che leggono i campi del market_snapshot:

  • Dealer net gamma > 0 (default: dealer_gamma_min: 0). Long-gamma regime = dealer hedge che sopprime la vol → ideale per vendere credit spread. Short-gamma = vol-amplifying flow, statisticamente perdente. Disattivabile via dealer_gamma_filter_enabled: false.
  • Liquidation risk ≠ high (default: liquidation_filter_enabled: true). Salta entry quando il modulo sentiment flagga uno squeeze imminente su long o short side.

2.9 IV richness gate (introdotto in Phase 5, opt-in)

Filtro a maggior impatto sul win-rate. Disabilitato di default nella golden config — abilitato esplicitamente nel profilo strategy.aggressiva.yaml:

  • iv_minus_rv_filter_enabled: true|false — master switch.
  • iv_minus_rv_min: <pt vol> — soglia: l'entry passa solo se la IV implicita 30g supera la realized vol 30g di almeno tot punti. Default 0; valori sensati 3-5 dopo calibrazione sui dati raccolti.

Razionale: il selling vol nudo è strutturalmente neutro a win-rate 70-72%. L'edge della strategia esiste solo quando il premio è "ricco" — IV30 > RV30 + N. Vedere 13-strategia-spiegata.md §4-quater per il razionale completo.

Se anche una sola condizione fallisce → no entry, log con motivo, ritento la settimana successiva.

3. Selezione struttura

3.1 Bias direzionale

Il bias è dedotto deterministicamente da due indicatori, mai in modo discrezionale:

Indicatore Calcolo Soglia bull Soglia bear
Trend ETH 30g (ETH_now / ETH_30g_ago - 1) × 100 ≥ +5% ≤ -5%
Funding cross-exchange mediana funding annualizzato 4 maggiori exchange ≥ +20% ≤ -20%

Risultato:

  • Entrambi bull → Bull Put Spread.
  • Entrambi bear → Bear Call Spread.
  • Discordanti → no entry (mercato indeciso, edge incerto).
  • Entrambi in range neutro (-5%, +5%) E DVOL ≥ 55 E ADX(14) < 20 → Iron Condor stretto ammesso (vedi §6).
  • Tutti gli altri casi neutri → no entry.

3.2 Strike short

Si seleziona lo strike short più vicino a delta target, in valore assoluto.

Parametro Valore
Delta short target 0.12
Tolleranza delta [0.10, 0.15]
Distanza minima OTM 15% (anche se delta è dentro tolleranza)
Distanza massima OTM 25%

Variante dinamica per regime DVOL (Phase 5, opt-in). Il campo short_strike.delta_by_dvol (lista step-function) sostituisce il delta target singolo con bande ordinate per dvol_under: a DVOL bassa il bot prende delta più alto (più premio), a DVOL alta sceglie delta più basso (più safety distance). Lista vuota = comportamento classico col delta target sopra. Esempio bande nel profilo strategy.aggressiva.yaml:

dvol_under delta_target delta_min delta_max
50 0.15 0.13 0.17
70 0.12 0.10 0.15
90 0.10 0.08 0.12

Se nessuno strike disponibile rientra in entrambe le tolleranze → no entry.

3.3 Strike long (protezione)

Si seleziona lo strike a distanza fissa dallo short:

Parametro Valore
Larghezza spread (in % di spot) 4%
Larghezza minima accettabile 3%
Larghezza massima accettabile 5%

Se non esiste lo strike esatto a 4%, si prende il più vicino entro [3%, 5%]; altrimenti no entry.

3.4 Rapporto credito/larghezza

Il credito netto incassato (mid-price del combo) deve essere ≥ 30% della larghezza dello spread. Sotto questa soglia il rapporto rischio/rendimento è inferiore al minimo accettabile. → no entry.

4. Liquidità (filtro hard pre-entry)

Per ciascuno strumento delle due gambe, tutte le condizioni:

Misura Soglia
Open interest ≥ 100 contratti
Volume 24h sullo strumento ≥ 20 contratti
Spread bid-ask ≤ 15% del mid (≤ 10% per ATM, irrilevante qui)
Profondità book ai primi 3 livelli ≥ 5 contratti aggregati

Calcoliamo inoltre uno slippage stimato moltiplicando la larghezza del bid-ask di entrambe le gambe per la size proposta. Se lo slippage totale > 8% del credito atteso → no entry.

5. Sizing

5.1 Calcolo numero contratti

risk_target_usd  = capitale_corrente * 0.13            # Quarter Kelly
risk_target_usd  = min(risk_target_usd, 200_eur_in_usd) # cap Cerbero
n_contracts      = floor(risk_target_usd / max_loss_per_contract)
n_contracts      = min(n_contracts, 4)                  # cap aggregato implicito

max_loss_per_contract = larghezza spread × multiplier ETH (1 ETH).

5.2 Vincolo aggregato

Se n_contracts × max_loss_per_contract + engagement_aperto_totale > 1.000_eur → riduci n_contracts finché il vincolo è rispettato. Se risulta < 1 → no entry.

5.3 Volatilità di volatilità

Sizing dinamico per regime DVOL:

DVOL corrente Aggiustamento n_contracts
< 45 × 1.0 (base)
4560 × 0.85
6080 × 0.65
> 80 (no entry, vedi §2)

Arrotondamento sempre per difetto a intero, minimo 1.

6. Iron Condor (ammesso solo in regime laterale)

Se le condizioni del §3.1 attivano IC, struttura:

  • Bull Put Spread alle stesse regole §3.2/§3.3
  • Bear Call Spread speculare (delta 0.12, 4% width)
  • Sizing: n_contracts calcolato come sopra ma dimezzato per gamba (rischio totale = somma max loss dei due lati, ma su ETH i due lati non possono essere entrambi violati, quindi rischio effettivo = max loss del lato peggiore + credito del lato vincente)
  • Profit take: 25% del credito totale (più aggressivo)
  • Tutto il resto delle regole §7-§9 si applica per lato.

7. Gestione attiva (decision loop ogni 12 ore)

Per ogni posizione aperta, il rule engine valuta in ordine:

  1. Profit take — se mark price del combo ≤ 50% del credito incassato, decision = CLOSE_PROFIT.
  2. Stop loss stretto — se mark price del combo ≥ 250% del credito (perdita = 1.5× credito), decision = CLOSE_STOP.
  3. Vol stop — se DVOL corrente ≥ DVOL all'entry + 10, decision = CLOSE_VOL.
  4. Time stop — se (scadenza - oggi) ≤ 7 giorni, decision = CLOSE_TIME (a meno che non siamo già al 50% di profit: in quel caso teniamo per regola 1 in arrivo).
  5. Strike testato — se |delta_short_corrente| ≥ 0.30, decision = CLOSE_DELTA. Su ETH non si difende, si esce.
  6. Movimento esplosivo — se |return_4h_ETH| ≥ 5% direzione avversa, decision = CLOSE_AVERSE (azione conservativa, può essere finalizzata alla prossima fenestra).
  7. Altrimenti decision = HOLD.

L'ordine è importante: il primo trigger soddisfatto vince.

7-bis. Estensioni opzionali (Phase 5)

Tre miglioramenti opt-in al decision loop. Tutti disabled di default nella golden config; il profilo strategy.aggressiva.yaml li abilita.

7-bis.1 Vol-collapse harvest (D)

Inserito tra il profit-take §7.1 e lo stop-loss §7.2:

Se vol_harvest_dvol_decrease > 0, siamo in profit (debit < credit) E DVOL_now ≤ DVOL_entry vol_harvest_dvol_decrease, decision = CLOSE_VOL_HARVEST.

Razionale: edge IV-RV già catturato, vol attesa rientrata, non c'è motivo di tenere fino al profit-take. Default disabilitato (0); profilo aggressivo: 15 punti vol.

7-bis.2 Profit-take graduale (C — scaffolding)

Schema in place per chiusure parziali; pipeline runtime di chiusura partial-close NON ancora wirata. Default vuoto. Quando popolato, ogni livello {mark_at_pct_credit, close_pct_of_initial_contracts} emette un'azione CLOSE_PROFIT_PARTIAL advisory che il runtime attualmente ignora. Il completamento richiede refactor del position model (contracts_open vs contracts_initial) — PR dedicato.

7-bis.3 Auto-pause su drawdown (F)

Circuit breaker sopra il kill-switch tecnico. Valutato all'inizio di ogni entry-cycle:

Se auto_pause.enabled e P/L cumulato delle ultime lookback_trades posizioni chiuse < max_drawdown_pct × capitale_corrente, l'engine si auto-mette in pausa per pause_weeks settimane (skip-week mode).

Difende dai regime change non rilevati dai filtri quant. La pausa si annulla automaticamente alla scadenza, oppure manualmente con UPDATE system_state SET auto_pause_until = NULL. Default disabilitato; profilo aggressivo: lookback 5 trade, soglia 15%, 2 settimane di pausa.

8. Esecuzione di apertura

  1. Engine costruisce combo order Deribit (un solo ordine atomico con due gambe). Mai due ordini separati.
  2. Limit price = mid-price calcolato dall'engine.
  3. Ordine inviato come limit GTC con time-in-force che scade alle 16:00 UTC dello stesso giorno.
  4. Se non riempito entro 30 min, engine alza limit di 1 tick verso ask combinato fino a un massimo di 3 step (poi cancella e log "no fill").
  5. Riempimento → engine persiste lo stato (vedi 05-data-model.md) includendo: spot ETH, DVOL, strike, scadenza, credit incassato, timestamp.

9. Esecuzione di chiusura

  1. Stessa logica di combo, in direzione inversa.
  2. Limit di partenza al mid-price.
  3. Se non riempito entro 30 min: alza limit fino a 3 step verso il bid combinato. Su trigger CLOSE_STOP o CLOSE_VOL o CLOSE_DELTA l'engine può accettare slippage maggiore (fino a 5 step) perché l'urgenza prevale sul prezzo.
  4. Riempimento → posizione marcata CLOSED, P&L calcolato e loggato, record archiviato per Kelly recalibration mensile.

10. Cosa NON fa il rule engine — esplicito

  • Non rolla mai una posizione (regola §7.5: si esce e basta).
  • Non aggiunge gambe a una posizione esistente (no conversione in IC durante un trade aperto).
  • Non aggiusta strike o size dopo l'apertura.
  • Non apre nuovi trade per "compensare" perdite recenti.
  • Non opera fuori dalla finestra del lunedì 14:00 UTC, eccetto chiusure.
  • Non deroga ai cap nemmeno per "opportunità eccezionali".
  • Non si aggiorna automaticamente: nuovo set di regole = nuovo deploy con review esplicita.

11. Riepilogo soglie (parametri di config)

Tutti i numeri sopra sono parametrizzati in strategy.yaml (vedi 10-config-spec.md). Modificarli è una decisione di Adriano con giustificazione scritta nel commit message. La regola di default fissata da questo documento è la golden config che il sistema parte con al primo deploy.