'use client' import { useEffect, useState } from 'react' interface ClusterStatus { cluster: { totalCores: number activeCores: number cpuUsage: number activeWorkers: number totalWorkers: number workerProcesses: number status: string } workers: Array<{ name: string host: string cpuUsage: number loadAverage: string activeProcesses: number status: string }> exploration: { totalCombinations: number testedCombinations: number progress: number chunks: { total: number completed: number running: number pending: number } } topStrategies: Array<{ rank: number pnl_per_1k: number win_rate: number trades: number profit_factor: number max_drawdown: number params: { flip_threshold: number ma_gap: number adx_min: number long_pos_max: number short_pos_min: number } }> recommendation: string lastUpdate: string } export default function ClusterPage() { const [status, setStatus] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [controlLoading, setControlLoading] = useState(false) const [controlMessage, setControlMessage] = useState(null) const [coordinatorLog, setCoordinatorLog] = useState('') const [logLoading, setLogLoading] = useState(false) const fetchStatus = async () => { try { const res = await fetch('/api/cluster/status') if (!res.ok) throw new Error('Failed to fetch') const data = await res.json() setStatus(data) setError(null) } catch (err: any) { setError(err.message) } finally { setLoading(false) } } const fetchLog = async () => { try { setLogLoading(true) const response = await fetch('/api/cluster/logs') const data = await response.json() if (data.success) { setCoordinatorLog(data.log) } } catch (error) { console.error('Failed to fetch coordinator log:', error) } finally { setLogLoading(false) } } const handleControl = async (action: 'start' | 'stop') => { setControlLoading(true) setControlMessage(null) try { const res = await fetch('/api/cluster/control', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action }) }) const data = await res.json() setControlMessage(data.message || (data.success ? `Cluster ${action}ed` : 'Operation failed')) // Refresh status after control action setTimeout(() => fetchStatus(), 2000) } catch (err: any) { setControlMessage(`Error: ${err.message}`) } finally { setControlLoading(false) } } useEffect(() => { fetchStatus() fetchLog() const statusInterval = setInterval(fetchStatus, 30000) // Refresh status every 30s const logInterval = setInterval(fetchLog, 3000) // Refresh log every 3s return () => { clearInterval(statusInterval) clearInterval(logInterval) } }, []) if (loading) { return (

πŸ–₯️ EPYC Cluster Status

Loading cluster status...
) } if (error) { return (

πŸ–₯️ EPYC Cluster Status

Error: {error}

) } if (!status) return null const getStatusColor = (statusStr: string) => { if (statusStr === 'active') return 'text-green-400' if (statusStr === 'idle') return 'text-yellow-400' return 'text-red-400' } const getStatusBg = (statusStr: string) => { if (statusStr === 'active') return 'bg-green-900/20 border-green-500' if (statusStr === 'idle') return 'bg-yellow-900/20 border-yellow-500' return 'bg-red-900/20 border-red-500' } return (
{/* Back Button */} Back to Dashboard

πŸ–₯️ EPYC Cluster Status

{status.cluster.status === 'idle' ? ( ) : ( )}
{/* Control Message */} {controlMessage && (

{controlMessage}

)} {/* Cluster Overview */}

Cluster Overview

Status
{status.cluster.status.toUpperCase()}
CPU Usage
{status.cluster.cpuUsage.toFixed(1)}%
Active Cores
{status.cluster.activeCores} / {status.cluster.totalCores}
Workers
{status.cluster.activeWorkers} / {status.cluster.totalWorkers}
{/* Coordinator Log */}

Coordinator Log

              {coordinatorLog || 'No log output available'}
            
Updates automatically every 3 seconds
{/* Worker Details */}
{status.workers.map((worker) => (

{worker.name}

{worker.host}
CPU: {worker.cpuUsage.toFixed(1)}%
Load: {worker.loadAverage}
Processes: {worker.activeProcesses}
))}
{/* Exploration Progress */}

πŸ“Š Parameter Exploration

{/* Main Stats Grid */}
Total Combinations
{status.exploration.totalCombinations.toLocaleString()}
v9 comprehensive sweep
Tested
{status.exploration.testedCombinations.toLocaleString()}
strategies evaluated
Chunks Progress
{status.exploration.chunks.completed}
of {status.exploration.chunks.total.toLocaleString()} completed
Status
{status.exploration.chunks.running > 0 ? ( ⚑ Processing ) : status.exploration.chunks.pending > 0 ? ( ⏳ Pending ) : status.exploration.chunks.completed === status.exploration.chunks.total && status.exploration.chunks.total > 0 ? ( βœ… Complete ) : ( ⏸️ Idle )}
{status.exploration.chunks.running > 0 && `${status.exploration.chunks.running} chunks running`} {status.exploration.chunks.running === 0 && status.exploration.chunks.pending > 0 && `${status.exploration.chunks.pending.toLocaleString()} chunks pending`}
{/* Chunk Status Breakdown */}
{status.exploration.chunks.completed}
βœ“ Completed
{status.exploration.chunks.running}
⏳ Running
{status.exploration.chunks.pending.toLocaleString()}
⏸️ Pending
{/* Progress Bar */}
Overall Progress {status.exploration.progress > 0 ? status.exploration.progress.toFixed(2) : '0.00'}%
{status.exploration.progress > 2 && ( {status.exploration.progress.toFixed(1)}% )}
{status.exploration.chunks.completed.toLocaleString()} / {status.exploration.chunks.total.toLocaleString()} chunks processed {status.exploration.testedCombinations > 0 && ( β€’ {status.exploration.testedCombinations.toLocaleString()} strategies evaluated )}
{/* Recommendation */} {status.recommendation && (

🎯 AI Recommendation

{status.recommendation}
)} {/* Top Strategies */} {status.topStrategies.length > 0 && (

πŸ† Top Strategies

{status.topStrategies.map((strategy) => (
#{strategy.rank}
${strategy.pnl_per_1k.toFixed(2)}
per $1k
Win Rate:{' '} {(strategy.win_rate * 100).toFixed(1)}%
Trades:{' '} {strategy.trades}
PF:{' '} {strategy.profit_factor.toFixed(2)}x
Max DD:{' '} ${Math.abs(strategy.max_drawdown).toFixed(0)}
Show Parameters
flip: {strategy.params.flip_threshold}
ma_gap: {strategy.params.ma_gap}
adx: {strategy.params.adx_min}
long_pos: {strategy.params.long_pos_max}
short_pos: {strategy.params.short_pos_min}
))}
)}
Last updated: {new Date(status.lastUpdate).toLocaleString()}
) }