Files
PythagorasGoal/docs/diary/2026-06-04-shadow-divergence.md
T
2026-06-04 16:20:07 +00:00

2.2 KiB
Raw Blame History

2026-06-04 — Shadow execution: divergenza sim/reale misurata + TODO limit reduce-only

Deploy v1.0.6

Fix float deployata (74670da + release): _quantize_step con Decimal in src/live/execution.py72*0.001 = 0.07200000000000001 causava Invalid params su Deribit (1 REAL_OPEN_FAIL su MR07 il 2026-06-03). Resume pulito al restart.

Misura della divergenza sim vs reale (primi 7 close shadow)

Bilancio: PnL sim +11.85 USD vs reale +0.62 USD → delta 11.22 USD. Le fee NON sono il problema ($0.63 totali = 0.05%/lato, esattamente l'assunto del backtest). Il problema è tutto nel timing delle uscite.

  • Aperture allineate: slippage da 8 a +27 bps, mediana ~±7 bps. OK.
  • Chiusure take-profit: +235 bps di slippage medio (MR07 ETH short: +257/+267/+283/+333 bps). Causa strutturale, non liquidità: il sim esce al livello TP intrabar (come il backtest), il reale chiude a mercato solo al poll del tick, quando il prezzo è già rientrato (TP toccato a ~1790, fill reale a ~1840). Sim +3 USD a trade, reale ~0.
  • Stop-loss: stessa meccanica ma a favore (MR02 SL: 0.68 reale vs 2.87 sim). Le fade però hanno più TP che SL → netto negativo.
  • 2 REAL_CLOSE non verificate (order_id null, fallback su stima sim). Venue flat (get_positions()=[]), nessuna posizione orfana — ma sorvegliare i prossimi close.

Implicazione onesta: l'edge di MR07 non sopravvive all'esecuzione market-on-poll. Il backtest assume il fill al livello TP; il reale incassa il prezzo post-rimbalzo.

TODO (richiesto, da implementare)

Nello shadow-execution (src/live/execution.py + StrategyWorker): all'apertura della posizione reale piazzare su Deribit un LIMIT reduce-only appoggiato al livello TP (e idealmente stop-market per lo SL), invece di chiudere a mercato al poll — così il fill reale replica l'assunzione intrabar del backtest.

Dettagli da considerare:

  • cancellare/aggiornare l'ordine resting se il sim esce per max_bars o al restart (resume);
  • i 3 fade BTC condividono lo strumento (posizioni nettate per conto): il limit reduce-only deve coprire la SOLA quota del worker, come già fa close_amount;
  • verificare il fill del resting order via get_trade_history (order_id), come per i market.