Files
PythagorasGoal/docs/specs/mainnet-microtest-plan.md
T
Adriano Dal Pastro c21e1dc635 docs: timing-sweep pairs/honest (NO deploy) + stato mainnet + vincolo feed v2
- CLAUDE: feed ETH ancora congelato 36h+; vincolo Cerbero v2 (serve SOLO
  5m/15m/1h, 30m/10m -> 400, legacy 404; _SUBHOURLY "30m" speculativo mai
  testato); esito timing-sweep (5m non conviene: regime recente peggiore +
  flat ETH 29%; gate full+OOS necessario ma non sufficiente); stato mainnet
  (token in .env.mainnet verificato is_mainnet=True, conto VUOTO = blocco)
- spec mainnet-microtest: blocco STATO 2026-06-14, .env.mainnet separato +
  servizio dedicato, checklist aggiornata (token done, funding = blocco)
- nuovo diario 2026-06-14-timing-sweep-pairs-honest.md + harness riusabile
  scripts/analysis/timing_sweep_pairs_honest.py
- .gitignore: .env.mainnet (token mainnet mai in git)

Nessuna modifica a codice/config live: PORT06 invariato (19 sleeve).

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

8.1 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-14)

  • 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.
  • 🔴 BLOCCO: conto Deribit mainnet VUOTO (equity 0.0 USDC/BTC/ETH). Serve il deposito (~€1000 USDC) prima di qualsiasi smoke/trade.
  • ⏭️ Appena finanziato: avviare il micro-test come servizio separato (env_file .env.mainnet, dir dati pulita, portfolios.yml fade-only) → Fase 0 smoke → 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
  • Conto Deribit mainnet KYC + finanziato ~€1000 USDC ← BLOCCO ATTUALE (conto a €0)
  • Servizio micro-test separato (env_file .env.mainnet, dir dati pulita)
  • Fase 0 smoke mainnet verde (ordine→verifica→fee)
  • 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