Files
PythagorasGoal/Old/docs/diary/2026-06-11-system-audit.md
T
Adriano Dal Pastro 14522262e6 chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita
Reset del progetto su fondamenta verificate dopo la scoperta che l'intera
libreria "validata OOS" era artefatto di feed contaminato (print fantasma del
feed Cerbero TESTNET + storico Binance/USDT).

- Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e
  CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia
  (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample
  (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE
  50-82% barre flat; XRP/BNB non certificabili).
- Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni
  portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST
  con segnale residuo, da ri-validare in isolamento.
- Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio,
  runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/
  portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/
  (preservati, non cancellati). Diario consolidato in un unico documento.
- Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal +
  src/backtest/engine + load_data; tool dati certificati (rebuild_history,
  certify_feed, audit_feed, multi_source_check).
- Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico
  (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:20:59 +00:00

5.8 KiB
Raw Blame History

2026-06-11 — Audit di sistema + verità contabile sul netting (v1.1.24)

Seconda tornata della giornata (dopo lo sweep strategie): analisi del SISTEMA live (esecuzione, stato, feed, processo) con 3 indagini parallele + fix.

Audit live (dal reset 2026-06-10T21:24Z)

  • Churn phantom-TP quantificato: 20 round-trip fantasma sui fade ETH (2 finestre, 13:06Z e 17:32-17:58Z, feed che stampava wick ~1640 con mercato a 1675-90 per 25 min). Somma real_pnl 2.35 USD vs sim_pnl +80 USD: il real-truth ledger ha contenuto, il gate TP_PHANTOM (v1.1.23) copre il pattern da stasera.
  • Il conto NON quadrava coi libri: short 0.027 ETH in più (l'hedge long ETH del pair ETH/SOL mangiato dai close reduce-only dei fade) e BTC flat con MR02_BTC convinto di essere short (TP resting fillato da uno spike REALE del book a 3.8%, +6.6$ non bookati, che il worker riconcilierà alla chiusura sim) col disaster-SL residuo sul book a posizione flat. Bonifica eseguita: DSL USDC-SLMB-26521 cancellato, riallineo +0.027 ETH reduce-only (fill 1682.5) → conto == libri (verificato).

Root-cause strutturale

Le quote per-worker con ordini reduce-only su un conto a NETTING si rompono quando due worker hanno direzioni opposte sullo stesso strumento (pairs long ETH vs fade short ETH):

  • un close reduce-only può essere cappato (Deribit riduce l'amount in silenzio) → il ledger bookava la chiusura PIENA perché Fill.amount era il richiesto, non il fillato;
  • un close reduce-only nel verso "sbagliato" rispetto al netto viene respinto → la gamba pairs resta orfana sul conto, ma il worker bookava il PnL al prezzo sim e azzerava lo stato (3 volte oggi: PnL fantasma nel ledger real-truth, ETH/SOL di fatto short nudo).

Fix (v1.1.24) — verità, non workaround

  1. Fill.filled_amount (da order.filled_amount, fallback trades/history): tutti i ledger usano il fillato; nota "FILL PARZIALE" nel Fill.
  2. REAL_CLOSE_PARTIAL (log + Telegram): close che filla meno del residuo → residuo orfano dichiarato, REAL_CLOSE verified=false.
  3. Pairs per-gamba: PnL bookato SOLO per gambe con fill verificato; gamba respinta → record in orphan_legs (persistito nello status) + alert PAIR_LEG_ORPHAN; applied=True (real-truth) solo con ENTRAMBE le gambe → altrimenti fallback sim DICHIARATO (meglio del numero mezzo-reale di prima).
  4. REAL_DIVERGENCE anche su jsonl (prima solo Telegram: l'audit ha dovuto ricostruire gli episodi dai REAL_CLOSE).
  5. Runner: tick isolato per-worker — un'eccezione in un worker non salta più gli altri né l'update equity; streak per-worker con alert WORKER_ERROR_STREAK a 5.

Test: 2 nuovi (partial-close, orphan-leg) + fixture aggiornate → 106 passed.

Decisione di design APERTA (per l'utente)

Finché pairs e fade condividono strumenti in direzioni opposte, le chiusure possono orfanizzarsi: ora è VISIBILE e contabilizzato giusto, ma non eliminato. Opzioni: A) Position-manager centrale per strumento (il runner netta i delta di tutti i worker e manda UN ordine; ricostruisce le quote contabilmente) — corretto ma invasivo, da progettare con calma; B) Sotto-conti Deribit separati per famiglia (pairs vs fade) — pulito, richiede setup conto e client multi-token; C) Status quo monitorato: alert PAIR_LEG_ORPHAN + riallineo manuale (oggi: 1 giro in 2 minuti) — accettabile su testnet, NON per capitale vero. Raccomandazione: C ora, A prima di passare a capitale reale.

Secondo passo — FATTO (v1.1.25): NETTING delle chiusure market. close_amount tenta il reduce-only e riesegue il residuo cappato/respinto in market puro (= il netting contro le quote opposte: il conto si muove del delta esatto del libro). Un solo punto di fix (anche close_pair ci passa). Fill combinato per il chiamante (prezzo pesato, fee sommate), evento NET_CLOSE su log+Telegram a ogni fallback, 4 test dedicati. Niente più orfani per costruzione; orphan_legs resta come ultima difesa se fallisce anche il market puro. Effetto collaterale benefico: la chiusura futura della gamba ETH di ETH_SOL#2 (che sarebbe stata respinta di nuovo) ora eseguirà correttamente. La scelta A-vs-B-vs-C resta aperta solo per la parte RESTING (TP/DSL su book condiviso) e per i multi-asset.

Primo passo verso A — FATTO (sera stessa): reconciler read-only. scripts/analysis/reconcile_account.py: per ogni strumento USDC confronta atteso (Σ quote reali dai status.json: single-leg + pairs 2 gambe + orphan_legs registrati = drift SPIEGATO) vs conto reale (get_positions, size/mark → coin), tolleranza 1.5×step, anti-race (ricontrollo a 10s prima di segnalare). In crontab host ORARIO (:40) con alert Telegram ACCOUNT_DRIFT. Al primo run ha beccato un vero positivo: BTC libro short 0.0028 vs conto flat (il TP di MR02_BTC fillato dallo spike reale delle 12:22Z, che il worker riconcilierà alla chiusura sim) — esattamente la classe di divergenza che prima restava invisibile per ore.

Altri esiti della tornata

  • Dedup engine gate (TODO chiuso): _port06_gate_common.py, output 3 gate byte-identici, nessun copy-drift trovato (la paura era fondata ma non ancora avverata).
  • Bug bfill _daily_equity quantificato (TODO aggiornato): NON materiale — OOS invariato per costruzione, FULL DD 3.46→3.67 col fix (l'attuale è lievemente ottimista), nessun verdetto di gate a rischio. Lasciato documentato.
  • Drift monitor in produzione: drift_monitor.py in crontab host (07:15 UTC, Telegram): rolling 60/120g per famiglia vs distribuzione storica propria, warn < p5. Oggi: FADE 120g al p2 (coda storica, nessun intervento), resto normale, XSEC p84.
  • Dati cerbero-bite refreshati: catena opzioni a ~153k righe/asset (fino a oggi 19:30), pannello regime denso (net-GEX 644/673 ultimi 7g). Sempre un solo regime: niente validazione edge, valore forward.