fix(live): ROT02/TSM01 scartano la barra 1d in formazione (forming-bar in _panel)

Code-review follow-up: i worker daily valutavano momentum/regime e bookavano il
return sulla candela 1d PARZIALE al primo poll dopo mezzanotte UTC, poi last_bar_ts
bloccava la rivalutazione a giorno chiuso (stessa classe del bug gia' fixato su
fade/TR01/Pairs). Fix in _panel (un punto solo -> ROT02 e TSM01 lo ereditano) via
src.live.bars.last_bar_is_forming. Replay honest invariato (dati storici: nessuna
barra in formazione). Test: 88/88 + parity drop forming daily bar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-08 10:00:16 +00:00
parent 7f4378190e
commit f509f51543
2 changed files with 26 additions and 1 deletions
+10 -1
View File
@@ -13,7 +13,14 @@ FEE_RT = 0.001
def _panel(data: dict, universe: list):
"""Allinea {asset: df} sui timestamp comuni -> (df_panel, cols presenti)."""
"""Allinea {asset: df} sui timestamp comuni -> (df_panel, cols presenti).
Scarta la barra IN FORMAZIONE (riga -1 = candela in corso finche' non e'
trascorsa la sua durata): ROT02/TSM01 valutavano momentum/regime e bookavano
il return sulla barra 1d parziale al primo poll dopo mezzanotte UTC, poi
last_bar_ts bloccava la rivalutazione a giorno chiuso. Stessa lezione EXIT-16
gia' applicata a fade/TR01/Pairs (detection condivisa src.live.bars)."""
from src.live.bars import last_bar_is_forming
frames = {}
for a in universe:
df = data.get(a)
@@ -25,6 +32,8 @@ def _panel(data: dict, universe: list):
for a, f in frames.items():
panel = f if panel is None else panel.merge(f, on="timestamp", how="inner")
panel = panel.sort_values("timestamp").reset_index(drop=True)
if len(panel) and last_bar_is_forming(panel["timestamp"].values):
panel = panel.iloc[:-1].reset_index(drop=True)
cols = [a for a in universe if a in frames]
return panel, cols