Pannello "P/L atteso — Conservativa vs Aggressiva":
* Sostituiti slider Capitale/Spot con slider parametrici Cap/trade
(EUR) + posizioni concorrenti. Il capitale richiesto viene calcolato
in automatico via Kelly-binding aggregato:
capital = cap_pertrade_usd × concorrenza / max(kelly, 1e-3).
* Profili Conservativa/Aggressiva ora ereditano dai yaml SOLO le leve
qualitative (width_pct, credit_ratio, kelly_fraction, feature
attive); le leve di sizing (cap, concorrenza) sono comandate dagli
slider per confronti omogenei.
* Tre metriche header: capitale richiesto, cap aggregato notional,
cap per trade USD.
Fix in `_compute_pl`:
* Max loss per contratto era `width` (errato per credit spread).
Corretto a `width − credit` allineato a core/sizing_engine.py.
Effetto: n_kelly aumenta proporzionalmente al credit incassato →
P/L stimato più realistico per spread con credit_to_width_ratio
alto (es. 0.30+ in profilo Aggressiva).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Estende il pannello "💰 P/L atteso" della pagina `📚 Strategia` per
applicare gli effetti stimati di IV-RV gate, A (delta dinamico),
D (vol-harvest) e F (auto-pause) leggendoli direttamente dai
`strategy.*.yaml` di ciascun profilo.
- Nuova `_detect_features(strategy)` che ispeziona la config:
A → `short_strike.delta_by_dvol` non vuoto
D → `exit.vol_harvest_dvol_decrease > 0`
F → `auto_pause.enabled`
IV → `entry.iv_minus_rv_filter_enabled`
- `_compute_pl` accetta ora un dict `features` opzionale e applica:
IV: +5 pp win-rate, −25% trade/anno (skip-week aggressivo)
A: +1.5 pp win-rate, sl_loss × 0.95 (strike picking migliore)
D: 5% trade convertiti da loss a harvest exit (+0.20×credito)
F: −8% trade/anno (skip-week dopo streak)
- `_render_profile_card` mostra ora:
badge "🟢 Miglioramenti attivi" con la lista per profilo,
delta vs base in E[trade] e P/L annuo,
help con win_rate effettivo / prob_loss / trade/anno.
- Checkbox "Applica effetti dei miglioramenti" (default ON) per
switchare tra simulazione realistica e formula base.
- Nuova mini-tabella "Contributo marginale di ogni feature": per
ogni miglioramento mostra ΔP/L annuo e ΔAPR isolando l'effetto
del singolo feature, con marker "✅ attiva nel YAML".
- Sensibilità win-rate ora applica le feature attive ai due profili.
Effetti dichiarati come **stime ex-ante** dalla letteratura
short-vol systematic; i valori puntuali (+5 pp win, etc.) andranno
calibrati sul dataset accumulato.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Due metriche per ciascun profilo nel pannello P/L:
- **Max DD attesa (P99)**: streak di stop consecutivi con probabilità
≤ 1% nell'anno (union-bound: N_trade × p_loss^N ≤ 0.01) ×
perdita stop × contratti × posizioni concorrenti.
- **Max DD coda (gap)**: scenario gap notturno in cui il mark salta
oltre la copertura long PRIMA che lo stop sia eseguibile —
perdita = larghezza intera meno credito iniziale, su tutte le
posizioni aperte.
Aggiunge anche colonna "Max DD" nella tabella di sensibilità
win-rate, così si vede immediatamente il trade-off
APR-vs-drawdown al variare del win-rate (da 65% a 82%).
Effetto pratico: a default cap=10k, spot=3000, win=0.75, trades=18:
- Conservativa: APR ≈ +1.8%, Max DD attesa ≈ −2.2% capitale
- Aggressiva: APR ≈ +14%, Max DD attesa ≈ −30% capitale
Numeri che rendono molto più tangibile la frase "drawdown scala con
lo stesso fattore" del §4-ter del documento.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Espone la GUI Streamlit su https://cerbero-bite.tielogic.xyz tramite il
Traefik già attivo sull'host (label allineate al pattern di cerbero-mcp,
TLS via Let's Encrypt, websocket pass-through). Aggiunge:
- nuova tab `📚 Strategia` con stato live dei gate §2 confrontati con
l'ultimo tick di market_snapshots, pannello P/L parametrico
affiancato Conservativa vs Aggressiva, tabella di sensibilità
win-rate → APR e rendering del documento canonico esteso.
- doc `13-strategia-spiegata.md` che lega ogni regola §2-§9 al campo di
market_snapshots che la alimenta, con sezioni §4-bis (P/L atteso
realistico, win-rate empirico, drawdown, Sharpe) e §4-ter (confronto
fra i due profili e quando passare dall'uno all'altro).
- `strategy.conservativa.yaml` (golden config v1.0.0 esplicita) e
`strategy.aggressiva.yaml` (cap_per_trade 4×, max_concurrent 2×,
max_contracts 4×, deroga §11 documentata) con config_hash validi.
- nel compose: servizio dedicato `cerbero-bite-gui` (Streamlit su
0.0.0.0:8765, healthcheck su /_stcore/health, label Traefik), env
condivisi via anchor YAML `x-bite-env`, `--environment mainnet`
passato a `start` per allineare il boot check al token del .env (era
testnet vs mainnet → kill switch armato all'avvio).
- Dockerfile installa anche l'extra `gui` (streamlit) e copia
`docs/` + i due nuovi profili nell'immagine; `.dockerignore` non
esclude più `docs/` (causa del primo build silenzioso).
Fix bonus: `_try_load` nella pagina ritornava `LoadedConfig` ma la GUI
leggeva `.sizing.*` direttamente — l'`except: pass` mascherava
l'AttributeError facendo cadere sui default conservativi sia nel
pannello P/L sia nello stato gate (stesso pattern presente nella
Calibrazione). Ora ritorna `.config`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>