Files
PythagorasGoal/Old/docs/specs/mainnet-microtest-plan.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

9.0 KiB
Raw Blame History

Piano operativo — Micro-test MAINNET (Deribit)

Obiettivo. Rispondere all'unica domanda che testnet e backtest non possono: quando si passa ai fill VERI, quanto edge sopravvive? Si misura con poco denaro reale (€5001500) per 24 settimane, leggendo il report ledger-vs-backtest. Costo del verdetto: poche centinaia di € invece di scoprirlo a €5k.

Perché serve (e perché testnet non basta). Testnet ha feed farlocchi — il 2026-06-13 ETH-PERPETUAL inverse era congelato a 1661.95 da 12h+ mentre il prezzo reale si muoveva (gap 1.3%); BTC era vivo. Su mainnet l'arbitraggio tiene inverse ≈ lineare ≈ realtà (entro bps): il micro-test risolve il problema feed per costruzione, oltre a dare fill/slippage/fee reali. (Il 2026-06-14 ETH-PERPETUAL testnet era ancora congelato a 1661.95 da 36h+ → conferma definitiva: testnet è inaffidabile.)


STATO (2026-06-16)

  • Token mainnet wired e VERIFICATO. MAINNET_TOKEN (da cerbero-mcp, che ha già le chiavi Deribit LIVE) copiato in .env.mainnet (chmod 600, gitignored), SEPARATO dal .env condiviso. Verifica read-only: is_mainnet()=True, auth OK su get_account_summary (nessun ordine). Il .env condiviso resta testnet → il runner attuale NON flippa a mainnet a un riavvio.
  • FASE 0 SMOKE VERDE (2026-06-16). Catena d'esecuzione validata su mainnet con soldi VERI a costo ~0: LIMIT SELL ETH_USDC spot 0.0138 ETH @ floor 1776.3 (marketable, NON market) → order_state=filled, average_price 1778.1 (= bid, zero slippage negativo), fee 0.0. Riconciliazione conto: USDC 25.00→49.54 (+24.54), ETH→0.000078 dust, nessun ordine resting. Provato end-to-end: routing live + auth + place_order limit + fill + verifica trade + balance. (Doppio scopo: consolidare l'ETH stranded in margine USDC + smoke.) Diario docs/diary/2026-06-16-mainnet-fase0-smoke.md.
  • 🟡 FINANZIAMENTO PARZIALE: ~$49.54 USDC (deposito iniziale ~$50: 25 USDC + 0.0138 ETH, ora consolidati). Sotto il minimo €500 del piano → basta per la meccanica (Fase 0 ) ma NON per testare l'edge (a $50 di margine il rumore di arrotondamento BTC soffoca il segnale). Serve top-up a ~€500-1000 USDC prima della Fase 1.
  • ⏭️ Appena finanziato a ~€1000: avviare il micro-test come servizio separato (env_file .env.mainnet, dir dati pulita, portfolios.yml fade-only) → Fase 1.

Prerequisiti (umani, fuori dal codice)

  1. Conto Deribit MAINNET (KYC) finanziato con ~€1000 in USDC (vedi sizing).
  2. MAINNET_TOKEN Cerbero abilitato al trading mainnet sul conto (lato CerberoSuite).
  3. Decidere il capitale: €1000 raccomandato (vedi sezione Sizing).

NB sicurezza: il MAINNET_TOKEN dà accesso a soldi veri. Va in .env (gitignored), mai committato. Un bot-tag dedicato (pythagoras-mainnet) per isolarlo nell'audit.


Come si punta a mainnet (già pronto, 1 sola modifica .env)

Il client legge il token da env (default = testnet). Il token mainnet vive in un file .env.mainnet DEDICATO (NON nel .env condiviso, che resta testnet → il runner attuale non flippa a mainnet a un riavvio):

# .env.mainnet (gitignored, chmod 600) — caricato SOLO dal servizio micro-test mainnet
CERBERO_TOKEN=<MAINNET_TOKEN>
CERBERO_BOT_TAG=pythagoras-mainnet

Il servizio micro-test usa env_file: [.env, .env.mainnet] (le chiavi di .env.mainnet prevalgono → Telegram da .env, token mainnet da .env.mainnet).

Nessuna modifica di codice. CerberoClient.is_mainnet() lo rileva; il runner, l'ExecutionClient e gli smoke usano lo stesso client. Per tornare a testnet: togliere le due righe. (Verificato: default invariato testnet, override flippa il rilevamento.)

Consiglio: non riusare il container/data testnet. Avviare il micro-test su una dir dati pulita (data/ separata o nuovo volume) così i ledger reali mainnet non si mescolano allo storico testnet, e il report parte clean-start.


Sizing & taglia — perché €1000 e SOLO le fade in fase 1

Notional = alloc_sleeve × position_size × leverage; amount = notional/prezzo, quantizzato allo step Deribit. Rumore di arrotondamento = step/amount.

Fades-only (6 sleeve equal, pos 0.5 × leva 3) — rumore arrotondamento:

Capitale notional/fade round% BTC round% ETH
€500 $125 5.2% 1.3%
€1000 $250 2.6% 0.7%
€1500 $375 1.7% 0.4%

€1000 è il punto giusto: BTC ~2.6% di rumore (leggibile), abbastanza piccolo da non far male. €500 funziona ma BTC sale al 5%; €1500 è il più pulito.

Perché NIENTE pairs/SH01 in fase 1:

  • Pairs (pos 0.13, 2 gambe): a €1000 il notional/gamba è ~$21 → arrotondamento ~30% (la gamba alt anche peggio): a questa taglia misureresti l'arrotondamento, non l'edge. Servono ~€58k per pairs puliti. Inoltre l'executor a 2 gambe ha leg-risk: più superfici d'errore. → fuori dalla fase 1.
  • SH01: bootstrap full-history dal parquet inverse; su mainnet va ri-derivato il parquet da prezzi mainnet. Diversificatore, non core. → fuori dalla fase 1.

Le 6 fade single-leg (MR01/02/07 × BTC/ETH) sono il core edge, l'esecuzione più semplice (open market + TP limit resting + disaster-SL), e quelle col track record validato col worker reale. Sono il test giusto.


Fasi

Fase 0 — Smoke mainnet (€0 di rischio reale, 1 ordine minimo)

Con il token mainnet attivo, eseguire live_exec_smoke.py (ordine→verifica→fee) e live_shadow_smoke.py su size minima per confermare: auth mainnet OK, strumenti USDC risolti, fill verificato per order_id, fee reali lette. Se uno fallisce, STOP.

Fase 1 — Solo fade, €1000, 24 settimane

portfolios.yml per il micro-test:

overrides:
  total_capital: 1000
  leverage: 3                 # config che vorremmo deployare (misura il vero)
  position_size: 0.5
  paper_sleeves: [TR01, ROT02, TSM01, XS01, PR01..., SH01...]   # tutto tranne le 6 fade -> paper
  execution:
    enabled: true
    sleeves: [MR01, MR02, MR07]      # solo fade (DIP01 opz.: 1h BTC, core honest)
    pairs_enabled: false             # niente 2-gambe in fase 1
    disaster_sl_pct: 0.30            # rete di coda invariata
    real_truth: true

Alternativa prudente settimana-1: leverage: 2 per dimezzare il DD mentre si verifica l'esecuzione, poi 3.

Avviare il runner mainnet (container separato o stessa immagine con .env mainnet),

  • reconciler orario + report ledger-vs-backtest giornaliero --since <data-start>.

Fase 2 — Verdetto (dal report ledger-vs-backtest)

Aspettare ≥1020 trade reali (su mainnet le fade ETH/BTC tradano regolarmente, no feed congelato). Criterio (lo stesso del report, soglie già nel verdetto 🟢/🟡/🔴):

  • 🟢 slippage medio ≤15 bps E leakage per-trade < €0.30 in relativo → l'edge regge, si scala.
  • 🟡 leakage moderato → estendere il campione, capire dove perde.
  • 🔴 slippage >40 bps o leakage che mangia l'edge → NON scalare; l'edge non sopravvive all'esecuzione (hai perso ~€2050, non €5k).

Fase 3 — Espansione (solo se 🟢)

  1. Alzare il capitale (€1000→€2k→€5k) — i pairs diventano puliti sopra ~€5k.
  2. Riaccendere pairs (a conto flat) e SH01 (con parquet mainnet).
  3. Continuare a leggere il report ad ogni step.

Rischi & safeguard (già implementati)

  • Disaster-SL on-book 30% ad ogni apertura → protegge da outage del runner.
  • Reconciler orario (reconcile_account --telegram) → drift conto-vs-libri + guard STALE_REAL_POSITION (worker non gestito).
  • Netting close (v1.1.25) → niente gambe orfane/close cappati.
  • Real-truth ledger → equity = soldi veri sul conto.
  • Kill-switch: execution.enabled: false (smette di aprire reali, gestisce le uscite) oppure stop del container + flatten manuale (procedura già rodata).
  • Perdita massima plausibile in fase 1: qualche % di €1000 = €2080. È il prezzo del verdetto.

Cosa NON fare

  • Non partire con pairs/SH01 (rumore/complessità).
  • Non scalare prima del verdetto 🟢 stabile per più giorni.
  • Non mescolare i dati testnet e mainnet nello stesso ledger.
  • Non committare mai il MAINNET_TOKEN.

Checklist di avvio

  • MAINNET_TOKEN Cerbero abilitato + verificato (auth OK, is_mainnet=True) — 2026-06-14
  • Token in .env.mainnet (separato, gitignored, chmod 600) + CERBERO_BOT_TAG=pythagoras-mainnet
  • Fase 0 smoke mainnet VERDE (LIMIT SELL ETH_USDC filled, fill@bid, fee 0, balance riconciliato) — 2026-06-16
  • [] Conto Deribit mainnet finanziato: **$49.54 USDC** (parziale, sotto il min €500) ← TOP-UP a ~€1000 = BLOCCO Fase 1
  • Servizio micro-test separato (env_file .env.mainnet, dir dati pulita)
  • portfolios.yml micro-test (fade-only, €1000, exec sleeves MR01/02/07)
  • runner mainnet + reconciler + report ledger-vs-backtest schedulati
  • dopo ≥1020 trade: leggere il verdetto → scala / aspetta / stop