training WIP
This commit is contained in:
@@ -85,15 +85,15 @@
|
||||
<div id="inference-buttons-container">
|
||||
<button class="btn btn-success btn-sm w-100" id="start-inference-btn">
|
||||
<i class="fas fa-play"></i>
|
||||
Start Live Inference (No Training)
|
||||
Start Paper Trading (No Training)
|
||||
</button>
|
||||
<button class="btn btn-info btn-sm w-100 mt-1" id="start-inference-pivot-btn">
|
||||
<i class="fas fa-chart-line"></i>
|
||||
Live Inference + Pivot Training
|
||||
Paper Trading + Pivot Training
|
||||
</button>
|
||||
<button class="btn btn-primary btn-sm w-100 mt-1" id="start-inference-candle-btn">
|
||||
<i class="fas fa-graduation-cap"></i>
|
||||
Live Inference + Per-Candle Training
|
||||
Paper Trading + Online Learning
|
||||
</button>
|
||||
</div>
|
||||
<button class="btn btn-danger btn-sm w-100 mt-1" id="stop-inference-btn" style="display: none;">
|
||||
@@ -144,6 +144,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Online Learning Metrics -->
|
||||
<div id="online-learning-metrics" style="display: none;">
|
||||
<div class="alert alert-info py-2 px-2 mb-2">
|
||||
<strong class="small">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
Online Learning
|
||||
</strong>
|
||||
<div class="small mt-1">
|
||||
<div>Incremental Steps: <span id="incremental-steps" class="fw-bold text-primary">0</span></div>
|
||||
<div>Current Loss: <span id="online-loss" class="fw-bold text-warning">--</span></div>
|
||||
<div>Current Accuracy: <span id="online-accuracy" class="fw-bold text-success">--</span></div>
|
||||
<div class="mt-1 pt-1 border-top" style="font-size: 0.7rem; color: #666;">
|
||||
<div>Last Training: <span id="last-training-time">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Inference Status -->
|
||||
<div id="inference-status" style="display: none;">
|
||||
<div class="alert alert-success py-2 px-2 mb-2">
|
||||
@@ -152,7 +170,7 @@
|
||||
<div class="spinner-border spinner-border-sm me-2" role="status">
|
||||
<span class="visually-hidden">Running...</span>
|
||||
</div>
|
||||
<strong class="small">🔴 LIVE</strong>
|
||||
<strong class="small">LIVE</strong>
|
||||
</div>
|
||||
<!-- Model Performance -->
|
||||
<div class="small text-end">
|
||||
@@ -161,8 +179,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Position & PnL Status -->
|
||||
<div class="mb-2 p-2" style="background-color: rgba(0,0,0,0.1); border-radius: 4px;">
|
||||
<!-- Trading Status Warning -->
|
||||
<div class="mb-2 p-2" style="background-color: rgba(255, 193, 7, 0.2); border: 1px solid rgba(255, 193, 7, 0.5); border-radius: 4px;" id="trading-inactive-warning">
|
||||
<div class="small text-center">
|
||||
<i class="fas fa-exclamation-triangle text-warning"></i>
|
||||
<strong>PREDICTIONS ONLY</strong>
|
||||
<div style="font-size: 0.7rem; color: #666; margin-top: 4px;">
|
||||
No trading session active.<br>
|
||||
Click a button above to start paper trading.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Position & PnL Status (shown when trading active) -->
|
||||
<div class="mb-2 p-2" style="background-color: rgba(0,0,0,0.1); border-radius: 4px; display: none;" id="trading-active-status">
|
||||
<!-- DEMO MODE Badge -->
|
||||
<div class="text-center mb-2 pb-2 border-bottom" style="border-color: rgba(255,255,255,0.2) !important;">
|
||||
<span class="badge bg-info" style="font-size: 0.65rem; letter-spacing: 0.5px;">
|
||||
📊 PAPER TRADING (DEMO)
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="small">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>Position:</span>
|
||||
@@ -742,6 +779,10 @@
|
||||
document.getElementById('inference-status').style.display = 'block';
|
||||
document.getElementById('inference-controls').style.display = 'block';
|
||||
|
||||
// Show trading active status, hide warning
|
||||
document.getElementById('trading-inactive-warning').style.display = 'none';
|
||||
document.getElementById('trading-active-status').style.display = 'block';
|
||||
|
||||
// Show manual training button if in manual mode
|
||||
if (trainingMode === 'manual') {
|
||||
document.getElementById('manual-train-btn').style.display = 'block';
|
||||
@@ -770,6 +811,13 @@
|
||||
|
||||
// Start polling for signals
|
||||
startSignalPolling();
|
||||
startTrainingMetricsPolling(); // Start training metrics polling
|
||||
|
||||
// Show online learning metrics panel
|
||||
const onlineMetricsPanel = document.getElementById('online-learning-metrics');
|
||||
if (onlineMetricsPanel) {
|
||||
onlineMetricsPanel.style.display = 'block';
|
||||
}
|
||||
|
||||
// Start chart auto-update
|
||||
if (window.appState && window.appState.chartManager) {
|
||||
@@ -822,6 +870,10 @@
|
||||
document.getElementById('manual-train-btn').style.display = 'none';
|
||||
document.getElementById('inference-status').style.display = 'none';
|
||||
document.getElementById('inference-controls').style.display = 'none';
|
||||
|
||||
// Show warning, hide trading status
|
||||
document.getElementById('trading-inactive-warning').style.display = 'block';
|
||||
document.getElementById('trading-active-status').style.display = 'none';
|
||||
|
||||
// Hide live mode banner
|
||||
const banner = document.getElementById('live-mode-banner');
|
||||
@@ -831,6 +883,13 @@
|
||||
|
||||
// Stop polling
|
||||
stopSignalPolling();
|
||||
stopTrainingMetricsPolling(); // Stop training metrics polling
|
||||
|
||||
// Hide online learning metrics panel
|
||||
const onlineMetricsPanel = document.getElementById('online-learning-metrics');
|
||||
if (onlineMetricsPanel) {
|
||||
onlineMetricsPanel.style.display = 'none';
|
||||
}
|
||||
|
||||
// Stop chart auto-update and remove metrics overlay
|
||||
if (window.appState && window.appState.chartManager) {
|
||||
@@ -1298,6 +1357,99 @@
|
||||
historyDiv.innerHTML = html;
|
||||
}
|
||||
|
||||
// Training metrics polling
|
||||
let trainingMetricsInterval = null;
|
||||
|
||||
function startTrainingMetricsPolling() {
|
||||
if (trainingMetricsInterval) {
|
||||
clearInterval(trainingMetricsInterval);
|
||||
}
|
||||
|
||||
trainingMetricsInterval = setInterval(function () {
|
||||
fetch('/api/training-metrics')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success && data.metrics) {
|
||||
updateTrainingMetricsDisplay(data.metrics);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.debug('[Training Metrics] Polling error:', error);
|
||||
});
|
||||
}, 2000); // Poll every 2 seconds
|
||||
}
|
||||
|
||||
function stopTrainingMetricsPolling() {
|
||||
if (trainingMetricsInterval) {
|
||||
clearInterval(trainingMetricsInterval);
|
||||
trainingMetricsInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTrainingMetricsDisplay(metrics) {
|
||||
// Update live accuracy and loss in inference status banner
|
||||
const liveAccuracyEl = document.getElementById('live-accuracy');
|
||||
const liveLossEl = document.getElementById('live-loss');
|
||||
|
||||
if (liveAccuracyEl && metrics.accuracy !== undefined) {
|
||||
const accuracyPct = (metrics.accuracy * 100).toFixed(1);
|
||||
liveAccuracyEl.textContent = accuracyPct + '%';
|
||||
}
|
||||
|
||||
if (liveLossEl && metrics.loss !== undefined) {
|
||||
const lossVal = metrics.loss ? metrics.loss.toFixed(4) : '--';
|
||||
liveLossEl.textContent = lossVal;
|
||||
}
|
||||
|
||||
// Update metric-accuracy if it exists
|
||||
const metricAccuracyEl = document.getElementById('metric-accuracy');
|
||||
if (metricAccuracyEl && metrics.accuracy !== undefined) {
|
||||
const accuracyPct = (metrics.accuracy * 100).toFixed(1);
|
||||
metricAccuracyEl.textContent = accuracyPct + '%';
|
||||
}
|
||||
|
||||
// Update training status if visible
|
||||
const trainingLossEl = document.getElementById('training-loss');
|
||||
if (trainingLossEl && metrics.loss !== undefined) {
|
||||
trainingLossEl.textContent = metrics.loss.toFixed(4);
|
||||
}
|
||||
|
||||
// Update online learning metrics panel
|
||||
if (metrics.incremental_steps !== undefined && metrics.incremental_steps > 0) {
|
||||
const onlineMetricsPanel = document.getElementById('online-learning-metrics');
|
||||
if (onlineMetricsPanel) {
|
||||
onlineMetricsPanel.style.display = 'block';
|
||||
}
|
||||
|
||||
const incrementalStepsEl = document.getElementById('incremental-steps');
|
||||
if (incrementalStepsEl) {
|
||||
incrementalStepsEl.textContent = metrics.incremental_steps;
|
||||
}
|
||||
|
||||
const onlineLossEl = document.getElementById('online-loss');
|
||||
if (onlineLossEl && metrics.loss !== undefined) {
|
||||
onlineLossEl.textContent = metrics.loss.toFixed(4);
|
||||
}
|
||||
|
||||
const onlineAccuracyEl = document.getElementById('online-accuracy');
|
||||
if (onlineAccuracyEl && metrics.accuracy !== undefined) {
|
||||
const accuracyPct = (metrics.accuracy * 100).toFixed(1);
|
||||
onlineAccuracyEl.textContent = accuracyPct + '%';
|
||||
}
|
||||
|
||||
const lastTrainingTimeEl = document.getElementById('last-training-time');
|
||||
if (lastTrainingTimeEl && metrics.recent_history && metrics.recent_history.length > 0) {
|
||||
const lastStep = metrics.recent_history[metrics.recent_history.length - 1];
|
||||
if (lastStep.timestamp) {
|
||||
const timeStr = new Date(lastStep.timestamp).toLocaleTimeString();
|
||||
lastTrainingTimeEl.textContent = timeStr;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[Online Learning] ${metrics.incremental_steps} incremental training steps completed`);
|
||||
}
|
||||
}
|
||||
|
||||
function startSignalPolling() {
|
||||
signalPollInterval = setInterval(function () {
|
||||
// Poll for signals
|
||||
|
||||
Reference in New Issue
Block a user