From c74b411404926b9447aea4fed5af5d933b42df5d Mon Sep 17 00:00:00 2001 From: rufinomec-afk Date: Sun, 7 Jun 2026 23:09:29 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20history=5Fready=20event=20=E2=80=94=20fr?= =?UTF-8?q?ontend=20refetch=20apos=20replay=20completo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/mt5_collector.py | 5 ++++- backend/server.py | 14 +++++++++++++- frontend/src/App.jsx | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/backend/mt5_collector.py b/backend/mt5_collector.py index 4c2a2f9..8f7bcc0 100644 --- a/backend/mt5_collector.py +++ b/backend/mt5_collector.py @@ -15,9 +15,10 @@ logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(me logger = logging.getLogger("mt5_collector") class MT5Collector: - def __init__(self, aggregator: Aggregator, on_update_callback: Callable[[dict, Optional[dict]], Any]): + def __init__(self, aggregator: Aggregator, on_update_callback: Callable[[dict, Optional[dict]], Any], on_history_ready_callback: Callable = None): self.aggregator = aggregator self.on_update_callback = on_update_callback + self.on_history_ready_callback = on_history_ready_callback self.symbol = settings.MT5_SYMBOL self.running = False self.connected = False @@ -177,6 +178,8 @@ class MT5Collector: if not self._history_annotated and len(ticks) < 1000: self._history_annotated = True await self.annotate_history_bar_volume() + if self.on_history_ready_callback: + self.on_history_ready_callback() if len(ticks) > 0: logger.info(f"Fetched {len(ticks)} ticks starting at {ticks[0]['time_msc']}") diff --git a/backend/server.py b/backend/server.py index 40a72fc..9b6a0c4 100644 --- a/backend/server.py +++ b/backend/server.py @@ -44,8 +44,20 @@ def broadcast_update(active_json: dict, closed_json: Optional[dict]): for connection in list(active_connections): asyncio.create_task(safe_send(connection, message)) +def broadcast_history_ready(): + """Notify all clients that historical replay is complete — they should refetch /history.""" + if not active_connections: + return + async def _send(): + for ws in list(active_connections): + try: + await ws.send_json({"type": "history_ready"}) + except Exception: + active_connections.discard(ws) + asyncio.create_task(_send()) + # Initialize MT5 Collector -collector = MT5Collector(aggregator, on_update_callback=broadcast_update) +collector = MT5Collector(aggregator, on_update_callback=broadcast_update, on_history_ready_callback=broadcast_history_ready) async def _start_collector_delayed(): """Wait a moment for the server to fully start, then begin polling MT5.""" diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index d780766..b2a2ee9 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -78,7 +78,9 @@ export default function App() { if (msg.type === 'init') { setActiveCluster(msg.active); - fetchHistory(); // Sync history on connection + fetchHistory(); + } else if (msg.type === 'history_ready') { + fetchHistory(); // Replay completo — busca histórico atualizado } else if (msg.type === 'tick') { setActiveCluster(msg.active); if (msg.active?.bid) setLastBid(msg.active.bid);