Files
PythagorasGoal/docs/diary/2026-07-01-book-live-error-surfacing.md
Adriano Dal Pastro 567046953d fix(book): gate fail-safe posizione + diagnostica equity — niente errori silenziosi nel path live
Terza+quarta chiusura del pattern "eccezione ingoiata -> stato safe silenzioso"
in src/live, dopo skh_error (31369b3). Emerse durante la verifica del gate SKH01.

Opzione A (gate fail-safe posizione):
- shadow._positions: se la read della posizione reale Deribit lancia, assume flat
  MA ora ritorna un pos_error esplicito (prima solo una note mai propagata).
- Propagato shadow_report -> book_report -> book_execute: se ONLINE ma posizione
  IGNOTA, l'esecutore NON opera a cieco (return + alert), come gia' per 'online'.

Opzione B (diagnostica equity, no halt):
- shadow._equity/shadow_report: se ONLINE ma equity reale non leggibile, il book
  ripiega su paper_cap (~$2000) invece del conto reale (~$598) -> sovradimensiona
  ~33%, ma l'hard-cap $300/asset limita il downside. Nuovo flag eq_fallback ->
  book_execute stampa warning + alert Telegram MA prosegue (niente gate: la scelta
  e' solo diagnostica, l'hard-cap gia' protegge).

Test: +8 (4 gate A, 4 diagnostica B). Suite 156/156. Path live pulito
(skh_error/pos_error/eq_fallback = None). Diario 2026-07-01-book-live-error-surfacing.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:39:59 +00:00

59 lines
4.0 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.
# 2026-07-01 — Book live: verifica gate SKH01 + emersione errori silenziosi
## Contesto
Il BOOK DERIBIT armato (TP01 0.75 + SKH01 0.25 nettati) è **flat da quando è stato armato
(2026-06-23)**: 193 run orari, tutte HOLD, zero ordini reali. Domanda: il flat è legittimo o il
gate di SKH01 è muto per un bug?
## Verifica del gate SKH01 — SANO
- **Logica viva:** `skyhook_entries` produce 335 entry (BTC, 222 long/113 short) e 341 (ETH,
226/115) su tutta la storia. Non è degenere.
- **Shorta davvero i crash:** ha aperto SHORT sulla gamba di crollo di fine maggio/inizio giugno —
BTC 05-28→06-04 ($73k→$64k), ETH 06-02→06-06 ($1865→$1555).
- **Flat da 06-23 = legittimo:** ultimo entry 06-06, `max_bars=16 × 230m ≈ 2,5g` → chiuso ~06-08/09,
**prima** dell'arming (06-23). Dal grind post-crash nessun setup breakout+regime valido → flat
corretto per design ("NON trend-follower"). Contesto prezzo al 01-07: BTC 53% dal picco, ETH
67,5%, momentum negativo su 1/3/6/12 mesi → anche TP01 (long-flat TSMOM) è a 0x.
- **Entrambi i feed valutano senza crash:** certificato e live `fresh_5m``skh_error=None`.
## Bug scoperto e corretto — pattern "eccezione ingoiata → stato safe silenzioso"
`src/live/` aveva più `try/except` che, in errore, producono uno stato safe (flat/fallback) **senza
farlo emergere**. Rischio: quando l'errore è transitorio ma reale, l'esecutore opera su dati sbagliati
credendoli legittimi.
### (1) `skh_error` — CORRETTO
`book_report` scriveva `skh_error` in un dict locale **mai incluso nel return**`r.get("skh_error")`
sempre `None`; e `book_execute` non lo leggeva comunque. Un feed SKH rotto avrebbe forzato SKH→flat in
silenzio (entry mancato, nessun alert). Fix: `skh_error` esposto nel return + `book_execute` emette
log `⚠️ SKH FEED ERRORE` + alert Telegram. (commit 31369b3)
### (2) Gate fail-safe posizione (Opzione A) — CORRETTO
`src/live/shadow.py::_positions`: se la read della posizione reale Deribit lancia, assume flat (0.0)
con una `note`, MAI propagata (`pos_src`) a `book_report`/`book_execute`. Severità mitigata a valle
da `rebalance_signed` che **rilegge la posizione fresca** (no doppia-posizione), ma resta il caso
"target≈0 + posizione aperta + read fallita → close saltato quel run" (transitorio, backstoppato dal
disaster-SL 30%). **Scelta A = gate fail-safe:** `_positions` ritorna un `pos_error` esplicito →
propagato `shadow_report → book_report → book_execute`; se presente (ONLINE ma posizione IGNOTA)
l'esecutore **NON opera a cieco** (return + alert), come già fa per `online`.
### (3) Diagnostica equity (Opzione B) — CORRETTO
`src/live/shadow.py::_equity`: se `account_summary('USDC')` e tutte le per-asset falliscono,
`real_eq=None` e `shadow_report` ripiega su `paper_cap` (~$2000 dallo state paper) mentre il conto
reale è ~$598 → il book dimensionerebbe su $2000 invece di $598 (**sovradimensiona ~33%**). Il danno
è limitato dall'**hard-cap $300/asset** in `book_net_target`. **Scelta B = SOLO DIAGNOSTICA** (niente
gate/halt, l'hard-cap già protegge il downside): `shadow_report` calcola `eq_fallback` (ONLINE +
equity reale non leggibile + no override), propagato `→ book_report → book_execute`, che stampa
`⚠️ EQUITY FALLBACK` + alert Telegram **ma prosegue** (a differenza del gate posizione, che blocca).
## Test
Suite completa **156/156** (era 148; +4 gate A + 4 diagnostica B). Dry-run reale di `book_execute`
invariato (nessuna riga d'errore, nessun ordine, conto $598.06 al target). Path live: `pos_error=None`,
`skh_error=None`, `eq_fallback=None`.
## Sintesi finale — i 3 pattern "errore silenzioso" del path live sono ora tutti tracciati
| # | Punto | Comportamento | Emersione |
|---|-------|---------------|-----------|
| 1 | `book_report` feed SKH | SKH → flat | log `⚠️ SKH FEED ERRORE` + alert |
| 2 | `_positions` read fallita | posizione → flat | **HALT** (non esegue) + alert (gate A) |
| 3 | `_equity` non leggibile | sizing → paper_cap | log `⚠️ EQUITY FALLBACK` + alert (diagnostica B) |