Files
PythagorasGoal/docs/diary/2026-06-11-system-audit.md
T
Adriano Dal Pastro 429fa01c97 fix(exec): verità contabile sul netting — filled_amount, gambe orfane, tick isolato
Da audit live (3 indagini parallele, diario 2026-06-11-system-audit.md): il modello
quote-per-worker reduce-only si rompe con direzioni opposte sullo stesso strumento
(pairs long ETH vs fade short ETH) — close cappati bookati pieni, 3 gambe pairs mai
eseguite col PnL sim nel ledger reale, conto short 0.027 ETH oltre i libri
(riallineato a mano + DSL orfano cancellato).

- Fill.filled_amount (order.filled_amount): TUTTI i ledger usano il fillato reale
- REAL_CLOSE_PARTIAL (log+alert) su close cappato; residuo orfano dichiarato
- pairs: PnL solo per gambe verificate; gamba respinta -> orphan_legs persistito
  + alert PAIR_LEG_ORPHAN; applied solo con entrambe le gambe (else sim_fallback)
- REAL_DIVERGENCE anche su jsonl (prima solo Telegram)
- runner: tick isolato per-worker + WORKER_ERROR_STREAK a 5 fail consecutivi

Strutturale APERTO (decisione utente, opzioni nel diario): position-manager
centrale / sotto-conti per famiglia / status-quo monitorato.

Test: +2 (partial-close, orphan-leg), fixture filled_amount -> 106 passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 20:05:42 +00:00

4.4 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.

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.