From 61aaa2d12241a1afba1757daed1708d7c48d4035 Mon Sep 17 00:00:00 2001 From: DiTus Date: Sun, 1 Mar 2026 19:58:14 +0100 Subject: [PATCH] Add indicator recalculation on timeframe change and new candle Changes: - Added lastCandleTimestamp to track candle completion - Detect new candle when timestamp increases - Clear indicator caches when new candle detected - Clear indicator caches when timeframe changes - Recalculate indicators and signals in both cases - Refresh chart when new candle is detected This ensures indicators are always recalculated with fresh data when: 1. Timeframe is switched 2. A new candle completes Both cases now force: - Cache clearing - Indicator recalculation - Chart refresh - Signal recalculation --- src/api/dashboard/static/js/ui/chart.js | 42 ++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/api/dashboard/static/js/ui/chart.js b/src/api/dashboard/static/js/ui/chart.js index 3e882ae..92c3458 100644 --- a/src/api/dashboard/static/js/ui/chart.js +++ b/src/api/dashboard/static/js/ui/chart.js @@ -23,6 +23,7 @@ constructor() { this.taData = null; this.indicatorSignals = []; this.summarySignal = null; + this.lastCandleTimestamp = null; this.init(); } @@ -294,10 +295,21 @@ constructor() { } else if (e.key === 'ArrowUp') { this.navigateToRecent(); } - }); +}); } -async loadInitialData() { + clearIndicatorCaches() { + const activeIndicators = window.getActiveIndicators?.() || []; + activeIndicators.forEach(indicator => { + indicator.cachedResults = null; + indicator.cachedMeta = null; + indicator.lastSignalTimestamp = null; + indicator.lastSignalType = null; + }); + console.log(`[Dashboard] Cleared caches for ${activeIndicators.length} indicators`); + } + + async loadInitialData() { await Promise.all([ this.loadData(2000, true), this.loadStats() @@ -377,6 +389,19 @@ async loadNewData() { volume: parseFloat(c.volume || 0) })); + const latest = chartData[chartData.length - 1]; + + // Check if new candle detected + const isNewCandle = this.lastCandleTimestamp !== null && latest.time > this.lastCandleTimestamp; + + if (isNewCandle) { + console.log(`[NewData Load] New candle detected: ${this.lastCandleTimestamp} -> ${latest.time}`); + // Clear indicator caches to force recalculation + this.clearIndicatorCaches(); + } + + this.lastCandleTimestamp = latest.time; + chartData.forEach(candle => { if (candle.time >= lastTimestamp) { this.candleSeries.update(candle); @@ -392,7 +417,6 @@ async loadNewData() { this.chart.timeScale().scrollToRealTime(); } - const latest = chartData[chartData.length - 1]; this.updateStats(latest); // Recalculate indicators and signals when new data loads @@ -400,6 +424,11 @@ async loadNewData() { window.drawIndicatorsOnChart(); } await this.loadSignals(); + + // Refresh chart if new candle detected + if (isNewCandle) { + this.chart.timeScale().scrollToRealTime(); + } } } catch (error) { console.error('Error loading new data:', error); @@ -675,7 +704,7 @@ const signalsHtml = this.indicatorSignals?.length > 0 ? this.indicatorSignals.ma } } - switchTimeframe(interval) { +switchTimeframe(interval) { if (!this.intervals.includes(interval) || interval === this.currentInterval) return; const oldInterval = this.currentInterval; @@ -686,8 +715,13 @@ const signalsHtml = this.indicatorSignals?.length > 0 ? this.indicatorSignals.ma btn.classList.toggle('active', btn.dataset.interval === interval); }); + // Clear indicator caches before switching timeframe + this.clearIndicatorCaches(); + // Clear old interval data, not new interval this.allData.delete(oldInterval); + this.lastCandleTimestamp = null; + this.loadInitialData(); window.clearSimulationResults?.();