PairsExecutionClient (compone ExecutionClient): open_pair (2 market long A/short B,
verifica per-gamba, LEG-RISK unwind se una sola filla), close_pair (2 reduce-only via
close_amount, MAI close_position), register_contract (fetch spec USDC). Spec LTC/ADA/SOL
aggiunti. PairsWorker: ledger reale shadow a 2 gambe resume-safe (_real_open_pair/
_real_close_pair, PnL per gamba dir A=+d/B=-d, doppio arrotondamento riportato). Runner:
pairs_executor gated su execution.pairs_enabled (false di default).
Validazione: test 92/92 (open/close, leg-risk unwind, resume) + smoke testnet
end-to-end (open 2 gambe verificate, close reduce-only, PnL reale -0.039 vs sim -0.036,
conto flat). Smoke ora aborta se ci sono posizioni di produzione + usa solo close_amount.
NB incidente testnet documentato (diario): pulizia manuale con close_position ha flattato
le quote shadow dei fade sul conto condiviso -> auto-riconciliazione al prossimo close.
Lezione: mai close_position su strumenti condivisi.
pairs_enabled resta FALSE: accendere con finestra a conto flat + osservazione.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Punti 5-6 dell'improvement-sweep 2026-06-06 (protezione capitale + osservabilita'):
Punto 5 — disaster bracket:
- ExecutionClient.place_disaster_sl: STOP_MARKET reduce-only a ~-30% dall'ingresso
(trigger mark price), piazzato a ogni REAL_OPEN (MR01/MR02/MR07/DIP01) e
cancellato in _real_close. Assicurazione outage: il poll-loop in except lascia
le posizioni reali senza valutazione exit (ETH gap max storico 33%/1h). In
operativita' normale non scatta mai -> 0 costo Sharpe. real_dsl_order_id
persistito (resume-safe). Config overrides.execution.disaster_sl_pct (0.30).
- NB: set_stop_loss di cerbero-mcp e' un private/edit Deribit (solo ordini APERTI)
-> non usabile su market fillati; il bracket e' un trigger order autonomo via
place_order(type=stop_market). Cancel di un trigger order risponde 'untriggered'
(= successo, verificato testnet: re-cancel -> order_not_found).
- Runner: alert Telegram FEED_OUTAGE dopo 5 poll falliti consecutivi (elenco
posizioni reali aperte) + notifica RIPRESO con durata.
Punto 6 — osservabilita':
- in_position nei _save() di TR01/ROT02/TSM01; hourly_report: sezione MULTI-ASSET
(book | ultimo flip | freschezza status) — prima i 3 worker erano invisibili
(collect() filtra su event/in_position che non emettevano); esclusi dalla
tabella IN CORSO (assume entry/bars single-leg).
- live_shadow_smoke esteso: scenari C/D SHORT (TP-resting BUY mai esercitato
prima) + disaster bracket in tutti gli scenari.
Verifiche: 72/72 test; smoke testnet 4 scenari verdi (DSL piazzato/cancellato due
lati, zero ordini orfani sul book, conto flat); multi_asset_section renderizza sui
dati live. Diario docs/diary/2026-06-07-sweep-fixes.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All'apertura reale il worker piazza un limit reduce-only al TP della strategia
(quota del SOLO worker, prezzo quantizzato al tick); alla chiusura sim cancella
il resting, riconcilia i fill (anche parziali) via get_trade_history per
order_id e chiude a market solo il residuo. real_tp_order_id persistito
(resume-safe). SL resta market-on-poll (deliberato: trigger Deribit = nuovo
order_id al trigger, fill non verificabile; e il rimbalzo sul SL lavora a
favore). Smoke testnet 2 scenari OK (resting+cancel / fill immediato).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>