Fix: Signal date tracking and indicator real-time updates

Issue 1: Only update lastSignalDate when signal type changes (BUY→SELL or SELL→BUY)
- Modified clearIndicatorCaches() to accept clearSignalState parameter
- When new candle completes: only clear cachedResults/cachedMeta (not signal state)
- When timeframe changes: clear everything including signal tracking
- This preserves signal change history across multiple candles

Issue 2: Indicator lines not updating when new candles arrive
- Added updateIndicatorCandles() function to update existing series
- Instead of removing and recreating series, now uses .setData() to update
- Called when new candle is detected to update indicator lines
- Chart renders correctly with new data after each candle completion

Both issues now resolved:
1. Shows last crossover date only when signal actually changes
2. Indicator lines update in real-time when new candles complete
This commit is contained in:
DiTus
2026-03-01 20:07:12 +01:00
parent 61aaa2d122
commit 0df8547d96
2 changed files with 72 additions and 9 deletions

View File

@ -813,6 +813,61 @@ function renderIndicatorOnPane(indicator, meta, instance, candles, paneIndex, li
});
}
// Update existing indicator series with new data (for real-time updates)
export function updateIndicatorCandles() {
if (!window.dashboard || !window.dashboard.chart) return;
const activeIndicators = getActiveIndicators();
const currentInterval = window.dashboard.currentInterval;
const candles = window.dashboard?.allData?.get(currentInterval);
if (!candles || candles.length === 0) return;
activeIndicators.forEach(indicator => {
if (!indicator.visible || indicator.series.length === 0) return;
const IndicatorClass = IndicatorRegistry[indicator.type];
if (!IndicatorClass) return;
const instance = new IndicatorClass(indicator);
const results = instance.calculate(candles);
if (!results || results.length === 0) return;
const meta = instance.getMetadata();
// Update each plot series
meta.plots.forEach((plot, plotIdx) => {
const series = indicator.series[plotIdx];
if (!series) return;
const plotColor = indicator.params[`_color_${plotIdx}`] || plot.color || '#2962ff';
const lineWidth = indicator.params._lineWidth || 2;
// Build complete data array
const data = [];
for (let i = 0; i < candles.length; i++) {
const value = results[i]?.[plot.id];
if (value !== null && value !== undefined) {
data.push({
time: candles[i].time,
value: value,
color: plotColor,
lineWidth: lineWidth
});
}
}
if (data.length > 0) {
series.setData(data);
}
});
});
console.log(`[UpdateIndicators] Updated ${activeIndicators.length} indicator series`);
}
// Chart drawing
export function drawIndicatorsOnChart() {
if (!window.dashboard || !window.dashboard.chart) {