'use client'
import React, { useState, useEffect } from 'react'
import RealTimePriceMonitor from '../../components/RealTimePriceMonitor'
export default function AutomationPage() {
const [config, setConfig] = useState({
mode: 'SIMULATION',
symbol: 'SOLUSD',
timeframe: '1h',
tradingAmount: 100,
maxLeverage: 3,
stopLossPercent: 2,
takeProfitPercent: 6,
maxDailyTrades: 5,
riskPercentage: 2
})
const [status, setStatus] = useState(null)
const [isLoading, setIsLoading] = useState(false)
const [learningInsights, setLearningInsights] = useState(null)
const [aiLearningStatus, setAiLearningStatus] = useState(null)
const [recentTrades, setRecentTrades] = useState([])
const [analysisDetails, setAnalysisDetails] = useState(null)
const [selectedTrade, setSelectedTrade] = useState(null)
const [tradeModalOpen, setTradeModalOpen] = useState(false)
const [configCollapsed, setConfigCollapsed] = useState(true)
useEffect(() => {
fetchStatus()
fetchLearningInsights()
fetchAiLearningStatus()
fetchRecentTrades()
fetchAnalysisDetails()
// Auto-refresh every 30 seconds
const interval = setInterval(() => {
fetchStatus()
fetchAnalysisDetails()
fetchAiLearningStatus()
}, 30000)
return () => clearInterval(interval)
}, [])
const fetchAnalysisDetails = async () => {
try {
const response = await fetch('/api/automation/analysis-details')
const data = await response.json()
if (data.success) {
setAnalysisDetails(data.data)
// Also update recent trades from the same endpoint
if (data.data.recentTrades) {
setRecentTrades(data.data.recentTrades)
}
}
} catch (error) {
console.error('Failed to fetch analysis details:', error)
}
}
const fetchStatus = async () => {
try {
const response = await fetch('/api/automation/status')
const data = await response.json()
if (data.success) {
setStatus(data.status)
}
} catch (error) {
console.error('Failed to fetch status:', error)
}
}
const fetchLearningInsights = async () => {
try {
const response = await fetch('/api/automation/learning-insights')
const data = await response.json()
if (data.success) {
setLearningInsights(data.insights)
}
} catch (error) {
console.error('Failed to fetch learning insights:', error)
}
}
const fetchAiLearningStatus = async () => {
try {
const response = await fetch('/api/ai-learning-status')
const data = await response.json()
if (data.success) {
setAiLearningStatus(data.data)
}
} catch (error) {
console.error('Failed to fetch AI learning status:', error)
}
}
const fetchRecentTrades = async () => {
try {
console.log('🔍 Fetching recent trades...')
// Get enhanced trade data from analysis-details instead of recent-trades
const response = await fetch('/api/automation/analysis-details')
const data = await response.json()
console.log('📊 Trade data response:', data.success, data.data?.recentTrades?.length || 0)
if (data.success && data.data.recentTrades) {
console.log('✅ Setting recent trades:', data.data.recentTrades.length)
setRecentTrades(data.data.recentTrades)
}
} catch (error) {
console.error('Failed to fetch recent trades:', error)
}
}
const handleStart = async () => {
setIsLoading(true)
try {
const response = await fetch('/api/automation/start', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(config)
})
const data = await response.json()
if (data.success) {
fetchStatus()
} else {
alert('Failed to start automation: ' + data.error)
}
} catch (error) {
console.error('Failed to start automation:', error)
alert('Failed to start automation')
} finally {
setIsLoading(false)
}
}
const handleStop = async () => {
setIsLoading(true)
try {
const response = await fetch('/api/automation/stop', {
method: 'POST'
})
const data = await response.json()
if (data.success) {
fetchStatus()
} else {
alert('Failed to stop automation: ' + data.error)
}
} catch (error) {
console.error('Failed to stop automation:', error)
alert('Failed to stop automation')
} finally {
setIsLoading(false)
}
}
const handlePause = async () => {
setIsLoading(true)
try {
const response = await fetch('/api/automation/pause', {
method: 'POST'
})
const data = await response.json()
if (data.success) {
fetchStatus()
} else {
alert('Failed to pause automation: ' + data.error)
}
} catch (error) {
console.error('Failed to pause automation:', error)
alert('Failed to pause automation')
} finally {
setIsLoading(false)
}
}
const handleResume = async () => {
setIsLoading(true)
try {
const response = await fetch('/api/automation/resume', {
method: 'POST'
})
const data = await response.json()
if (data.success) {
fetchStatus()
} else {
alert('Failed to resume automation: ' + data.error)
}
} catch (error) {
console.error('Failed to resume automation:', error)
alert('Failed to resume automation')
} finally {
setIsLoading(false)
}
}
const openTradeModal = async (tradeId) => {
try {
const response = await fetch(`/api/automation/trade-details/${tradeId}`)
const data = await response.json()
if (data.success) {
setSelectedTrade(data.data)
setTradeModalOpen(true)
} else {
alert('Failed to load trade details')
}
} catch (error) {
console.error('Failed to load trade details:', error)
alert('Failed to load trade details')
}
}
const closeTradeModal = () => {
setTradeModalOpen(false)
setSelectedTrade(null)
}
// Use status API data instead of calculating from limited recent trades
const getWinRate = () => {
return status?.winRate || 0
}
// Use status API data for total P&L
const getTotalPnL = () => {
return status?.totalPnL || 0
}
return (
Automation Mode
AI-powered automated trading on 1H timeframe with learning capabilities
{status?.isActive ? (
<>
{isLoading ? 'Pausing...' : 'Pause'}
{isLoading ? 'Stopping...' : 'Stop'}
>
) : (
<>
{status?.status === 'PAUSED' && (
{isLoading ? 'Resuming...' : 'Resume'}
)}
{isLoading ? 'Starting...' : 'Start Automation'}
>
)}
{/* Real-Time Price Monitor */}
{/* Right Side Panel - Active Trades or Status */}
{/* Active Trades Monitor */}
{status && status.activeTrades && status.activeTrades.length > 0 ? (
Active Trades Monitor
{status.activeTrades.map((trade, idx) => (
{trade.side} {trade.amount} @ ${trade.entryPrice}
0 ? 'bg-green-600' : 'bg-red-600'
} text-white`}>
${trade.unrealizedPnl}
SL: ${trade.stopLoss} | TP: ${trade.takeProfit}
))}
) : (
/* Trading Status Summary when no active trades */
Trading Status
Mode:
{config.mode}
Status:
{status?.isActive ? 'ACTIVE' : (status?.status || 'STOPPED')}
Symbol:
{config.symbol}
Timeframe:
{config.timeframe}
Active Trades:
{status?.activeTrades?.length || 0}
Trading Amount:
${config.tradingAmount}
Max Leverage:
{config.maxLeverage}x
Stop Loss:
{config.stopLossPercent}%
Take Profit:
{config.takeProfitPercent}%
Max Daily Trades:
{config.maxDailyTrades}
Risk Percentage:
{config.riskPercentage}%
{status && (
<>
Total Trades:
{status.totalTrades || 0}
Win Rate:
= 50 ? 'text-green-400' : 'text-red-400'
}`}>
{(status.winRate || 0).toFixed(1)}%
Total P&L:
0 ? 'text-green-400' :
(status.totalPnL || 0) < 0 ? 'text-red-400' : 'text-gray-400'
}`}>
${(status.totalPnL || 0).toFixed(2)}
>
)}
{/* Quick Actions */}
Quick Actions:
setConfigCollapsed(!configCollapsed)}
className="px-3 py-1 bg-blue-600 text-white rounded text-xs hover:bg-blue-700 transition-colors"
>
{configCollapsed ? 'Show Config' : 'Hide Config'}
window.location.reload()}
className="px-3 py-1 bg-gray-600 text-white rounded text-xs hover:bg-gray-700 transition-colors"
>
Refresh
)}
{/* Configuration Panel - Collapsible */}
Configuration
setConfigCollapsed(!configCollapsed)}
className="px-3 py-1 bg-gray-700 text-white rounded hover:bg-gray-600 transition-colors"
>
{configCollapsed ? 'Show' : 'Hide'}
{!configCollapsed && (
Trading Mode
setConfig({...config, mode: e.target.value})}
className="w-full p-3 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
disabled={status?.isActive}
>
Simulation (Paper Trading)
Live Trading (Jupiter DEX)
Symbol
setConfig({...config, symbol: e.target.value})}
className="w-full p-3 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
disabled={status?.isActive}
>
SOL/USD
BTC/USD
ETH/USD
Timeframe
setConfig({...config, timeframe: e.target.value})}
className="w-full p-3 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
disabled={status?.isActive}
>
1 Hour (Recommended)
4 Hours
1 Day
)}
{/* AI Learning Status */}
{aiLearningStatus && (
🧠 AI Learning Status
{/* Learning Phase */}
{aiLearningStatus.phaseDescription}
Phase: {aiLearningStatus.phase.replace('_', ' ')}
{aiLearningStatus.totalAnalyses}
Total Analyses
{aiLearningStatus.totalTrades}
Total Trades
{/* Performance Metrics */}
{(aiLearningStatus.avgAccuracy * 100).toFixed(1)}%
Avg Accuracy
{(aiLearningStatus.winRate * 100).toFixed(1)}%
Win Rate
{aiLearningStatus.confidenceLevel.toFixed(1)}%
Confidence Level
{/* Strengths and Improvements */}
Strengths
{aiLearningStatus.strengths.map((strength, idx) => (
✓ {strength}
))}
Areas for Improvement
{aiLearningStatus.improvements.map((improvement, idx) => (
• {improvement}
))}
{/* Next Milestone */}
Next Milestone
{aiLearningStatus.nextMilestone}
{/* Recommendation */}
AI Recommendation
{aiLearningStatus.recommendation}
)}
{/* Learning Insights */}
{learningInsights && (
AI Learning Insights
Total Analyses:
{learningInsights.totalAnalyses}
Avg Accuracy:
{(learningInsights.avgAccuracy * 100).toFixed(1)}%
Best Timeframe:
{learningInsights.bestTimeframe}
Worst Timeframe:
{learningInsights.worstTimeframe}
Recommendations
{learningInsights.recommendations.map((rec, idx) => (
• {rec}
))}
)}
{/* Status and Performance */}
{/* Status Panel */}
Status
{status ? (
Status:
{status.isActive ? 'ACTIVE' : 'STOPPED'}
Mode:
{status.mode}
Symbol:
{status.symbol}
Timeframe:
{status.timeframe}
Total Trades:
{status.totalTrades}
Win Rate:
60 ? 'text-green-400' :
getWinRate() > 40 ? 'text-yellow-400' : 'text-red-400'
}`}>
{getWinRate()}%
Total P&L:
0 ? 'text-green-400' :
getTotalPnL() < 0 ? 'text-red-400' : 'text-gray-300'
}`}>
${getTotalPnL()}
{status.lastAnalysis && (
Last Analysis:
{new Date(status.lastAnalysis).toLocaleTimeString()}
)}
{status.errorCount > 0 && (
Errors:
{status.errorCount}
)}
) : (
No active automation session
)}
{/* Recent Trades */}
Active & Latest Trades
(Top 4)
Debug: {recentTrades.length} total trades
{console.log('🎯 Rendering trades section, count:', recentTrades.length)}
{recentTrades.length > 0 ? (
{/* Sort trades to show active trades first, then latest completed trades */}
{recentTrades
.sort((a, b) => {
// Active trades first
if (a.isActive && !b.isActive) return -1
if (!a.isActive && b.isActive) return 1
// Then by creation date (most recent first)
return new Date(b.createdAt) - new Date(a.createdAt)
})
.slice(0, 4)
.map((trade, idx) => (
openTradeModal(trade.id)}
>
{/* Trade Header - Enhanced for active trades */}
{trade.isActive && (
)}
{trade.side}
{trade.amount}
{trade.leverage}x
{trade.isActive ? 'ACTIVE' : trade.result}
${trade.entryPrice?.toFixed(2) || trade.price?.toFixed(2) || '0.00'}
{trade.confidence || 0}% confidence
{trade.isActive && (
Current: ${trade.currentPrice?.toFixed(2) || '0.00'}
)}
{/* Enhanced Timing Information */}
Entry Time:
{new Date(trade.entryTime).toLocaleTimeString()}
Exit Time:
{trade.exitTime ? new Date(trade.exitTime).toLocaleTimeString() : 'Active'}
Duration:
{trade.durationText}
{/* Trading Details */}
Trading Mode:
{trade.tradingMode || 'SIMULATION'}
Trading Amount:
{trade.realTradingAmount ? `$${trade.realTradingAmount}` : `$${trade.tradingAmount || '0'}`}
Leverage:
{trade.leverage || 1}x
Position Size:
{trade.amount?.toFixed(6) || '0.000000'} SOL
{/* Entry Price - Always show for completed trades */}
Entry Price:
${trade.entryPrice?.toFixed(2) || trade.price?.toFixed(2) || '0.00'}
{/* Current/Exit Price with real-time updates for active trades */}
{trade.isActive ? 'Current' : 'Exit'} Price:
{trade.isActive ?
`$${trade.currentPrice?.toFixed(2) || '0.00'}` :
(trade.exitPrice ?
`$${trade.exitPrice.toFixed(2)}` :
Not recorded
)
}
{/* Live Trade Transaction ID */}
{trade.tradingMode === 'LIVE' && trade.driftTxId && (
Transaction ID:
{trade.driftTxId.slice(0, 8)}...{trade.driftTxId.slice(-8)}
)}
{/* Live Trade Fees */}
{trade.tradingMode === 'LIVE' && trade.fees > 0 && (
Fees Paid:
${trade.fees?.toFixed(4) || '0.0000'}
)}
{/* Price difference for completed trades */}
{!trade.isActive && trade.exitPrice && trade.entryPrice && (
Price Difference:
0 ? 'text-green-400' :
(trade.exitPrice - trade.entryPrice) < 0 ? 'text-red-400' :
'text-gray-400'
}`}>
${((trade.exitPrice - trade.entryPrice) >= 0 ? '+' : '')}${(trade.exitPrice - trade.entryPrice).toFixed(2)}
)}
{/* P&L Display - Enhanced for active trades */}
{trade.isActive ? 'Unrealized P&L:' : 'Realized P&L:'}
0 ? 'text-green-400' : 'text-red-400') :
(trade.realizedPnl && parseFloat(trade.realizedPnl) > 0 ? 'text-green-400' :
trade.realizedPnl && parseFloat(trade.realizedPnl) < 0 ? 'text-red-400' : 'text-gray-400')
}`}>
${trade.isActive ?
(trade.unrealizedPnl || '0.00') :
(trade.realizedPnl || '0.00')
}
{trade.pnlPercent && (
0 ? 'text-green-400' : 'text-red-400') :
(trade.realizedPnl && parseFloat(trade.realizedPnl) > 0 ? 'text-green-400' :
trade.realizedPnl && parseFloat(trade.realizedPnl) < 0 ? 'text-red-400' : 'text-gray-400')
}`}>
({trade.pnlPercent})
)}
{trade.isActive ? '⚡ Live' : '✓ Final'}
{/* Additional active trade info */}
{trade.isActive && trade.currentPrice && trade.entryPrice && (
Price Change:
0 ? 'text-green-400' : 'text-red-400'
}`}>
${((trade.currentPrice - trade.entryPrice) >= 0 ? '+' : '')}${(trade.currentPrice - trade.entryPrice).toFixed(2)}
({(((trade.currentPrice - trade.entryPrice) / trade.entryPrice) * 100).toFixed(2)}%)
)}
{/* Debug info for missing data */}
{trade.result === 'UNKNOWN' && (
⚠️ Missing exit data: {!trade.exitPrice ? 'Exit Price ' : ''}{trade.calculatedProfit === null ? 'Profit' : ''}
)}
{/* Warning for old incorrect trades */}
{trade.isOldWrongTrade && (
🔧 Old trade with incorrect price data (stored: ${trade.originalStoredPrice?.toFixed(2)}, should be ~$189)
)}
{/* Click hint */}
SL: ${trade.stopLoss} | TP: ${trade.takeProfit}
📊 Click to view analysis
))}
) : (
No recent trades
)}
{/* Detailed AI Analysis Section */}
{analysisDetails?.analysis && (
Latest AI Analysis
{/* Main Decision */}
🎯 Trading Decision
Decision:
{analysisDetails.analysis.decision}
Confidence:
80 ? 'text-green-400' :
analysisDetails.analysis.confidence > 60 ? 'text-yellow-400' :
'text-red-400'
}`}>
{analysisDetails.analysis.confidence}%
Market Sentiment:
{analysisDetails.analysis.sentiment}
Summary: {analysisDetails.analysis.summary}
{/* Key Levels */}
📊 Key Levels
{analysisDetails.analysis.keyLevels?.support?.length > 0 && (
Support Levels
{analysisDetails.analysis.keyLevels.support.map((level, idx) => (
S{idx + 1}:
${level.toFixed(2)}
))}
)}
{analysisDetails.analysis.keyLevels?.resistance?.length > 0 && (
Resistance Levels
{analysisDetails.analysis.keyLevels.resistance.map((level, idx) => (
R{idx + 1}:
${level.toFixed(2)}
))}
)}
{/* Technical Indicators */}
📈 Technical Indicators
{analysisDetails.analysis.technicalIndicators && Object.entries(analysisDetails.analysis.technicalIndicators).map(([key, value]) => (
{key.replace(/([A-Z])/g, ' $1').trim()}:
{typeof value === 'number' ? value.toFixed(2) : value}
))}
{/* AI Reasoning */}
{analysisDetails.analysis.reasoning && (
🤖 AI Reasoning
{analysisDetails.analysis.reasoning}
{analysisDetails.analysis.executionPlan && (
Execution Plan:
{analysisDetails.analysis.executionPlan}
)}
)}
{/* Risk Assessment */}
{analysisDetails.analysis.riskAssessment && (
⚠️ Risk Assessment
{analysisDetails.analysis.riskAssessment}
{analysisDetails.analysis.marketConditions && (
Market Conditions:
{analysisDetails.analysis.marketConditions}
)}
)}
{/* Layout Analysis */}
{analysisDetails.analysis.layoutAnalysis && (
🔍 Multi-Layout Analysis
{Object.entries(analysisDetails.analysis.layoutAnalysis).map(([layout, analysis]) => (
{layout} Layout:
{analysis}
))}
)}
{/* Performance Metrics */}
📊 Analysis Performance
{analysisDetails.analysis.timestamp ?
new Date(analysisDetails.analysis.timestamp).toLocaleTimeString() :
'N/A'
}
Last Analysis
{analysisDetails.analysis.processingTime ?
`${analysisDetails.analysis.processingTime}ms` :
'N/A'
}
Processing Time
{analysisDetails.session?.totalTrades || 0}
Total Trades
{analysisDetails.session?.errorCount || 0}
Errors
)}
{/* Multi-Timeframe Analysis Results */}
{analysisDetails?.analysis?.multiTimeframeResults && analysisDetails.analysis.multiTimeframeResults.length > 0 && (
📊 Multi-Timeframe Analysis
{analysisDetails.analysis.multiTimeframeResults.map((result, index) => (
{result.analysisComplete ? (
✅
) : (
⏳
)}
{result.timeframe} Timeframe
{result.analysisComplete ? 'Complete' : 'In Progress'}
Decision:
{result.decision}
Confidence:
80 ? 'text-green-400' :
result.confidence > 60 ? 'text-yellow-400' :
'text-red-400'
}`}>
{result.confidence}%
Sentiment:
{result.sentiment}
{result.createdAt && (
Analyzed: {new Date(result.createdAt).toLocaleString()}
)}
))}
{/* Multi-Timeframe Summary */}
📈 Cross-Timeframe Consensus
{analysisDetails.analysis.multiTimeframeResults.length}
Timeframes Analyzed
{analysisDetails.analysis.multiTimeframeResults.filter(r => r.analysisComplete).length}
Completed
{Math.round(
analysisDetails.analysis.multiTimeframeResults.reduce((sum, r) => sum + r.confidence, 0) /
analysisDetails.analysis.multiTimeframeResults.length
)}%
Avg Confidence
)}
{/* No Analysis Available */}
{!analysisDetails?.analysis && status?.isActive && (
🤖 AI Analysis
Waiting for first analysis...
The AI will analyze the market every hour
)}
{/* Trade Details Modal */}
{tradeModalOpen && selectedTrade && (
{/* Modal Header */}
Trade Analysis Details
{selectedTrade.side} {selectedTrade.amount} @ ${selectedTrade.price?.toFixed(2) || '0.00'}
0 ? 'bg-green-600 text-white' : 'bg-red-600 text-white'
}`}>
{selectedTrade.status} {selectedTrade.profit && `(${selectedTrade.profit > 0 ? '+' : ''}$${selectedTrade.profit?.toFixed(2) || '0.00'})`}
×
{/* Modal Content */}
{/* Trade Overview */}
Trade Info
Entry Time:
{new Date(selectedTrade.entryTime).toLocaleString()}
Exit Time:
{selectedTrade.exitTime ? new Date(selectedTrade.exitTime).toLocaleString() : 'Active'}
Duration:
{selectedTrade.exitTime ?
`${Math.floor((new Date(selectedTrade.exitTime) - new Date(selectedTrade.entryTime)) / (1000 * 60))}m` :
`${Math.floor((new Date() - new Date(selectedTrade.entryTime)) / (1000 * 60))}m (Active)`
}
Position Details
Trading Amount:
${selectedTrade.tradingAmount}
Leverage:
{selectedTrade.leverage}x
Position Size:
${selectedTrade.positionSize}
Risk Management
Stop Loss:
${selectedTrade.detailedAnalysis?.keyLevels?.stopLoss?.price || 'N/A'}
Take Profit:
${selectedTrade.detailedAnalysis?.keyLevels?.takeProfit?.price || 'N/A'}
Risk/Reward:
{selectedTrade.detailedAnalysis?.riskManagement?.riskReward || 'N/A'}
{/* Analysis Screenshots */}
📊 Analysis Screenshots
{selectedTrade.screenshots && Object.entries(selectedTrade.screenshots).map(([key, screenshot]) => (
{screenshot.title}
📷 {screenshot.title}
{screenshot.description}
{screenshot.description}
))}
{/* AI Analysis Details */}
{selectedTrade.detailedAnalysis && (
🤖 AI Analysis
{/* Decision Summary */}
Decision Summary
{selectedTrade.detailedAnalysis.decision} ({selectedTrade.detailedAnalysis.confidence}%)
{selectedTrade.detailedAnalysis.aiReasoning}
{/* Multi-timeframe Analysis */}
Multi-timeframe Analysis
{selectedTrade.detailedAnalysis.timeframes && Object.entries(selectedTrade.detailedAnalysis.timeframes).map(([tf, data]) => (
{tf}
{data.decision}
Confidence: {data.confidence}%
{data.signals.slice(0, 2).map((signal, idx) => (
• {signal}
))}
))}
{/* Technical Indicators */}
Technical Indicators
{selectedTrade.detailedAnalysis.technicalIndicators && Object.entries(selectedTrade.detailedAnalysis.technicalIndicators).map(([indicator, data]) => (
{indicator}
{data.value}
{data.interpretation}
))}
{/* Execution Plan */}
Execution Plan
{selectedTrade.detailedAnalysis.executionPlan && Object.entries(selectedTrade.detailedAnalysis.executionPlan).map(([key, value]) => (
{key}:
{value}
))}
)}
)}
)
}