feat(live): REAL-TRUTH ledger — capital aggiornato dal PnL dei fill reali, sim ridotto a diagnostica
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# 2026-06-10 — REAL-TRUTH: il ledger segue i fill reali (sim → diagnostica)
|
||||
|
||||
## Richiesta
|
||||
|
||||
L'utente vuole che sim e reale coincidano — o meglio, che il sim non esista come
|
||||
verità: «voglio vedere dati che hanno avuto movimento reale su exchange». La
|
||||
ricognizione dei 77 eventi reali (dal 2026-06-03) ha mostrato che il gap
|
||||
sim/reale NON era slippage (piccolo, es. −0.15 bps su un TP) ma **contabile**:
|
||||
|
||||
1. **Ledger separati.** Il `capital` che guida portafoglio/ribilanci/sizing era
|
||||
aggiornato dal PnL SIM; il PnL reale finiva in un `real_capital` parallelo che
|
||||
non guidava nulla. MR01 BTC: sim +28.93 vs reale +1.98 sugli stessi 4 trade.
|
||||
2. **Prezzi sim da candele testnet** (spike print, es. 2026-06-07 sim short BTC a
|
||||
65266.5 con mark reale 62395): il sim bookava PnL che il reale non vede. Con
|
||||
il ledger sim come verità, l'equity del portafoglio accumulava questa fantasia.
|
||||
|
||||
Nota: il *notional* reale era GIÀ derivato dalla formula sim
|
||||
(`capital·ps·lev` passato a `_real_open`/`_real_open_pair`) — il punto 1 della
|
||||
richiesta (sizing allineato) si chiude da solo una volta che `capital` è reale.
|
||||
|
||||
## Implementazione (REAL-TRUTH)
|
||||
|
||||
- `StrategyWorker` e `PairsWorker` accettano `real_truth: bool` (default False =
|
||||
shadow storico). Con flag attivo e esecuzione abilitata:
|
||||
- `_real_close`/`_real_close_pair` ritornano `(real_pnl, applied)`;
|
||||
`applied=True` se ci sono fill reali (o chiusura verificata).
|
||||
- `_close_position`/`_close` chiamano la chiusura reale PRIMA dell'update
|
||||
ledger: `capital += real_pnl` (fee reali incluse); `is_win = pnl_reale > 0`.
|
||||
- Il sim resta nel log CLOSE come diagnostica: `pnl_source` ("real" |
|
||||
"sim_fallback"), `sim_pnl`, `real_pnl`.
|
||||
- **Fallback al sim** SOLO se il trade reale non è mai esistito/fillato
|
||||
(REAL_OPEN_FAIL, fill zero) — dichiarato nel log, mai silenzioso.
|
||||
- Runner: `overrides.execution.real_truth` (yml) → `build_worker_for(...,
|
||||
real_truth=)`. `portfolios.yml`: **`real_truth: true`**.
|
||||
- Conseguenza a catena: equity ledger → pesi → allocazioni → notional dei
|
||||
prossimi ordini derivano ora dai soldi veri sul conto. Il `real_capital`
|
||||
parallelo resta come ledger puro-reale di confronto.
|
||||
|
||||
## Test
|
||||
|
||||
`tests/portfolio/test_real_truth.py` (6 test): capital segue i fill reali
|
||||
(single-leg e pairs), una divergenza sim-win/reale-loss viene contata come LOSS,
|
||||
fallback sim dichiarato su REAL_OPEN_FAIL/leg-fail, e modalità shadow invariata
|
||||
senza flag. Suite completa: 99 passed.
|
||||
|
||||
## Limiti onesti
|
||||
|
||||
- I multi-asset (TR01/ROT02/TSM01/XS01) restano sim per costruzione (paper
|
||||
sleeves fuori dal pool, capitale insufficiente per i book multi-leg).
|
||||
- La STORIA del ledger non è riscritta: l'equity attuale (~2154) ingloba il PnL
|
||||
sim accumulato fino a oggi (reale realizzato era ≈ −15.6 dal 3/6). Da ora la
|
||||
divergenza smette di accumularsi; se si vuole un azzeramento (reset equity al
|
||||
conto reale) è un'operazione separata e deliberata.
|
||||
- Le DECISIONI di trading (entry/exit) restano guidate dai prezzi del feed
|
||||
(candele testnet): real-truth corregge la contabilità, non i segnali. Gli
|
||||
spike print del feed possono ancora generare entry/exit subottimali — ma ora
|
||||
il loro effetto si misura in PnL reale, non in PnL immaginario.
|
||||
Reference in New Issue
Block a user