From 2b9adaeea3e5ee8dfa3d25c4fef16a7ec473cd4c Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Fri, 12 Jun 2026 12:24:37 +0000 Subject: [PATCH] docs(diary): reconcile resting + FEED_BOOK_GAP + epoca v1.1.26 (tornata v1.1.27) Co-Authored-By: Claude Fable 5 --- .../2026-06-12-resting-reconcile-feedgap.md | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 docs/diary/2026-06-12-resting-reconcile-feedgap.md diff --git a/docs/diary/2026-06-12-resting-reconcile-feedgap.md b/docs/diary/2026-06-12-resting-reconcile-feedgap.md new file mode 100644 index 0000000..11f5408 --- /dev/null +++ b/docs/diary/2026-06-12-resting-reconcile-feedgap.md @@ -0,0 +1,74 @@ +# 2026-06-12 — Reconcile resting + guard feed↔book + epoca report (v1.1.27) + +## Contesto: la notte ha validato (di nuovo) il tema osservabilità + +Due eventi nelle 24h hanno motivato la tornata: + +1. **MR02_BTC (06:00):** il TP resting LIMIT ha fillato sul **book reale** a 60481 + nella notte (+6.55 USD reali) mentre il **feed sim** non è mai sceso sotto 63285 + (−443 bps di divergenza, sim chiuso a time_limit con −1.25). Il disaster-SL è + risultato `order_not_found` alla cancel (probabile auto-cancel a posizione flat). + Caso SPECULARE del TP_PHANTOM: lì il feed stampa wick che il book non ha; qui il + book si muove e il feed non lo vede. Real-truth ha bookato il reale (corretto), + ma il sistema se n'è accorto solo ORE dopo, al close sim. +2. **Incidente venue (dalle ~09:47):** il conto Deribit testnet ha iniziato a + rifiutare ordini (`locked_by_admin`, `invalid_reduce_only_order`) e le posizioni + sul conto sono cambiate da sole (ETH LONG 0.141 con avg 1849.5 — prezzo vecchio + di settimane): **rollback/reset admin del testnet**, non un nostro bug. Difese OK: + `REAL_CLOSE_PARTIAL`, leg-fail con unwind, orfani registrati (ETH −0.026, + SOL +0.7), `sim_fallback` dichiarato. MA: il reconciler delle 11:40 è **morto in + silenzio** su un 502 — il guardiano che non suona è indistinguibile dal tutto-ok. + +## Fatto + +### 1. Reconcile degli ordini RESTING (cron :40, read-only) + +- **cerbero-mcp 9a74052:** nuovo endpoint Deribit `get_open_orders` + (`private/get_open_orders_by_currency`; per i trigger untriggered interrogare + anche `type='trigger_all'` e merge per order_id). Pattern già presente per + Hyperliquid/IBKR. Rebuild + smoke su testnet (book vuoto == stato atteso). +- **`books.expected_resting()`:** TP/DSL attesi dai libri dei worker single-leg + in posizione reale (i pairs non hanno resting). +- **`reconcile_account.compute_resting_drift()`** — tre classi: + `FILLED_UNBOOKED` (atteso non in book + fill nel trade history col worker ancora + in posizione = il caso MR02), `MISSING` (atteso, non in book, zero fill — per il + DSL triggered il fill ha order_id NUOVO → appare qui e il drift posizioni + completa), `STALE` (in book con label di un nostro worker ma nessun libro: + fillerebbe a sorpresa). Anti-race come per le posizioni; alert `RESTING_DRIFT`. +- **`RECONCILE_FAIL`:** il main è ora guardato — su eccezione alert Telegram + + exit 2 (fix del crash silenzioso delle 11:40). + +### 2. Guard FEED_BOOK_GAP nel runner + +`_check_feed_book_gap`: ad ogni poll confronta il close della candela in corso col +**mark dello strumento d'ESECUZIONE** (USDC, `get_ticker_batch`, 1 chiamata); +oltre soglia (`overrides.feed_book_gap_bps`, default 150) → alert per episodio, +recovery con isteresi a soglia/2, fail-open su errori di rete. Le decisioni +restano sul feed (il sim è la verità che guida): questo dice solo QUANDO i fill +reali possono divergere dal sim. Avrebbe segnalato il caso MR02 in tempo reale. + +### 3. Epoca v1.1.26 nell'hourly_report + +I conteggi CHIUSI cumulativi erano inquinati dal churn TP-fantasma dell'11-06 +17:32–17:58 (~24 giri pre-fix). Nuova riga `epoca v1.1.26+ (TP_PHANTOM attivo)` +da `EPOCH_V1126 = 2026-06-11T21:40` (deploy del gate): oggi legge **7/1** contro +il 18/17 storico — è il numero da confrontare col backtest da qui in poi. + +## Test e deploy + +`pytest` 121 passed (114 + 7 nuovi: `test_reconcile_resting.py`, +`test_feed_book_gap.py`). Deploy **v1.1.27** (runner nel container; reconciler e +hourly_report girano da host → già attivi). cerbero-mcp rebuildato (endpoint). + +## Aperto / lezioni + +- **Drift ETH +0.167 non spiegato** dal rollback testnet: quando il conto si + sblocca serve `reset_flatten` + riallineamento ledger (decisione utente). +- I **residui dei close single-leg falliti** (`REAL_CLOSE_PARTIAL`, es. MR07 + 0.102) NON finiscono in `orphan_legs` → il reconciler li vede come drift NON + spiegato. Estendere la registrazione orfani anche al single-leg è il naturale + passo successivo (punto in analisi sviluppi). +- Il testnet può **riscrivere il conto sotto i piedi** (lock + rollback): nessuna + invariante "il conto cambia solo per nostri ordini" è affidabile. Il reconciler + orario è l'unico rilevatore; valutare cadenza più fitta in presenza di + posizioni reali aperte.