feat(chain): assorbita la raccolta catena opzioni, cerbero-bite dismesso
cerbero-bite viene eliminato. L'unica sua parte irreversibile e' il DATO:
una catena opzioni non si ricostruisce a posteriori (Deribit non serve book
storici, non c'e' un secondo venue). Il codice si riscrive; le ore non
raccolte no.
ASSORBITO
- scripts/live/collect_chain.py + scripts/cron_chain.sh (cron 25 * * * *):
raccolta propria, ~570 strumenti/giro, ~3 min.
- scripts/analysis/import_cb_archive.py: archivio 1.23M righe (2026-05-01+)
+ market_snapshots 17.402 righe (2026-03-26+: dealer gamma, gamma flip,
rischio liquidazioni, funding cross — dati che non abbiamo altrove).
- snapshot sqlite integrale in /opt/docker/backups/manual/ (SHA256).
NON ASSORBITO, con motivo: motore credit-spread ETH (regola "niente
short-vol da modello in deploy", conto a $52 contro minimo $720), GUI, kill
switch/dead-man/audit (abbiamo venue_watch/edge_watch/monitor_health/
fee_watch), dvol_history (fetch_dvol.py ha storia PIU' LUNGA: 2020+ contro
2026-05), decisions/positions (0 posizioni).
TRE DIFETTI DI BITE NON REPLICATI, tutti misurati il 30/07:
1. una chiamata per strumento invece di due (get_order_book?depth=3 da' gia'
quote+greche+IV+OI+book+underlying) + prefiltro OI in una chiamata sola:
551 -> ~290 chiamate per asset;
2. pacing invece di raffica. Il carico non e' mai stato il problema: 570
chiamate/ora = 0.16/s DISTRIBUITE; bite le sparava in 26s (~44/s) e si
auto-saturava il rate limit per-IP (12.186 risposte 429 in 26h, 96% al
minuto :00). Primo giro reale: 574 chiamate, 0 risposte 429. Il minuto :25
e' scelto: :00 era la raffica, :07 e' cron_book (feed 5m di SKH01).
3. quote_status esplicito {ok, no_quote, error} e book_depth NULL su errore
mai 0. "Book vuoto" e "chiamata fallita" sono cose diverse: e' per questo
che il guasto del 29/07 (50% di quote perse, 38 ore) non produsse alcun
segnale. Le righe ereditate restano 'unknown': bite non lo registrava e a
posteriori non e' ricostruibile.
Battuta di cuore in data/chain_collect/runs.jsonl anche a giro fallito,
sorvegliata da monitor_health (1h, max_age 3h): un collettore fermo non
produce niente, e il niente si legge come "nessun dato quel giorno".
Difetto trovato per strada: due formati ISO nella stessa colonna (92 righe
di backfill senza microsecondi). pd.to_datetime senza `format` ne inferisce
uno solo e manda gli altri a NaT -> il dropna a valle li toglieva in
silenzio, e la serie di contesto perdeva 5 settimane slittando dal 26/03 al
01/05. Corretto con format="ISO8601" e scarto RUMOROSO.
Book, pesi, config, strategia INVARIATI. 537 test verdi.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1667,12 +1667,38 @@ df = load_data("BTC", "1h") # OK. load_data("SOL", ...) -> FileNotFoundError (
|
||||
< 365g reali (es. **AXS 83% sintetico → fuori**), (3) gata i gap vol=0 interni. Universo certificato
|
||||
= **51** (era 52). I **19 major di XS01 hanno 0 backfill → invariati** (strategia live non toccata).
|
||||
Verificato direttamente su cerbero MCP. Diario `2026-06-20-cerbero-backfill-fix.md`.
|
||||
- **CATENA OPZIONI REALE (cerbero-bite mainnet) — integrata e certificata 2026-07-30.**
|
||||
`/opt/docker/cerbero-bite` accumula dal 2026-06-09 la catena Deribit **mainnet** (BTC+ETH,
|
||||
entrambe le ali, scadenze 1g→3 mesi, ORARIA, con `book_depth_top3`). Estrazione+certificazione:
|
||||
`scripts/analysis/fetch_cb_chain.py` → `data/raw/cb_chain.parquet` (gitignored, ~1.23M righe);
|
||||
harness `scripts/research/cblib.py`. **È l'unica fonte di prezzi opzioni VERI del progetto** e
|
||||
serve a sostituire il premio modellato BS-su-DVOL (vedi il f di VRP01, misurato il 30/07).
|
||||
- **CATENA OPZIONI REALE — RACCOLTA PROPRIA dal 2026-07-30 (cerbero-bite ASSORBITO e dismesso).**
|
||||
`/opt/docker/cerbero-bite` (progetto separato) accumulava dal 2026-06-09 la catena Deribit
|
||||
**mainnet** BTC+ETH; **viene eliminato, e la raccolta è passata dentro PythagorasGoal**:
|
||||
- **raccolta:** `scripts/live/collect_chain.py`, cron **`25 * * * *`** (`scripts/cron_chain.sh`) →
|
||||
`data/raw/cb_chain/YYYY-MM-DD.parquet`. Entrambe le ali, scadenze ≤95g, OI≥100, ~570 strumenti
|
||||
a giro, ~3 min. **Minuto :25 scelto, non arbitrario:** :00 era la raffica di bite, :07 è
|
||||
`cron_book` (feed 5m di SKH01, la cosa che non deve trovare l'IP occupato).
|
||||
- **archivio ereditato:** `scripts/analysis/import_cb_archive.py` (una-tantum) →
|
||||
`cb_chain/bite_archive.parquet` (1.23M righe, 2026-05-01+) e `cb_market_snapshots.parquet`
|
||||
(17.402 righe, 2026-03-26+: DVOL, RV30, funding perp e cross, **dealer net gamma**, gamma flip,
|
||||
**rischio liquidazioni**, giorni all'evento macro — dati che il progetto non ha altrove).
|
||||
Snapshot sqlite integrale in `/opt/docker/backups/manual/cerbero-bite-20260730/` (SHA256).
|
||||
- **certificazione:** `scripts/analysis/certify_cb_chain.py`; **harness** `scripts/research/cblib.py`
|
||||
(`load_chain()` unisce archivio + raccolta, dedup su `(ts, strumento)`).
|
||||
- **battuta di cuore:** ogni giro scrive `data/chain_collect/runs.jsonl`, sorvegliato da
|
||||
`monitor_health` (cadenza 1h, `max_age_h=3`) — **un collettore fermo non produce niente, e il
|
||||
niente si legge come "nessun dato quel giorno"**.
|
||||
**TRE DIFETTI DI BITE NON REPLICATI** (misurati il 30/07): (a) **una chiamata per strumento** —
|
||||
`get_order_book?depth=3` dà già quote+greche+IV+OI+book+underlying, bite ne faceva due con
|
||||
rischio di disallineamento; (b) **pacing** (token bucket 4/s + backoff) invece della raffica —
|
||||
il carico non è mai stato il problema (~570 chiamate/ora = 0.16/s **distribuite**), bite le
|
||||
sparava in ~26s (~44/s) auto-saturandosi il rate limit per-IP; misurato sul nostro giro:
|
||||
**574 chiamate, 0 risposte 429**; (c) **`quote_status` esplicito** in {`ok`, `no_quote`, `error`}
|
||||
— "book vuoto" (fatto di mercato) e "chiamata fallita" (fatto di infrastruttura) sono cose
|
||||
diverse, e `book_depth_top3` è **NULL su errore, mai 0**. ⚠️ Le righe ereditate da bite hanno
|
||||
`quote_status='unknown'`: bite non registrava il perché, e si dichiara l'ignoranza invece di
|
||||
inventare uno stato.
|
||||
**NON assorbito, e perché:** il motore credit-spread ETH (il progetto ha già la regola "niente
|
||||
short-vol da modello in deploy"), la GUI, kill switch/dead-man/audit (PythagorasGoal ha
|
||||
`venue_watch`/`edge_watch`/`monitor_health`/`fee_watch`), `dvol_history` (`fetch_dvol.py` ha
|
||||
storia **più lunga**: 2020+ contro 2026-05), `decisions`/`positions` (59 righe a capitale $52,
|
||||
0 posizioni). Test `tests/test_collect_chain.py` (11) + `tests/test_cb_chain_vrp.py` (13).
|
||||
**Perché si MEMORIZZA invece di interrogarla:** una catena opzioni non è ricostruibile a
|
||||
posteriori — Deribit non serve book storici, un'ora non raccolta è persa per sempre, e non c'è un
|
||||
secondo venue da cui recuperarla.
|
||||
@@ -1684,8 +1710,8 @@ df = load_data("BTC", "1h") # OK. load_data("SOL", ...) -> FileNotFoundError (
|
||||
ogni giro, **96% al minuto :00**, generate dalla spazzata full-chain che si auto-satura) →
|
||||
`bid`/`ask`/`iv`/`delta` NULL e **conteggio righe INVARIATO** (13k/giorno prima e dopo). Tasso di
|
||||
quote vuote per settimana: 0.4·0.7·2.2·1.5·0.5·0.4·0.3 → **22%**; giorno peggiore **51.7% BTC /
|
||||
30.6% ETH**. Il fix lato bite (cron `:00`→`:20`) è **scritto ma non attivo** (`strategy.yaml` è
|
||||
copiato nell'immagine, serve rebuild). **REGOLA: una riga presente non è un dato presente** —
|
||||
30.6% ETH**. ✅ **Risolto dal cambio di collettore** (30/07): la raccolta propria è paced e ha
|
||||
fatto 574 chiamate con **0 risposte 429**. **REGOLA: una riga presente non è un dato presente** —
|
||||
contare ciò che è QUOTATO, non ciò che è SCRITTO (3ª occorrenza dopo `paper_dvolspread` e
|
||||
`fresh_5m`). **REGOLA: un guasto IN CORSO si misura al GIORNO PEGGIORE, non in media** — la prima
|
||||
stesura confrontava "tutto" con "ultimi 7g" e diluiva un guasto di 2 giorni al 13.5%, commettendo
|
||||
|
||||
Reference in New Issue
Block a user