This commit is contained in:
Dobromir Popov
2025-11-23 02:16:34 +02:00
parent 24aeefda9d
commit 53ce4a355a
8 changed files with 1088 additions and 155 deletions

View File

@@ -100,6 +100,10 @@
<i class="fas fa-stop"></i>
Stop Inference
</button>
<button class="btn btn-warning btn-sm w-100 mt-1" id="manual-train-btn" style="display: none;">
<i class="fas fa-hand-pointer"></i>
Train on Current Candle (Manual)
</button>
</div>
<!-- Backtest on Visible Chart -->
@@ -628,7 +632,7 @@
});
// Helper function to start inference with different modes
function startInference(enableLiveTraining, trainEveryCandle) {
function startInference(trainingMode) {
const modelName = document.getElementById('model-select').value;
if (!modelName) {
@@ -639,7 +643,7 @@
// Get timeframe
const timeframe = document.getElementById('primary-timeframe-select').value;
// Start real-time inference
// Start real-time inference with unified training_mode parameter
fetch('/api/realtime-inference/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -647,8 +651,7 @@
model_name: modelName,
symbol: appState.currentSymbol,
timeframe: timeframe,
enable_live_training: enableLiveTraining,
train_every_candle: trainEveryCandle
training_mode: trainingMode // 'none', 'every_candle', 'pivots_only', 'manual'
})
})
.then(response => response.json())
@@ -664,6 +667,11 @@
document.getElementById('inference-status').style.display = 'block';
document.getElementById('inference-controls').style.display = 'block';
// Show manual training button if in manual mode
if (trainingMode === 'manual') {
document.getElementById('manual-train-btn').style.display = 'block';
}
// Display active timeframe
document.getElementById('active-timeframe').textContent = timeframe.toUpperCase();
@@ -708,15 +716,15 @@
// Button handlers for different inference modes
document.getElementById('start-inference-btn').addEventListener('click', function () {
startInference(false, false); // No training
startInference('none'); // No training (inference only)
});
document.getElementById('start-inference-pivot-btn').addEventListener('click', function () {
startInference(true, false); // Pivot-based training
startInference('pivots_only'); // Pivot-based training
});
document.getElementById('start-inference-candle-btn').addEventListener('click', function () {
startInference(false, true); // Per-candle training
startInference('every_candle'); // Per-candle training
});
document.getElementById('stop-inference-btn').addEventListener('click', function () {
@@ -736,6 +744,7 @@
document.getElementById('start-inference-pivot-btn').style.display = 'block';
document.getElementById('start-inference-candle-btn').style.display = 'block';
document.getElementById('stop-inference-btn').style.display = 'none';
document.getElementById('manual-train-btn').style.display = 'none';
document.getElementById('inference-status').style.display = 'none';
document.getElementById('inference-controls').style.display = 'none';
@@ -762,6 +771,42 @@
showError('Network error: ' + error.message);
});
});
// Manual training button handler
document.getElementById('manual-train-btn').addEventListener('click', function () {
if (!currentInferenceId) {
showError('No active inference session');
return;
}
// Get user's action choice (could add a dropdown, for now use BUY as example)
const action = prompt('Enter action (BUY, SELL, or HOLD):', 'BUY');
if (!action || !['BUY', 'SELL', 'HOLD'].includes(action.toUpperCase())) {
showError('Invalid action. Must be BUY, SELL, or HOLD');
return;
}
// Trigger manual training
fetch('/api/realtime-inference/train-manual', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
inference_id: currentInferenceId,
action: action.toUpperCase()
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccess(`Manual training completed: ${data.action} (${data.metrics ? 'Loss: ' + data.metrics.loss.toFixed(4) : ''})`);
} else {
showError('Manual training failed: ' + (data.error || 'Unknown error'));
}
})
.catch(error => {
showError('Network error: ' + error.message);
});
});
// Backtest controls
let currentBacktestId = null;