c21e1dc635
- 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>
173 lines
8.1 KiB
Markdown
173 lines
8.1 KiB
Markdown
# 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 (€500–1500) per 2–4 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 ~€5–8k 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, 2–4 settimane
|
||
`portfolios.yml` per il micro-test:
|
||
```yaml
|
||
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 **≥10–20 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 ~€20–50, 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 = **€20–80**. È 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
|
||
|
||
- [x] MAINNET_TOKEN Cerbero abilitato + verificato (auth OK, is_mainnet=True) — 2026-06-14
|
||
- [x] 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 ≥10–20 trade: leggere il verdetto → scala / aspetta / stop
|