T predictions WIP
This commit is contained in:
@@ -281,7 +281,14 @@
|
||||
.catch(error => {
|
||||
console.error('❌ Error loading models:', error);
|
||||
const modelSelect = document.getElementById('model-select');
|
||||
modelSelect.innerHTML = '<option value="">Error loading models</option>';
|
||||
modelSelect.innerHTML = '<option value="">Error loading models (Click to retry)</option>';
|
||||
|
||||
// Allow retry by clicking
|
||||
modelSelect.addEventListener('click', function() {
|
||||
if (modelSelect.value === "") {
|
||||
loadAvailableModels();
|
||||
}
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -834,17 +841,29 @@
|
||||
|
||||
// Display last 5 predictions (most recent first)
|
||||
const html = predictionHistory.slice(0, 5).map(pred => {
|
||||
const time = new Date(pred.timestamp).toLocaleTimeString();
|
||||
// Safely parse timestamp
|
||||
let timeStr = '--:--:--';
|
||||
try {
|
||||
if (pred.timestamp) {
|
||||
const date = new Date(pred.timestamp);
|
||||
if (!isNaN(date.getTime())) {
|
||||
timeStr = date.toLocaleTimeString();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error parsing timestamp:', e);
|
||||
}
|
||||
|
||||
const actionColor = pred.action === 'BUY' ? 'text-success' :
|
||||
pred.action === 'SELL' ? 'text-danger' : 'text-secondary';
|
||||
const confidence = (pred.confidence * 100).toFixed(1);
|
||||
const price = pred.predicted_price ? pred.predicted_price.toFixed(2) : '--';
|
||||
const price = (pred.predicted_price && !isNaN(pred.predicted_price)) ? pred.predicted_price.toFixed(2) : '--';
|
||||
|
||||
return `
|
||||
<div class="d-flex justify-content-between align-items-center mb-1 pb-1 border-bottom">
|
||||
<div>
|
||||
<span class="${actionColor} fw-bold">${pred.action}</span>
|
||||
<span class="text-muted ms-1">${time}</span>
|
||||
<span class="text-muted ms-1">${timeStr}</span>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<div>${confidence}%</div>
|
||||
@@ -864,14 +883,46 @@
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success && data.signals.length > 0) {
|
||||
// Update Accuracy Metrics in Header
|
||||
if (data.metrics) {
|
||||
document.getElementById('metric-accuracy').textContent = (data.metrics.accuracy * 100).toFixed(1) + '%';
|
||||
// If you want to show these in the live banner too:
|
||||
const banner = document.getElementById('inference-status');
|
||||
if (banner) {
|
||||
// Check if we already have a metrics div, if not create one
|
||||
let metricsDiv = document.getElementById('live-banner-metrics');
|
||||
if (!metricsDiv) {
|
||||
metricsDiv = document.createElement('div');
|
||||
metricsDiv.id = 'live-banner-metrics';
|
||||
metricsDiv.className = 'mt-1 pt-1 border-top small text-muted d-flex justify-content-between';
|
||||
banner.querySelector('.small').appendChild(metricsDiv);
|
||||
}
|
||||
metricsDiv.innerHTML = `
|
||||
<span>Acc: ${(data.metrics.accuracy * 100).toFixed(1)}%</span>
|
||||
<span>Loss: ${data.metrics.loss ? data.metrics.loss.toFixed(4) : '--'}</span>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
const latest = data.signals[0];
|
||||
document.getElementById('latest-signal').textContent = latest.action;
|
||||
document.getElementById('latest-confidence').textContent =
|
||||
(latest.confidence * 100).toFixed(1) + '%';
|
||||
|
||||
// Handle prediction price and timestamp safely
|
||||
const predPrice = (latest.predicted_price && !isNaN(latest.predicted_price))
|
||||
? latest.predicted_price.toFixed(2)
|
||||
: '--';
|
||||
|
||||
// Format timestamp carefully
|
||||
let timestamp = new Date().toISOString();
|
||||
if (latest.timestamp) {
|
||||
timestamp = latest.timestamp;
|
||||
}
|
||||
|
||||
// Add to prediction history (keep last 5)
|
||||
predictionHistory.unshift({
|
||||
timestamp: latest.timestamp || new Date().toISOString(),
|
||||
timestamp: timestamp,
|
||||
action: latest.action,
|
||||
confidence: latest.confidence,
|
||||
predicted_price: latest.predicted_price
|
||||
@@ -882,21 +933,20 @@
|
||||
updatePredictionHistory();
|
||||
|
||||
// Update chart with signal markers
|
||||
if (appState.chartManager) {
|
||||
if (window.appState && window.appState.chartManager) {
|
||||
displaySignalOnChart(latest);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error polling signals:', error);
|
||||
});
|
||||
console.error('Error polling signals:', error);
|
||||
});
|
||||
}, 1000); // Poll every second
|
||||
}
|
||||
|
||||
// Update charts with latest data
|
||||
updateChartsWithLiveData();
|
||||
}, 1000); // Poll every second
|
||||
}
|
||||
// REMOVED: updateChartsWithLiveData() - Full chart refresh is deprecated in favor of incremental updates
|
||||
|
||||
function updateChartsWithLiveData() {
|
||||
/* DEPRECATED: Old update logic
|
||||
// Fetch latest chart data
|
||||
fetch('/api/chart-data', {
|
||||
method: 'POST',
|
||||
@@ -924,8 +974,7 @@
|
||||
console.error('Error updating charts:', error);
|
||||
});
|
||||
}
|
||||
|
||||
let liveUpdateCount = 0;
|
||||
*/
|
||||
|
||||
function updateSingleChart(timeframe, newData) {
|
||||
const chart = appState.chartManager.charts[timeframe];
|
||||
@@ -955,7 +1004,8 @@
|
||||
|
||||
// Update counter
|
||||
liveUpdateCount++;
|
||||
const counterEl = document.getElementById('live-update-count');
|
||||
// Note: The element ID is 'live-updates-count' in the header, not 'live-update-count'
|
||||
const counterEl = document.getElementById('live-updates-count') || document.getElementById('live-update-count');
|
||||
if (counterEl) {
|
||||
counterEl.textContent = liveUpdateCount + ' updates';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user