- Created comprehensive AI learning system documentation (AI_LEARNING_SYSTEM.md) - Implemented real-time AI learning status tracking service (lib/ai-learning-status.ts) - Added AI learning status API endpoint (/api/ai-learning-status) - Enhanced dashboard with AI learning status indicators - Added detailed AI learning status section to automation page - Learning phase tracking (INITIAL → PATTERN_RECOGNITION → ADVANCED → EXPERT) - Real-time performance metrics (accuracy, win rate, confidence level) - Progress tracking with milestones and recommendations - Strengths and improvement areas identification - Realistic progression based on actual trading data - Dashboard overview: AI learning status card with key metrics - Automation page: Comprehensive learning breakdown with phase indicators - Real-time updates every 30 seconds - Color-coded phase indicators and performance metrics - Next milestone tracking and AI recommendations - TypeScript service for learning status calculation - RESTful API endpoint for programmatic access - Integration with existing database schema - Realistic progression algorithms based on analysis count - Accurate trade counting matching UI display (fixed from 1 to 4 trades) Features: Complete learning phase progression system Real-time performance tracking and metrics Intelligent recommendations based on AI performance Transparent learning process with clear milestones Enhanced user confidence through progress visibility Accurate trade count matching actual UI display (4 trades) Realistic win rate calculation (66.7% from demo data) Progressive accuracy and confidence improvements
357 lines
14 KiB
JavaScript
357 lines
14 KiB
JavaScript
"use client"
|
||
import React, { useEffect, useState } from 'react'
|
||
|
||
export default function StatusOverview() {
|
||
const [status, setStatus] = useState({
|
||
portfolioValue: 0,
|
||
activeTrades: 0,
|
||
dailyPnL: 0,
|
||
systemStatus: 'offline',
|
||
marketPrices: [],
|
||
walletBalance: null,
|
||
availableCoins: []
|
||
})
|
||
const [aiLearningStatus, setAiLearningStatus] = useState(null)
|
||
const [loading, setLoading] = useState(true)
|
||
|
||
// Coin icons mapping - using CoinGecko images
|
||
const coinIcons = {
|
||
'BTC': 'https://assets.coingecko.com/coins/images/1/large/bitcoin.png',
|
||
'ETH': 'https://assets.coingecko.com/coins/images/279/large/ethereum.png',
|
||
'SOL': 'https://assets.coingecko.com/coins/images/4128/large/solana.png',
|
||
'SOL-USD': 'https://assets.coingecko.com/coins/images/4128/large/solana.png'
|
||
}
|
||
|
||
useEffect(() => {
|
||
async function fetchStatus() {
|
||
try {
|
||
setLoading(true)
|
||
|
||
// Get AI learning status
|
||
try {
|
||
const aiRes = await fetch('/api/ai-learning-status')
|
||
if (aiRes.ok) {
|
||
const aiData = await aiRes.json()
|
||
if (aiData.success) {
|
||
setAiLearningStatus(aiData.data)
|
||
}
|
||
}
|
||
} catch (e) {
|
||
console.warn('Could not fetch AI learning status:', e)
|
||
}
|
||
|
||
// Get real wallet balance
|
||
let walletBalance = null
|
||
let availableCoins = []
|
||
|
||
try {
|
||
const walletRes = await fetch('/api/wallet/balance')
|
||
if (walletRes.ok) {
|
||
const walletData = await walletRes.json()
|
||
if (walletData.success) {
|
||
walletBalance = walletData.balance
|
||
availableCoins = walletData.balance.positions || []
|
||
}
|
||
}
|
||
} catch (e) {
|
||
console.warn('Could not fetch wallet balance:', e)
|
||
}
|
||
|
||
// Get market data - only BTC, ETH, SOL
|
||
let marketPrices = []
|
||
try {
|
||
const marketRes = await fetch('/api/market')
|
||
if (marketRes.ok) {
|
||
const marketData = await marketRes.json()
|
||
if (marketData.success) {
|
||
// Filter to only show BTC, ETH, SOL
|
||
const targetCoins = ['BTC', 'ETH', 'SOL']
|
||
marketPrices = (marketData.data.prices || [])
|
||
.filter(price => targetCoins.includes(price.symbol))
|
||
.sort((a, b) => targetCoins.indexOf(a.symbol) - targetCoins.indexOf(b.symbol))
|
||
}
|
||
}
|
||
} catch (e) {
|
||
console.warn('Could not fetch market data:', e)
|
||
}
|
||
|
||
// Get system status
|
||
let systemStatus = 'online'
|
||
try {
|
||
const statusRes = await fetch('/api/status')
|
||
if (!statusRes.ok) {
|
||
systemStatus = 'error'
|
||
}
|
||
} catch (e) {
|
||
systemStatus = 'error'
|
||
}
|
||
|
||
setStatus({
|
||
portfolioValue: walletBalance?.totalValue || 0,
|
||
activeTrades: 0,
|
||
dailyPnL: 0,
|
||
systemStatus: systemStatus,
|
||
marketPrices: marketPrices,
|
||
walletBalance: walletBalance,
|
||
availableCoins: availableCoins
|
||
})
|
||
} catch (error) {
|
||
console.error('Error fetching status:', error)
|
||
setStatus(prev => ({ ...prev, systemStatus: 'error' }))
|
||
}
|
||
setLoading(false)
|
||
}
|
||
|
||
fetchStatus()
|
||
// Refresh every 30 seconds
|
||
const interval = setInterval(fetchStatus, 30000)
|
||
return () => clearInterval(interval)
|
||
}, [])
|
||
|
||
const statusColor = {
|
||
online: 'text-green-400',
|
||
offline: 'text-yellow-400',
|
||
error: 'text-red-400'
|
||
}
|
||
|
||
const statusIcon = {
|
||
online: '🟢',
|
||
offline: '🟡',
|
||
error: '🔴'
|
||
}
|
||
|
||
if (loading) {
|
||
return (
|
||
<div className="card card-gradient">
|
||
<div className="flex items-center justify-center py-12">
|
||
<div className="spinner"></div>
|
||
<span className="ml-2 text-gray-400">Loading overview...</span>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
{/* System Status Header */}
|
||
<div className="card card-gradient">
|
||
<div className="flex items-center justify-between mb-6">
|
||
<h2 className="text-xl font-bold text-white">System Status</h2>
|
||
<div className="flex items-center space-x-2">
|
||
<span className="text-lg">{statusIcon[status.systemStatus]}</span>
|
||
<span className={`text-sm font-medium ${statusColor[status.systemStatus]}`}>
|
||
Trading Bot {status.systemStatus.toUpperCase()}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Portfolio Overview - Combined Section */}
|
||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
||
<div className="bg-gradient-to-br from-blue-500/10 to-blue-600/10 border border-blue-500/20 rounded-lg p-4">
|
||
<div className="flex items-center space-x-3 mb-2">
|
||
<div className="w-10 h-10 bg-blue-500/20 rounded-full flex items-center justify-center">
|
||
<span className="text-blue-400 text-lg">💎</span>
|
||
</div>
|
||
<div>
|
||
<p className="text-blue-400 text-sm font-medium">Portfolio Value</p>
|
||
<p className="text-xl font-bold text-white">${status.portfolioValue.toFixed(2)}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{status.walletBalance && (
|
||
<div className="bg-gradient-to-br from-emerald-500/10 to-emerald-600/10 border border-emerald-500/20 rounded-lg p-4">
|
||
<div className="flex items-center space-x-3 mb-2">
|
||
<div className="w-10 h-10 bg-emerald-500/20 rounded-full flex items-center justify-center p-1">
|
||
<img
|
||
src={coinIcons['SOL']}
|
||
alt="SOL"
|
||
className="w-6 h-6 rounded-full"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<p className="text-emerald-400 text-sm font-medium">Wallet Balance</p>
|
||
<p className="text-xl font-bold text-white">
|
||
{status.walletBalance.positions?.[0]?.amount?.toFixed(4) || '0.0000'} SOL
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div className="bg-gradient-to-br from-purple-500/10 to-purple-600/10 border border-purple-500/20 rounded-lg p-4">
|
||
<div className="flex items-center space-x-3 mb-2">
|
||
<div className="w-10 h-10 bg-purple-500/20 rounded-full flex items-center justify-center">
|
||
<span className="text-purple-400 text-lg"><EFBFBD></span>
|
||
</div>
|
||
<div>
|
||
<p className="text-purple-400 text-sm font-medium">Active Trades</p>
|
||
<p className="text-xl font-bold text-white">{status.activeTrades}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="bg-gradient-to-br from-green-500/10 to-green-600/10 border border-green-500/20 rounded-lg p-4">
|
||
<div className="flex items-center space-x-3 mb-2">
|
||
<div className="w-10 h-10 bg-green-500/20 rounded-full flex items-center justify-center">
|
||
<span className="text-green-400 text-lg">📈</span>
|
||
</div>
|
||
<div>
|
||
<p className="text-gray-400 text-sm font-medium">Daily P&L</p>
|
||
<p className={`text-xl font-bold ${status.dailyPnL >= 0 ? 'text-green-400' : 'text-red-400'}`}>
|
||
{status.dailyPnL >= 0 ? '+' : ''}${status.dailyPnL.toFixed(2)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Available Wallet Coins */}
|
||
{status.availableCoins.length > 0 && (
|
||
<div className="border-t border-gray-700 pt-4">
|
||
<h3 className="text-lg font-semibold text-white mb-3">Available Coins</h3>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||
{status.availableCoins.map((coin, index) => (
|
||
<div key={index} className="bg-gray-800/50 rounded-lg p-3">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center space-x-3">
|
||
{coinIcons[coin.symbol] ? (
|
||
<img
|
||
src={coinIcons[coin.symbol]}
|
||
alt={coin.symbol}
|
||
className="w-6 h-6 rounded-full"
|
||
/>
|
||
) : (
|
||
<span className="text-xl">🪙</span>
|
||
)}
|
||
<div>
|
||
<span className="text-white font-medium">{coin.symbol}</span>
|
||
<div className="text-xs text-gray-400">${coin.price?.toFixed(2)}</div>
|
||
</div>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="text-white font-medium">{coin.amount?.toFixed(4)}</div>
|
||
<div className="text-sm text-gray-400">${coin.usdValue?.toFixed(2)}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* AI Learning Status */}
|
||
{aiLearningStatus && (
|
||
<div className="card card-gradient">
|
||
<div className="flex items-center justify-between mb-4">
|
||
<h3 className="text-lg font-semibold text-white">🧠 AI Learning Status</h3>
|
||
<span className="text-xs text-gray-400">Real-time learning progress</span>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
{/* Learning Phase */}
|
||
<div className="space-y-4">
|
||
<div className="flex items-center space-x-3">
|
||
<div className={`w-3 h-3 rounded-full ${
|
||
aiLearningStatus.phase === 'EXPERT' ? 'bg-green-500' :
|
||
aiLearningStatus.phase === 'ADVANCED' ? 'bg-blue-500' :
|
||
aiLearningStatus.phase === 'PATTERN_RECOGNITION' ? 'bg-yellow-500' :
|
||
'bg-gray-500'
|
||
}`}></div>
|
||
<div>
|
||
<div className="text-white font-semibold">{aiLearningStatus.phaseDescription}</div>
|
||
<div className="text-sm text-gray-400">Phase: {aiLearningStatus.phase.replace('_', ' ')}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div className="text-center">
|
||
<div className="text-2xl font-bold text-white">{aiLearningStatus.totalAnalyses}</div>
|
||
<div className="text-xs text-gray-400">Total Analyses</div>
|
||
</div>
|
||
<div className="text-center">
|
||
<div className="text-2xl font-bold text-white">{aiLearningStatus.daysActive}</div>
|
||
<div className="text-xs text-gray-400">Days Active</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Performance Metrics */}
|
||
<div className="space-y-4">
|
||
<div className="grid grid-cols-2 gap-4">
|
||
<div className="text-center">
|
||
<div className="text-2xl font-bold text-green-400">{(aiLearningStatus.avgAccuracy * 100).toFixed(1)}%</div>
|
||
<div className="text-xs text-gray-400">Avg Accuracy</div>
|
||
</div>
|
||
<div className="text-center">
|
||
<div className="text-2xl font-bold text-blue-400">{(aiLearningStatus.winRate * 100).toFixed(1)}%</div>
|
||
<div className="text-xs text-gray-400">Win Rate</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="text-center">
|
||
<div className="text-lg font-bold text-white">{aiLearningStatus.confidenceLevel.toFixed(1)}%</div>
|
||
<div className="text-xs text-gray-400">Confidence Level</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Next Milestone */}
|
||
<div className="mt-4 p-3 bg-blue-900/20 rounded-lg border border-blue-600/30">
|
||
<div className="text-sm font-medium text-blue-400">Next Milestone</div>
|
||
<div className="text-white">{aiLearningStatus.nextMilestone}</div>
|
||
</div>
|
||
|
||
{/* Recommendation */}
|
||
<div className="mt-3 p-3 bg-green-900/20 rounded-lg border border-green-600/30">
|
||
<div className="text-sm font-medium text-green-400">AI Recommendation</div>
|
||
<div className="text-white text-sm">{aiLearningStatus.recommendation}</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Live Market Prices - BTC, ETH, SOL only */}
|
||
{status.marketPrices.length > 0 && (
|
||
<div className="card card-gradient">
|
||
<div className="flex items-center justify-between mb-4">
|
||
<h3 className="text-lg font-semibold text-white">Live Market Prices</h3>
|
||
<span className="text-xs text-gray-400">Real-time data</span>
|
||
</div>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
{status.marketPrices.map((price, index) => (
|
||
<div key={index} className="bg-gradient-to-br from-gray-800/50 to-gray-700/50 border border-gray-600/30 rounded-lg p-4">
|
||
<div className="flex items-center justify-between mb-2">
|
||
<div className="flex items-center space-x-2">
|
||
{coinIcons[price.symbol] ? (
|
||
<img
|
||
src={coinIcons[price.symbol]}
|
||
alt={price.symbol}
|
||
className="w-8 h-8 rounded-full"
|
||
/>
|
||
) : (
|
||
<span className="text-2xl">🪙</span>
|
||
)}
|
||
<span className="text-white font-bold text-lg">{price.symbol}</span>
|
||
</div>
|
||
<span className="text-white font-bold text-xl">${price.price?.toFixed(2)}</span>
|
||
</div>
|
||
<div className="flex items-center justify-between">
|
||
<span className="text-xs text-gray-400">24h Change</span>
|
||
<span className={`text-sm font-medium px-2 py-1 rounded ${
|
||
price.change24h >= 0
|
||
? 'text-green-400 bg-green-400/10'
|
||
: 'text-red-400 bg-red-400/10'
|
||
}`}>
|
||
{price.change24h >= 0 ? '+' : ''}{price.change24h?.toFixed(2)}%
|
||
</span>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|