UI
This commit is contained in:
@@ -622,7 +622,27 @@ class ChartManager {
|
|||||||
|
|
||||||
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
|
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
|
||||||
const xMin = data.timestamps[0];
|
const xMin = data.timestamps[0];
|
||||||
const xMax = data.timestamps[data.timestamps.length - 1];
|
let xMax = data.timestamps[data.timestamps.length - 1];
|
||||||
|
|
||||||
|
// Extend xMax to include ghost candle predictions if they exist
|
||||||
|
if (this.ghostCandleHistory && this.ghostCandleHistory[timeframe] && this.ghostCandleHistory[timeframe].length > 0) {
|
||||||
|
const ghosts = this.ghostCandleHistory[timeframe];
|
||||||
|
const furthestGhost = ghosts[ghosts.length - 1];
|
||||||
|
if (furthestGhost && furthestGhost.targetTime) {
|
||||||
|
const ghostTime = new Date(furthestGhost.targetTime);
|
||||||
|
const currentMax = new Date(xMax);
|
||||||
|
if (ghostTime > currentMax) {
|
||||||
|
const year = ghostTime.getUTCFullYear();
|
||||||
|
const month = String(ghostTime.getUTCMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(ghostTime.getUTCDate()).padStart(2, '0');
|
||||||
|
const hours = String(ghostTime.getUTCHours()).padStart(2, '0');
|
||||||
|
const minutes = String(ghostTime.getUTCMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(ghostTime.getUTCSeconds()).padStart(2, '0');
|
||||||
|
xMax = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
console.log(`[${timeframe}] Pivot lines extended to include ${ghosts.length} ghost candles (to ${xMax})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process each timestamp that has pivot markers
|
// Process each timestamp that has pivot markers
|
||||||
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
|
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
|
||||||
@@ -1041,7 +1061,26 @@ class ChartManager {
|
|||||||
|
|
||||||
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
|
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
|
||||||
const xMin = data.timestamps[0];
|
const xMin = data.timestamps[0];
|
||||||
const xMax = data.timestamps[data.timestamps.length - 1];
|
let xMax = data.timestamps[data.timestamps.length - 1];
|
||||||
|
|
||||||
|
// Extend xMax to include ghost candle predictions if they exist
|
||||||
|
if (this.ghostCandleHistory && this.ghostCandleHistory[timeframe] && this.ghostCandleHistory[timeframe].length > 0) {
|
||||||
|
const ghosts = this.ghostCandleHistory[timeframe];
|
||||||
|
const furthestGhost = ghosts[ghosts.length - 1];
|
||||||
|
if (furthestGhost && furthestGhost.targetTime) {
|
||||||
|
const ghostTime = new Date(furthestGhost.targetTime);
|
||||||
|
const currentMax = new Date(xMax);
|
||||||
|
if (ghostTime > currentMax) {
|
||||||
|
const year = ghostTime.getUTCFullYear();
|
||||||
|
const month = String(ghostTime.getUTCMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(ghostTime.getUTCDate()).padStart(2, '0');
|
||||||
|
const hours = String(ghostTime.getUTCHours()).padStart(2, '0');
|
||||||
|
const minutes = String(ghostTime.getUTCMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(ghostTime.getUTCSeconds()).padStart(2, '0');
|
||||||
|
xMax = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process each timestamp that has pivot markers
|
// Process each timestamp that has pivot markers
|
||||||
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
|
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
|
||||||
@@ -1977,7 +2016,27 @@ class ChartManager {
|
|||||||
|
|
||||||
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
|
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
|
||||||
const xMin = data.timestamps[0];
|
const xMin = data.timestamps[0];
|
||||||
const xMax = data.timestamps[data.timestamps.length - 1];
|
let xMax = data.timestamps[data.timestamps.length - 1];
|
||||||
|
|
||||||
|
// Extend xMax to include ghost candle predictions if they exist
|
||||||
|
if (this.ghostCandleHistory && this.ghostCandleHistory[timeframe] && this.ghostCandleHistory[timeframe].length > 0) {
|
||||||
|
const ghosts = this.ghostCandleHistory[timeframe];
|
||||||
|
const furthestGhost = ghosts[ghosts.length - 1];
|
||||||
|
if (furthestGhost && furthestGhost.targetTime) {
|
||||||
|
const ghostTime = new Date(furthestGhost.targetTime);
|
||||||
|
const currentMax = new Date(xMax);
|
||||||
|
if (ghostTime > currentMax) {
|
||||||
|
const year = ghostTime.getUTCFullYear();
|
||||||
|
const month = String(ghostTime.getUTCMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(ghostTime.getUTCDate()).padStart(2, '0');
|
||||||
|
const hours = String(ghostTime.getUTCHours()).padStart(2, '0');
|
||||||
|
const minutes = String(ghostTime.getUTCMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(ghostTime.getUTCSeconds()).padStart(2, '0');
|
||||||
|
xMax = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
console.log(`[${timeframe}] Pivot lines extended to include ${ghosts.length} ghost candles (to ${xMax})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process each timestamp that has pivot markers
|
// Process each timestamp that has pivot markers
|
||||||
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
|
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
|
||||||
|
|||||||
@@ -1124,6 +1124,16 @@
|
|||||||
|
|
||||||
function updatePredictionHistory() {
|
function updatePredictionHistory() {
|
||||||
const historyDiv = document.getElementById('prediction-history');
|
const historyDiv = document.getElementById('prediction-history');
|
||||||
|
|
||||||
|
// Filter out invalid predictions (cleanup any that got through)
|
||||||
|
predictionHistory = predictionHistory.filter(pred => {
|
||||||
|
return pred.action &&
|
||||||
|
['BUY', 'SELL', 'HOLD'].includes(pred.action) &&
|
||||||
|
!isNaN(pred.confidence) &&
|
||||||
|
pred.confidence > 0 &&
|
||||||
|
pred.timestamp;
|
||||||
|
});
|
||||||
|
|
||||||
if (predictionHistory.length === 0) {
|
if (predictionHistory.length === 0) {
|
||||||
historyDiv.innerHTML = '<div class="text-muted">No predictions yet...</div>';
|
historyDiv.innerHTML = '<div class="text-muted">No predictions yet...</div>';
|
||||||
return;
|
return;
|
||||||
@@ -1148,7 +1158,7 @@
|
|||||||
pred.action === 'SELL' ? 'text-danger' : 'text-secondary';
|
pred.action === 'SELL' ? 'text-danger' : 'text-secondary';
|
||||||
const confidence = (pred.confidence * 100).toFixed(1);
|
const confidence = (pred.confidence * 100).toFixed(1);
|
||||||
const price = (pred.predicted_price && !isNaN(pred.predicted_price)) ? pred.predicted_price.toFixed(2) : '--';
|
const price = (pred.predicted_price && !isNaN(pred.predicted_price)) ? pred.predicted_price.toFixed(2) : '--';
|
||||||
const timeframe = pred.timeframe || '1m';
|
const timeframe = pred.timeframe || '1s';
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="d-flex justify-content-between align-items-center mb-1 pb-1 border-bottom">
|
<div class="d-flex justify-content-between align-items-center mb-1 pb-1 border-bottom">
|
||||||
@@ -1177,11 +1187,15 @@
|
|||||||
if (data.success && data.signals.length > 0) {
|
if (data.success && data.signals.length > 0) {
|
||||||
// Update Accuracy Metrics in Header
|
// Update Accuracy Metrics in Header
|
||||||
if (data.metrics) {
|
if (data.metrics) {
|
||||||
document.getElementById('metric-accuracy').textContent = (data.metrics.accuracy * 100).toFixed(1) + '%';
|
console.log('[Metrics Update]', data.metrics);
|
||||||
// If you want to show these in the live banner too:
|
const accuracyPct = (data.metrics.accuracy * 100).toFixed(1);
|
||||||
|
const lossVal = data.metrics.loss ? data.metrics.loss.toFixed(4) : '--';
|
||||||
|
|
||||||
|
document.getElementById('metric-accuracy').textContent = accuracyPct + '%';
|
||||||
|
|
||||||
|
// Update live banner with metrics
|
||||||
const banner = document.getElementById('inference-status');
|
const banner = document.getElementById('inference-status');
|
||||||
if (banner) {
|
if (banner) {
|
||||||
// Check if we already have a metrics div, if not create one
|
|
||||||
let metricsDiv = document.getElementById('live-banner-metrics');
|
let metricsDiv = document.getElementById('live-banner-metrics');
|
||||||
if (!metricsDiv) {
|
if (!metricsDiv) {
|
||||||
metricsDiv = document.createElement('div');
|
metricsDiv = document.createElement('div');
|
||||||
@@ -1190,8 +1204,9 @@
|
|||||||
banner.querySelector('.small').appendChild(metricsDiv);
|
banner.querySelector('.small').appendChild(metricsDiv);
|
||||||
}
|
}
|
||||||
metricsDiv.innerHTML = `
|
metricsDiv.innerHTML = `
|
||||||
<span>Acc: ${(data.metrics.accuracy * 100).toFixed(1)}%</span>
|
<span>Acc: ${accuracyPct}%</span>
|
||||||
<span>Loss: ${data.metrics.loss ? data.metrics.loss.toFixed(4) : '--'}</span>
|
<span>Loss: ${lossVal}</span>
|
||||||
|
<span>PnL: +$${pnlTracker.totalPnL.toFixed(2)}</span>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1219,16 +1234,7 @@
|
|||||||
const currentPrice = latest.price || latest.current_price;
|
const currentPrice = latest.price || latest.current_price;
|
||||||
|
|
||||||
// Add to prediction history (keep last 15)
|
// Add to prediction history (keep last 15)
|
||||||
const newPrediction = {
|
// Only create prediction if we have valid data
|
||||||
timestamp: timestamp,
|
|
||||||
action: latest.action,
|
|
||||||
confidence: latest.confidence,
|
|
||||||
predicted_price: latest.predicted_price,
|
|
||||||
current_price: currentPrice,
|
|
||||||
timeframe: appState.currentTimeframes ? appState.currentTimeframes[0] : '1m'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Strengthen filter: only add valid signals
|
|
||||||
const validActions = ['BUY', 'SELL', 'HOLD'];
|
const validActions = ['BUY', 'SELL', 'HOLD'];
|
||||||
if (latest.action &&
|
if (latest.action &&
|
||||||
validActions.includes(latest.action) &&
|
validActions.includes(latest.action) &&
|
||||||
@@ -1237,9 +1243,19 @@
|
|||||||
currentPrice &&
|
currentPrice &&
|
||||||
!isNaN(currentPrice)) {
|
!isNaN(currentPrice)) {
|
||||||
|
|
||||||
|
const newPrediction = {
|
||||||
|
timestamp: timestamp,
|
||||||
|
action: latest.action,
|
||||||
|
confidence: latest.confidence,
|
||||||
|
predicted_price: latest.predicted_price,
|
||||||
|
current_price: currentPrice,
|
||||||
|
timeframe: appState.currentTimeframes ? appState.currentTimeframes[0] : '1s'
|
||||||
|
};
|
||||||
|
|
||||||
// Update PnL tracking
|
// Update PnL tracking
|
||||||
updatePnLTracking(latest.action, currentPrice, timestamp);
|
updatePnLTracking(latest.action, currentPrice, timestamp);
|
||||||
|
|
||||||
|
// Add to history
|
||||||
predictionHistory.unshift(newPrediction);
|
predictionHistory.unshift(newPrediction);
|
||||||
if (predictionHistory.length > 15) {
|
if (predictionHistory.length > 15) {
|
||||||
predictionHistory = predictionHistory.slice(0, 15);
|
predictionHistory = predictionHistory.slice(0, 15);
|
||||||
|
|||||||
Reference in New Issue
Block a user