ghost T predictions plotting on chart live chart updates

This commit is contained in:
Dobromir Popov
2025-11-22 01:14:32 +02:00
parent f967f0a142
commit d349a1bac0
4 changed files with 272 additions and 30 deletions

View File

@@ -27,14 +27,14 @@ class ChartManager {
this.autoUpdateEnabled = true;
console.log('Starting chart auto-update...');
// Update 1s chart every 20 seconds
// Update 1s chart every 2 seconds (was 20s)
if (this.timeframes.includes('1s')) {
this.updateTimers['1s'] = setInterval(() => {
this.updateChart('1s');
}, 20000); // 20 seconds
}, 2000); // 2 seconds
}
// Update 1m chart - sync to whole minutes + every 20s
// Update 1m chart - sync to whole minutes + every 5s (was 20s)
if (this.timeframes.includes('1m')) {
// Calculate ms until next whole minute
const now = new Date();
@@ -44,10 +44,10 @@ class ChartManager {
setTimeout(() => {
this.updateChart('1m');
// Then update every 20s
// Then update every 5s
this.updateTimers['1m'] = setInterval(() => {
this.updateChart('1m');
}, 20000); // 20 seconds
}, 5000); // 5 seconds
}, msUntilNextMinute);
}
@@ -1758,6 +1758,7 @@ class ChartManager {
// Prepare prediction markers
const predictionShapes = [];
const predictionAnnotations = [];
const predictionTraces = []; // New traces for ghost candles
// Add DQN predictions (arrows)
if (predictions.dqn) {
@@ -1769,9 +1770,18 @@ class ChartManager {
this._addCNNPrediction(predictions.cnn, predictionShapes, predictionAnnotations);
}
// Add Transformer predictions (star markers with trend lines)
// Add Transformer predictions (star markers with trend lines + ghost candles)
if (predictions.transformer) {
this._addTransformerPrediction(predictions.transformer, predictionShapes, predictionAnnotations);
// Add ghost candle if available
if (predictions.transformer.predicted_candle) {
// Check if we have prediction for this timeframe
const candleData = predictions.transformer.predicted_candle[timeframe];
if (candleData) {
this._addGhostCandlePrediction(candleData, timeframe, predictionTraces);
}
}
}
// Update chart layout with predictions
@@ -1782,11 +1792,85 @@ class ChartManager {
});
}
// Add prediction traces (ghost candles)
if (predictionTraces.length > 0) {
// Remove existing ghost traces first (heuristic: traces with name 'Ghost Prediction')
const currentTraces = plotElement.data.length;
const indicesToRemove = [];
for (let i = 0; i < currentTraces; i++) {
if (plotElement.data[i].name === 'Ghost Prediction') {
indicesToRemove.push(i);
}
}
if (indicesToRemove.length > 0) {
Plotly.deleteTraces(plotId, indicesToRemove);
}
// Add new traces
Plotly.addTraces(plotId, predictionTraces);
}
} catch (error) {
console.debug('Error updating predictions:', error);
}
}
_addGhostCandlePrediction(candleData, timeframe, traces) {
// candleData is [Open, High, Low, Close, Volume]
// We need to determine the timestamp for this ghost candle
// It should be the NEXT candle after the last one on chart
const chart = this.charts[timeframe];
if (!chart || !chart.data) return;
const lastTimestamp = new Date(chart.data.timestamps[chart.data.timestamps.length - 1]);
let nextTimestamp;
// Calculate next timestamp based on timeframe
if (timeframe === '1s') {
nextTimestamp = new Date(lastTimestamp.getTime() + 1000);
} else if (timeframe === '1m') {
nextTimestamp = new Date(lastTimestamp.getTime() + 60000);
} else if (timeframe === '1h') {
nextTimestamp = new Date(lastTimestamp.getTime() + 3600000);
} else {
nextTimestamp = new Date(lastTimestamp.getTime() + 60000); // Default 1m
}
const open = candleData[0];
const high = candleData[1];
const low = candleData[2];
const close = candleData[3];
// Determine color
const color = close >= open ? '#10b981' : '#ef4444';
// Create ghost candle trace
const ghostTrace = {
x: [nextTimestamp],
open: [open],
high: [high],
low: [low],
close: [close],
type: 'candlestick',
name: 'Ghost Prediction',
increasing: {
line: { color: color, width: 1 },
fillcolor: color
},
decreasing: {
line: { color: color, width: 1 },
fillcolor: color
},
opacity: 0.3, // 30% transparent
hoverinfo: 'x+y+text',
text: ['Predicted Next Candle']
};
traces.push(ghostTrace);
console.log('Added ghost candle prediction:', ghostTrace);
}
_addDQNPrediction(prediction, shapes, annotations) {
const timestamp = new Date(prediction.timestamp || Date.now());
const price = prediction.current_price || 0;

View File

@@ -576,6 +576,11 @@
// Start polling for signals
startSignalPolling();
// Start chart auto-update
if (window.appState && window.appState.chartManager) {
window.appState.chartManager.startAutoUpdate();
}
const trainingMode = data.training_mode || 'inference-only';
const modeText = trainingMode === 'per-candle' ? ' with per-candle training' :
(trainingMode === 'pivot-based' ? ' with pivot training' : '');
@@ -630,6 +635,11 @@
// Stop polling
stopSignalPolling();
// Stop chart auto-update
if (window.appState && window.appState.chartManager) {
window.appState.chartManager.stopAutoUpdate();
}
currentInferenceId = null;
showSuccess('Real-time inference stopped');
@@ -932,9 +942,16 @@
}
updatePredictionHistory();
// Update chart with signal markers
// Update chart with signal markers and predictions
if (window.appState && window.appState.chartManager) {
displaySignalOnChart(latest);
// Update ghost candles and other predictions
const predictions = {};
const modelKey = latest.model ? latest.model.toLowerCase() : 'transformer';
predictions[modelKey] = latest;
window.appState.chartManager.updatePredictions(predictions);
}
}
})