import React, { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; import { Progress } from "@/components/ui/progress"; import { CheckCircle, AlertTriangle, Clock, ArrowRight, RefreshCw } from 'lucide-react'; interface TrainingMonitorProps { type: string; schedule: string; loading: boolean; engine: 'AI' | 'Crypto'; } const TrainingMonitor: React.FC = ({ type, schedule, loading, engine }) => { // Simulated training state with auto-progression const [trainingState, setTrainingState] = useState<{ status: 'running' | 'completed' | 'validating' | 'deploying' | 'idle'; progress: number; currentStep: number; lastRun: string; nextRun: string; metrics: Record; alerts: { message: string; type: 'warning' | 'error' | 'success' }[]; }>({ status: 'idle', progress: 0, currentStep: 0, lastRun: '2023-05-08 14:30', nextRun: '2023-05-09 14:30', metrics: engine === 'AI' ? { accuracy: 96.7, precision: 94.3, recall: 95.8, drift: -0.5 } : { sharpeRatio: 1.32, maxDrawdown: 3.8, winRate: 68.5, profitFactor: 1.45 }, alerts: [] }); // Simulate training cycle useEffect(() => { if (loading) return; const startTraining = () => { // Reset training state setTrainingState(prev => ({ ...prev, status: 'running', progress: 0, currentStep: 1, alerts: [] })); // Step 1: Data export (0-25%) const timer1 = setTimeout(() => { setTrainingState(prev => ({ ...prev, progress: 25, currentStep: 2 })); // Step 2: Model Training (25-70%) const timer2 = setTimeout(() => { setTrainingState(prev => ({ ...prev, progress: 70, currentStep: 3 })); // Step 3: Validation (70-85%) const timer3 = setTimeout(() => { setTrainingState(prev => ({ ...prev, status: 'validating', progress: 85, currentStep: 4, alerts: Math.random() > 0.8 ? [...prev.alerts, { message: engine === 'AI' ? 'Accuracy below threshold (94.8%). Rolling back.' : 'Sharpe ratio below threshold (0.95). Rolling back.', type: 'error' }] : prev.alerts })); // Step 4: Deployment (85-100%) const timer4 = setTimeout(() => { const success = Math.random() > 0.2; setTrainingState(prev => ({ ...prev, status: 'completed', progress: 100, currentStep: 0, lastRun: new Date().toLocaleString(), nextRun: new Date(Date.now() + (engine === 'AI' ? 24 : 1) * 60 * 60 * 1000).toLocaleString(), metrics: engine === 'AI' ? { accuracy: success ? 96.7 + (Math.random() * 0.6 - 0.3) : 94.8, precision: success ? 94.3 + (Math.random() * 0.6 - 0.3) : 93.1, recall: success ? 95.8 + (Math.random() * 0.6 - 0.3) : 94.5, drift: success ? -0.5 + (Math.random() * 0.4 - 0.2) : -1.2 } : { sharpeRatio: success ? 1.32 + (Math.random() * 0.2 - 0.1) : 0.95, maxDrawdown: success ? 3.8 + (Math.random() * 0.6 - 0.3) : 5.2, winRate: success ? 68.5 + (Math.random() * 1 - 0.5) : 65.2, profitFactor: success ? 1.45 + (Math.random() * 0.1 - 0.05) : 1.2 }, alerts: success ? prev.alerts : [ ...prev.alerts, { message: success ? 'Model deployed successfully to production endpoint.' : 'Validation failed. Rolled back to previous stable version.', type: success ? 'success' : 'error' } ] })); }, 3000); return () => clearTimeout(timer4); }, 2000); return () => clearTimeout(timer3); }, 4000); return () => clearTimeout(timer2); }, 2000); return () => clearTimeout(timer1); }; // Start initial training simulation const initialTimer = setTimeout(() => { startTraining(); }, 2000); // Set up recurring training simulation const recurringTimer = setInterval(() => { if (trainingState.status === 'idle') { startTraining(); } }, 15000); return () => { clearTimeout(initialTimer); clearInterval(recurringTimer); }; }, [loading, engine]); // Auto reset to idle after completion useEffect(() => { if (trainingState.status === 'completed') { const timer = setTimeout(() => { setTrainingState(prev => ({ ...prev, status: 'idle' })); }, 5000); return () => clearTimeout(timer); } }, [trainingState.status]); const steps = engine === 'AI' ? [ "Export new rows since last run", "Retrain AI model using in-db training", "Validate: ≥95% accuracy & no negative drift", "Deploy to /api/mes/predict endpoint", "Log metrics to monitoring DB" ] : [ "Fetch latest minute-level features", "Retrain RL agent with TD3 algorithm", "Backtest on last 7 days (Sharpe ≥1.0)", "Deploy updated policy to trading service", "Enforce risk constraints (drawdown, position)" ]; return (
{engine === 'AI' ? 'MES Predictor' : 'Crypto Trader'} Training {trainingState.status === 'running' ? 'Training' : trainingState.status === 'validating' ? 'Validating' : trainingState.status === 'completed' ? 'Completed' : 'Idle'}
Schedule: Every {schedule}
{loading ? (
{Array(5).fill(0).map((_, idx) => (
))}
) : ( <>
Training Progress {trainingState.progress}%
Training Pipeline Steps:
{steps.map((step, idx) => (
idx + 1 || (trainingState.status === 'completed' && trainingState.progress === 100) ? 'text-gray-500 dark:text-gray-400' : '' }`} >
{trainingState.currentStep > idx + 1 || (trainingState.status === 'completed' && trainingState.progress === 100) ? ( ) : trainingState.currentStep === idx + 1 ? ( ) : (
)}
{step}
))}
Last run: {trainingState.lastRun}
Next run: {trainingState.nextRun}
)}
Performance Metrics Latest model evaluation results {loading ? (
{Array(4).fill(0).map((_, idx) => (
))}
) : ( <>
{Object.entries(trainingState.metrics).map(([key, value], idx) => (
{key === 'sharpeRatio' ? 'Sharpe Ratio' : key === 'maxDrawdown' ? 'Max Drawdown' : key === 'winRate' ? 'Win Rate' : key === 'profitFactor' ? 'Profit Factor' : key}
{typeof value === 'number' ? key === 'maxDrawdown' ? `${value}%` : key === 'winRate' ? `${value}%` : key === 'drift' ? `${value > 0 ? '+' : ''}${value}%` : key === 'accuracy' || key === 'precision' || key === 'recall' ? `${value}%` : value.toFixed(2) : value} {key === 'accuracy' && value < 95 && ( Below threshold )} {key === 'sharpeRatio' && value < 1.0 && ( Below threshold )}
))}
Threshold Requirements:
{engine === 'AI' ? (
Accuracy ≥ 95%, No negative drift over 1%
) : (
Sharpe Ratio ≥ 1.0, Max drawdown ≤ 5%
)}
)}
{trainingState.alerts.length > 0 && !loading && (
{trainingState.alerts.map((alert, idx) => ( {alert.type === 'error' ? ( ) : alert.type === 'warning' ? ( ) : ( )} {alert.message} ))}
)}
); }; export default TrainingMonitor;