Files
PythagorasGoal/Old/docs/diary/2026-06-13-orphan-swap-guard.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

2.2 KiB

2026-06-13 — Orfano da swap: incidente + guard nel reconciler

Incidente

Lo stato trades del mattino ha scoperto una posizione reale orfana: il worker fade MR02_BTC 1h aveva aperto uno short reale (0.0028 BTC @ 64135.5) ieri alle 15:01; lo swap a 15m (v1.1.30, ~20:48) lo ha rimosso dal config mentre era ancora in posizione → da allora nessun runner lo gestiva. Stato:

  • conto Deribit: short 0.0028 BTC (il long di apertura del gemello 15m aveva aperto e chiuso nettando via il resto)
  • il TP limit (63387.75) era sparito dal book (cancellato durante il netting della chiusura 15m) → short NUDO, protetto solo dal disaster-SL a +30%
  • il reconciler NON allarmava: lo status.json del worker morto dichiarava ancora real_in_position: true → conto == libri. Punto cieco: il reconciler leggeva i libri dagli status ma non sapeva quali worker fossero VIVI.

Chiusura manuale (testnet): buy 0.0028 reduce-only @63766.5 (~+$0.85 netto sullo short), cancel disaster-SL, worker marcato flat, PnL bookato (real_capital 181.18→182.03). Conto verificato flat su BTC; SH01_ETH short intatto.

Guard implementato

reconcile_account.compute_stale_real_positions(max_age_min=15): segnala i worker che dichiarano real_in_position ma il cui status.json è fermo da oltre 15 min. Un worker vivo riscrive lo status a ogni poll (~60s) → la staleness è il discriminante robusto e venue-agnostico (cattura ritirati-da-swap, crashati, worker rimossi dal config). Alert Telegram STALE_REAL_POSITION (con --telegram), incluso nell'exit code e nel verdetto. Gira già al prossimo cron host (:40) — nessun rebuild (lo script gira dal working tree). Test: tests/portfolio/test_reconcile_resting.py (stantio flaggato / fresco no / flat-vecchio no).

Causa radice e direzione

La feature INIT_LINEAGE di ieri trasferisce il capitale al gemello del nuovo timeframe, ma non la posizione. Il guard di oggi è la rete di sicurezza (rileva e allarma entro un'ora). La prevenzione vera — flattare/consegnare la posizione reale del worker ritirato al boot del runner — resta da implementare (va fatta lato runner, con cautela: piazza ordini reali all'avvio). Per ora: swap a conto fade-flat quando possibile, e il reconciler copre il resto.