From dabcc8d15b35399df5704164fb7c4c9fcdf88531 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 1 May 2026 21:29:00 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20aggiornamento=20Phase=205=20=E2=80=94?= =?UTF-8?q?=20IV-RV=20gate,=20F+D+A,=20backtest,=20option=20chain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- docs/01-strategy-rules.md | 85 +++++++++++++++++++++++++++++++++++ docs/05-data-model.md | 69 +++++++++++++++++++++++++--- docs/13-strategia-spiegata.md | 41 +++++++++++++++++ 3 files changed, 189 insertions(+), 6 deletions(-) diff --git a/docs/01-strategy-rules.md b/docs/01-strategy-rules.md index f1473a4..2f0ed3b 100644 --- a/docs/01-strategy-rules.md +++ b/docs/01-strategy-rules.md @@ -41,6 +41,34 @@ sono vere: 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: ` — 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. @@ -77,6 +105,20 @@ assoluto. | 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) @@ -179,6 +221,49 @@ Per ogni posizione aperta, il rule engine valuta in ordine: 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 diff --git a/docs/05-data-model.md b/docs/05-data-model.md index f58f9b9..43de405 100644 --- a/docs/05-data-model.md +++ b/docs/05-data-model.md @@ -202,7 +202,9 @@ CREATE TABLE system_state ( last_kelly_calib TEXT, config_version TEXT NOT NULL, started_at TEXT NOT NULL, - last_audit_hash TEXT -- aggiunto dalla migration 0002 + last_audit_hash TEXT, -- aggiunto dalla migration 0002 + auto_pause_until TEXT, -- aggiunto dalla migration 0004 (§7-bis.3) + auto_pause_reason TEXT -- aggiunto dalla migration 0004 ); ``` @@ -212,6 +214,54 @@ Al boot l'orchestrator confronta questo valore con il tail del file `audit.log`: discrepanza → kill switch CRITICAL, vedi `07-risk-controls.md`. +I campi `auto_pause_until` / `auto_pause_reason` implementano il +circuit breaker §7-bis.3 (pausa automatica su drawdown rolling). +NULL = engine attivo. + +### `option_chain_snapshots` + +Snapshot della catena opzioni Deribit prelevata settimanalmente +(cron `55 13 * * MON`, 5 minuti prima del trigger entry). Ogni +tick contiene un quote per strumento entro la finestra +`[dte_min, dte_max]` di config; tutti i quote prelevati nello stesso +tick condividono ``timestamp``. Migration `0005`. + +```sql +CREATE TABLE option_chain_snapshots ( + timestamp TEXT NOT NULL, + asset TEXT NOT NULL, + instrument_name TEXT NOT NULL, + strike TEXT NOT NULL, + expiry TEXT NOT NULL, + option_type TEXT NOT NULL CHECK (option_type IN ('C','P')), + bid TEXT, + ask TEXT, + mid TEXT, + iv TEXT, + delta TEXT, + gamma TEXT, + theta TEXT, + vega TEXT, + open_interest INTEGER, + volume_24h INTEGER, + book_depth_top3 INTEGER, + PRIMARY KEY (timestamp, instrument_name) +) WITHOUT ROWID; +``` + +Indici: `(asset, timestamp DESC)` per listing recenti, `(asset, +expiry)` per query per scadenza specifica. ``book_depth_top3`` è +NULL by design — il collector non chiama l'order book per ogni +strike per non saturare l'API; lo legge il liquidity gate live solo +sugli strike candidati al picker. + +**Sblocca**: il backtest non-stilizzato (modulo `core/backtest.py` +con prezzi reali invece di Black-Scholes), la calibrazione empirica +dello skew premium, la validazione ex-post dello strike picker. + +Volume atteso: ~50 strike × 3 scadenze × 1 snapshot/settimana × +17 colonne ≈ 12 KB/settimana, ~600 KB/anno. + ## Log file Sotto `data/log/` un file per giorno: `cerbero-bite-YYYY-MM-DD.jsonl`. @@ -289,11 +339,18 @@ da altri processi (es. CLI `state inspect`) non vedano stati parziali. ## Migrations -Lo schema viene tracciato con il counter `PRAGMA user_version`. La -prima volta `0001_init.sql` viene applicato e versione → 1; alla -seconda esecuzione (o su DB già a versione 1) `0002_audit_anchor.sql` -viene applicato e versione → 2. `state.db.run_migrations` è -idempotente. Nessun rollback supportato (migrations forward-only). +Lo schema viene tracciato con il counter `PRAGMA user_version`. +`state.db.run_migrations` applica in ordine ogni file +`NNNN_.sql` con versione superiore a quella corrente, +idempotente, forward-only: + +| Versione | File | Cosa aggiunge | +|---|---|---| +| 1 | `0001_init.sql` | tabelle base (positions, decisions, ...) | +| 2 | `0002_audit_anchor.sql` | `system_state.last_audit_hash` | +| 3 | `0003_market_snapshots.sql` | tabella `market_snapshots` | +| 4 | `0004_auto_pause.sql` | `system_state.auto_pause_until / _reason` | +| 5 | `0005_option_chain_snapshots.sql` | tabella `option_chain_snapshots` | ## Backup diff --git a/docs/13-strategia-spiegata.md b/docs/13-strategia-spiegata.md index 67bd99d..28a435e 100644 --- a/docs/13-strategia-spiegata.md +++ b/docs/13-strategia-spiegata.md @@ -595,6 +595,47 @@ questa logica: muovi da 0.72 a 0.78 e vedi l'APR scattare. 3. **Multi-asset (ETH+BTC)**: come da §4-ter, sblocca il moltiplicatore 2× sulle opportunità a parità di filtri. +## 4-quinquies. Catena opzioni storica (Phase 5) + +In aggiunta a `market_snapshots` (cron `*/15`), il bot raccoglie +ora una seconda fonte di dati: la **catena opzioni Deribit completa** +ogni lunedì alle 13:55 UTC (5 minuti prima del trigger entry). + +Tabella `option_chain_snapshots` — vedi `05-data-model.md` per lo +schema. Cosa registra per ogni strumento entro la finestra +`[dte_min, dte_max]`: + +| Campo | Cosa misura | A che serve | +|---|---|---| +| `bid` / `ask` / `mid` | Prezzi reali Deribit in ETH | P/L reale per backtest | +| `iv` | IV implicita allo strike | Calibrazione skew premium | +| `delta`/`gamma`/`theta`/`vega` | Greeks | Sizing + risk monitoring | +| `open_interest` / `volume_24h` | Liquidità | Validazione gate §4 | + +**Cosa sblocca:** + +- **Backtest non-stilizzato**: il modulo `core/backtest.py` può + sostituire la stima Black-Scholes (con `skew_premium` hardcoded a + 1.5×) leggendo i `mid` reali. Numeri da "stime ex-ante per + ranking" a "P/L empirico per dimensionare capitale". +- **Calibrazione empirica dello skew**: rapporto fra prezzi + Deribit reali e BS pulito → valore data-driven invece di stima a + istinto. Va fatto dopo 4-8 settimane di accumulo. +- **Validazione ex-post strike picker**: "il delta-0.12 era davvero + a 25% OTM in quella settimana?" diventa una `SELECT`. + +**Strumenti CLI:** + +- `cerbero-bite option-chain trigger` — esegue UNA volta il + collector senza aspettare il cron. Utile per test e per popolare + prima del primo lunedì utile. +- `cerbero-bite option-chain analyze [--bias bull_put|bear_call]` — + legge l'ultimo snapshot, simula il selector di strike con la + strategy passata e stampa: short/long strike, delta, width, + credito reale, ratio credit/width, PASS/FAIL del gate + `credit_to_width_ratio_min`. Risponde in tempo reale: "il rule + engine aprirebbe un trade adesso?". + ## 5. Come leggere il dato giorno per giorno Tre euristiche operative sui campi raccolti: