Files
Cerbero-Bite/docs/01-strategy-rules.md
Adriano 881bc8a1bf Phase 0: project skeleton
- pyproject.toml with uv, deps for runtime + gui + backtest + dev
- ruff/mypy strict config, pre-commit hooks for ruff/mypy/pytest
- src/cerbero_bite/ layout with empty modules ready for Phase 1+
- structlog JSONL logger with daily rotation
- click CLI with placeholder subcommands (status, start, kill-switch,
  gui, replay, config hash, audit verify)
- 6 smoke tests passing, mypy --strict clean, ruff clean

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 23:10:30 +02:00

226 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
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% |
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.
## 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.