fix(live): 4 hardening da code-review — REAL_DIVERGENCE, outage su feed vuoto, bars.py condiviso, DSL cancel retry

Review multi-agente 7-angoli su 8c4e1cd..HEAD + check trades live:

1. Alert Telegram REAL_DIVERGENCE quando |slippage sim/reale| >= 100bps a
   open/close. Causa scatenante: spike print testnet 10:37 (candela 10:00
   H=65618, O/C ~62400) -> 3 fade BTC short su close fantasma 65266.5, reale
   fillato a 62395 (-440bps), sim +2.26 mai esistiti — passato in silenzio.
2. FEED_OUTAGE anche su feed degradato SENZA eccezione (HTTP 200 + candles
   vuote: i worker saltavano il tick in silenzio, streak a 0). Helper unico
   _outage_tick; chiavi payload uniformate (minuti su start e RIPRESO).
3. src/live/bars.py: detection forming-bar unificata (bar_ms_of /
   last_bar_is_forming / last_settled_idx) — era copiata in 4 punti
   (strategy_worker, basket, pairs, _check_stale_feed hardcoded 1h).
   E' l'invariante di sicurezza EXIT-16: ora una sola implementazione testata.
4. DSL cancel hardening in _real_close: retry su errore transitorio + alert
   REAL_DSL_CANCEL_FAIL se lo stop resta forse orfano sul book (prima l'id
   veniva dimenticato in silenzio); order_not_found = probabile trigger in
   outage -> solo log (il close a valle esce gia' verified=False).

Refutato il finding top dei finder ("stop_market senza trigger"): cerbero-mcp
traduce price->trigger_price+mark, e in produzione 2 DSL armati + 1 ciclo
completo pulito (MR07_BTC).

Test: 83/83 (9 nuovi: bars helper + DSL/divergence con executor finto).
Smoke testnet 4 scenari verdi, conto flat, zero falsi allarmi.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-07 14:59:58 +00:00
parent 7bf8b197e0
commit f5173fba06
9 changed files with 294 additions and 48 deletions
+4 -5
View File
@@ -60,15 +60,14 @@ class BasketTrendWorker:
df = data.get(a)
if df is None or len(df) < 111:
continue
# Scarta la barra 4h IN FORMAZIONE (la riga -1 e' la candela in corso
# finche' non e' trascorsa la sua durata): crossover EMA e booking del
# return valutati SOLO su barre COMPLETE, come il reference
# Scarta la barra 4h IN FORMAZIONE: crossover EMA e booking del return
# valutati SOLO su barre COMPLETE, come il reference
# honest_improve2._tr_basket_daily (lezione EXIT-16; evidenza live: flip
# SOL 0->1->0 in 59min nella stessa finestra 4h, -9.3% di glitch).
from src.live.bars import last_bar_is_forming
ts_arr = df["timestamp"].values.astype("int64")
bar_ms = int(np.median(np.diff(ts_arr[-50:]))) if len(ts_arr) > 1 else 0
c = df["close"].values
if bar_ms and now_ms < int(ts_arr[-1]) + bar_ms:
if last_bar_is_forming(ts_arr, now_ms):
c, ts_arr = c[:-1], ts_arr[:-1]
if len(c) < 110:
continue