# 2026-06-13 — Equity gonfiata dal ribilancio: +4.77 fantasma (causa + fix) ## Sintomo Report "dall'ultimo reset": equity 2020.53 → 2025.80 (+5.27), ma un solo trade chiuso (MR02_BTC 15m, reale +0.50). Il +4.77 residuo è comparso di colpo a 00:01:52 (primo poll dopo mezzanotte UTC = ribilancio giornaliero), senza alcuna chiusura dietro. ## Causa — doppio conteggio del capitale degli in-position al ribilancio `rebalance_allocations` faceva: 1. `total_capital = Σ capital di tutti i worker` 2. `alloc[sid] = peso × total_capital` per OGNI sid 3. ai worker in posizione NON applicava l'alloc (la posizione tiene il suo notional) 4. ai flat: `capital = alloc[sid]` `update_equity` (ogni poll) = Σ capital. Dopo il ribilancio la somma diventa: Σcapital = Σ(peso_i × total) [flat] + Σ(capital_j) [in-pos] = total − Σalloc_j + Σcapital_j = total + Σ(capital_j − alloc_j) ← inflazione Cioè i flat si dividevano l'INTERO total (che includeva anche il capitale degli in-position), e gli in-position lo tenevano in più → doppio conteggio. Al ribilancio delle 00:01, **MR02_BTC 15m era in posizione** col capitale seedato **181.19** (eredità del gemello 1h, INIT_LINEAGE di ieri) mentre la sua allocazione era ~176.42 → **+4.77** di equity dal nulla. Lo scatenante è stato il seed (capitale ben sopra l'allocazione media) combinato con la posizione aperta al ribilancio; ma il bug era latente da sempre (ogni worker in-pos che devia dall'alloc gonfiava/sgonfiava l'equity al ribilancio successivo). ## Fix — conservazione (ledger.allocate `reserved`) `allocate(weights, reserved={sid: capitale})`: i worker in posizione TRATTENGONO il loro capitale (deployato, non spostabile); i flat si dividono `total − Σreserved` per peso **rinormalizzato sui soli flat**. Così `Σalloc == total_capital` sempre → **l'equity è conservata dal ribilancio** (un ribilancio sposta capitale fra sleeve, non crea valore). `runner.rebalance_allocations` calcola `reserved` dai worker `in_position` e lo passa. Senza `reserved` (default) = comportamento storico (corretto solo a worker tutti flat, es. allocazione iniziale). Test: `tests/portfolio/test_ledger.py::test_alloc_conserves_total_with_reserved`. ## Correzione dello stato (rimozione del +4.77 già accumulato) Equity riportata a **2021.03** = baseline post-seed verificata (2020.53) + unico trade reale (MR02_BTC 15m +0.50). Capitali dei worker del pool scalati × (2021.03/2025.79) e peak del ledger resettato a 2021.03 (il 2025.80 non è mai stato un massimo legittimo → niente DD fantasma). L'orfano MR02_BTC 1h chiuso a parte (+0.85) resta sul worker ritirato, fuori dal pool. ## Esito Equity = soldi veri: dal reset il trading ha prodotto **+0.50** (1 trade), non +5.27. Deploy con codice fixato (rebuild) così il prossimo ribilancio conserva.