Files
trading_bot_v3/app/safe-paper-trading/page.js.backup

1786 lines
77 KiB
Plaintext
Raw Blame History

'use client'
import { useState, useEffect } from 'react'
// Available timeframes for analysis (matching automation-v2 format)
const timeframes = [
{ label: '5m', value: '5' },
{ label: '15m', value: '15' },
{ label: '30m', value: '30' },
{ label: '1h', value: '60' },
{ label: '2h', value: '120' },
{ label: '4h', value: '240' },
{ label: '1d', value: 'D' },
]
// Intelligent delay mapping based on timeframe (optimize ChatGPT budget)
const ANALYSIS_DELAYS = {
'5': 5 * 60 * 1000, // 5m chart: analyze every 5 minutes
'15': 15 * 60 * 1000, // 15m chart: analyze every 15 minutes
'30': 30 * 60 * 1000, // 30m chart: analyze every 30 minutes
'60': 60 * 60 * 1000, // 1h chart: analyze every 1 hour
'120': 2 * 60 * 60 * 1000, // 2h chart: analyze every 2 hours
'240': 4 * 60 * 60 * 1000, // 4h chart: analyze every 4 hours
'D': 24 * 60 * 60 * 1000, // 1d chart: analyze once per day
}
export default function SafePaperTradingPage() {
const [symbol, setSymbol] = useState('SOLUSD')
const [selectedTimeframes, setSelectedTimeframes] = useState(['60']) // Default to 1h
const [loading, setLoading] = useState(false)
const [currentAnalysis, setCurrentAnalysis] = useState(null)
const [paperBalance, setPaperBalance] = useState(1000)
const [paperTrades, setPaperTrades] = useState([])
const [analysisHistory, setAnalysisHistory] = useState([])
const [error, setError] = useState(null)
const [learningInsights, setLearningInsights] = useState(null)
const [showDetailedAnalysis, setShowDetailedAnalysis] = useState(false)
const [continuousLearning, setContinuousLearning] = useState(false)
const [autoExecuteTrades, setAutoExecuteTrades] = useState(false) // New: Auto-execute trades based on AI recommendations
const [learningInterval, setLearningInterval] = useState(null)
const [lastAnalysisTime, setLastAnalysisTime] = useState(null)
const [nextAnalysisTime, setNextAnalysisTime] = useState(null)
const [countdownTimer, setCountdownTimer] = useState(null)
const [timeRemaining, setTimeRemaining] = useState(0)
// Load persisted analysis data on component mount
useEffect(() => {
const loadPersistedData = () => {
try {
const savedAnalysis = localStorage.getItem('safePaperTrading_currentAnalysis')
const savedTrades = localStorage.getItem('safePaperTrading_paperTrades')
const savedBalance = localStorage.getItem('safePaperTrading_paperBalance')
const savedHistory = localStorage.getItem('safePaperTrading_analysisHistory')
const savedLearningInsights = localStorage.getItem('safePaperTrading_learningInsights')
const savedContinuousLearning = localStorage.getItem('safePaperTrading_continuousLearning')
const savedAutoExecute = localStorage.getItem('safePaperTrading_autoExecute')
if (savedAnalysis) {
const parsedAnalysis = JSON.parse(savedAnalysis)
// Check if the saved analysis is stale (older than 2 hours)
const analysisAge = Date.now() - new Date(parsedAnalysis.timestamp).getTime()
const twoHours = 2 * 60 * 60 * 1000
if (analysisAge > twoHours) {
console.log('📂 Found stale analysis data (>2 hours old), will fetch fresh data')
localStorage.removeItem('safePaperTrading_currentAnalysis')
// Trigger fresh analysis after component loads
setTimeout(() => {
console.log('🔄 Fetching fresh analysis to replace stale data')
runSafeAnalysis(false)
}, 5000)
} else {
setCurrentAnalysis(parsedAnalysis)
console.log('📂 Restored recent analysis from localStorage')
}
} else {
// No saved analysis, fetch fresh data
setTimeout(() => {
console.log('🔄 No saved analysis found, fetching fresh data')
runSafeAnalysis(false)
}, 3000)
}
if (savedTrades) {
const parsedTrades = JSON.parse(savedTrades)
setPaperTrades(parsedTrades)
console.log(`📂 Restored ${parsedTrades.length} paper trades`)
}
if (savedBalance) {
const parsedBalance = parseFloat(savedBalance)
setPaperBalance(parsedBalance)
console.log(`📂 Restored paper balance: $${parsedBalance}`)
}
if (savedHistory) {
const parsedHistory = JSON.parse(savedHistory)
setAnalysisHistory(parsedHistory)
console.log(`📂 Restored ${parsedHistory.length} analysis history entries`)
}
if (savedLearningInsights) {
const parsedInsights = JSON.parse(savedLearningInsights)
setLearningInsights(parsedInsights)
console.log('📂 Restored learning insights from localStorage')
}
if (savedContinuousLearning === 'true') {
console.log('📂 Found continuous learning was active - restarting...')
setContinuousLearning(true)
// Restart continuous learning after a short delay to ensure component is ready
setTimeout(() => {
console.log('<27> Restarting continuous learning from localStorage')
startContinuousLearning()
}, 3000) // Increased delay to ensure everything is loaded
}
} catch (error) {
console.error('⚠️ Error loading persisted data:', error)
// Clear corrupted data
localStorage.removeItem('safePaperTrading_currentAnalysis')
localStorage.removeItem('safePaperTrading_paperTrades')
localStorage.removeItem('safePaperTrading_paperBalance')
localStorage.removeItem('safePaperTrading_analysisHistory')
localStorage.removeItem('safePaperTrading_learningInsights')
localStorage.removeItem('safePaperTrading_continuousLearning')
}
}
loadPersistedData()
// Load auto-execute setting
try {
const savedAutoExecute = localStorage.getItem('safePaperTrading_autoExecute')
if (savedAutoExecute === 'true') {
console.log('📂 Found auto-execute was enabled - restoring...')
setAutoExecuteTrades(true)
}
} catch (error) {
console.error('⚠️ Error loading auto-execute setting:', error)
}
// Check if continuous learning should be active
const checkContinuousLearningState = () => {
try {
const savedContinuousLearning = localStorage.getItem('safePaperTrading_continuousLearning')
console.log('🔍 Checking continuous learning state:', savedContinuousLearning)
if (savedContinuousLearning === 'true') {
console.log('🔄 Restoring continuous learning state...')
setContinuousLearning(true)
setTimeout(() => {
console.log('🎓 Starting continuous learning from restored state')
startContinuousLearning()
}, 2000)
}
} catch (error) {
console.error('⚠️ Error checking continuous learning state:', error)
}
}
// Check state after a short delay to ensure everything is loaded
setTimeout(checkContinuousLearningState, 1000)
}, [])
// Persist analysis data whenever it changes
useEffect(() => {
if (currentAnalysis) {
try {
localStorage.setItem('safePaperTrading_currentAnalysis', JSON.stringify(currentAnalysis))
console.log('💾 Persisted current analysis to localStorage')
} catch (error) {
console.error('⚠️ Error persisting current analysis:', error)
}
}
}, [currentAnalysis])
useEffect(() => {
if (paperTrades.length >= 0) { // Always persist, even empty array
try {
localStorage.setItem('safePaperTrading_paperTrades', JSON.stringify(paperTrades))
console.log(`💾 Persisted ${paperTrades.length} paper trades`)
} catch (error) {
console.error('⚠️ Error persisting paper trades:', error)
}
}
}, [paperTrades])
useEffect(() => {
try {
localStorage.setItem('safePaperTrading_paperBalance', paperBalance.toString())
console.log(`💾 Persisted paper balance: $${paperBalance}`)
} catch (error) {
console.error('⚠️ Error persisting paper balance:', error)
}
}, [paperBalance])
useEffect(() => {
if (learningInsights) {
try {
localStorage.setItem('safePaperTrading_learningInsights', JSON.stringify(learningInsights))
console.log('💾 Persisted learning insights to localStorage')
} catch (error) {
console.error('⚠️ Error persisting learning insights:', error)
}
}
}, [learningInsights])
// Persist continuous learning state
useEffect(() => {
try {
localStorage.setItem('safePaperTrading_continuousLearning', continuousLearning.toString())
console.log(`💾 Persisted continuous learning state: ${continuousLearning}`)
} catch (error) {
console.error('⚠️ Error persisting continuous learning state:', error)
}
}, [continuousLearning])
// Persist auto-execute setting
useEffect(() => {
try {
localStorage.setItem('safePaperTrading_autoExecute', autoExecuteTrades.toString())
console.log(`💾 Persisted auto-execute setting: ${autoExecuteTrades}`)
} catch (error) {
console.error('⚠️ Error persisting auto-execute setting:', error)
}
}, [autoExecuteTrades])
// Live countdown timer for continuous learning
useEffect(() => {
if (continuousLearning && nextAnalysisTime) {
// Clear any existing countdown timer
if (countdownTimer) {
clearInterval(countdownTimer)
}
// Create new countdown timer that updates every second
const countdown = setInterval(() => {
const remaining = nextAnalysisTime - Date.now()
if (remaining <= 0) {
setTimeRemaining(0)
} else {
setTimeRemaining(remaining)
}
}, 1000)
setCountdownTimer(countdown)
// Initial calculation
const remaining = nextAnalysisTime - Date.now()
setTimeRemaining(remaining > 0 ? remaining : 0)
return () => {
if (countdown) {
clearInterval(countdown)
}
}
} else {
// Clear countdown when not in continuous learning
if (countdownTimer) {
clearInterval(countdownTimer)
setCountdownTimer(null)
}
setTimeRemaining(0)
}
}, [continuousLearning, nextAnalysisTime])
// Clean up countdown on unmount
useEffect(() => {
return () => {
if (countdownTimer) {
clearInterval(countdownTimer)
}
}
}, [])
// Health check for continuous learning - ensure it's actually running
useEffect(() => {
if (continuousLearning) {
const healthCheck = setInterval(() => {
if (!learningInterval) {
console.warn('⚠️ HEALTH CHECK: Continuous learning is ON but interval is missing - restarting...')
restartContinuousLearning()
} else {
console.log('✅ HEALTH CHECK: Continuous learning interval is active')
}
}, 5 * 60 * 1000) // Check every 5 minutes
return () => clearInterval(healthCheck)
}
}, [continuousLearning, learningInterval])
// SAFETY: Only these timeframes allowed in paper trading
const safeTimeframes = timeframes.map(tf => ({
...tf,
riskLevel: tf.value === '5' || tf.value === '15' ? 'HIGH' :
tf.value === '30' || tf.value === '60' ? 'MEDIUM' : 'LOW'
}))
const settings = {
riskPerTrade: 1.0,
paperMode: true, // ALWAYS true - cannot be changed
isolatedMode: true // ALWAYS true - completely isolated
}
const toggleTimeframe = (timeframe) => {
setSelectedTimeframes(prev =>
prev.includes(timeframe)
? prev.filter(tf => tf !== timeframe)
: [...prev, timeframe]
)
}
const calculateOptimalDelay = () => {
if (selectedTimeframes.length === 0) return 60 * 60 * 1000 // Default 1 hour
// Use the shortest timeframe as base, but not too frequent for budget optimization
const shortestTf = selectedTimeframes.reduce((shortest, current) => {
const currentDelay = ANALYSIS_DELAYS[current] || 60 * 60 * 1000
const shortestDelay = ANALYSIS_DELAYS[shortest] || 60 * 60 * 1000
return currentDelay < shortestDelay ? current : shortest
})
// Minimum 10 minutes delay to protect ChatGPT budget
return Math.max(ANALYSIS_DELAYS[shortestTf] || 60 * 60 * 1000, 10 * 60 * 1000)
}
// Format countdown time for display
const formatCountdown = (milliseconds) => {
if (milliseconds <= 0) return 'Running soon...'
const totalSeconds = Math.ceil(milliseconds / 1000)
const hours = Math.floor(totalSeconds / 3600)
const minutes = Math.floor((totalSeconds % 3600) / 60)
const seconds = totalSeconds % 60
if (hours > 0) {
return `${hours}h ${minutes}m ${seconds}s`
} else if (minutes > 0) {
return `${minutes}m ${seconds}s`
} else {
return `${seconds}s`
}
}
const startContinuousLearning = () => {
if (learningInterval) {
clearInterval(learningInterval)
}
const delay = calculateOptimalDelay()
console.log(`🎓 Starting continuous learning with ${delay / 60000} minute intervals`)
// Run first analysis immediately for faster feedback
setTimeout(async () => {
console.log('🔄 IMMEDIATE: Running first continuous learning analysis')
console.log('📚 Running immediate learning analysis (paper trading mode)')
try {
await runSafeAnalysis(true) // Mark as continuous learning
} catch (error) {
console.error('❌ Error in immediate analysis:', error)
}
}, 5000) // 5 seconds delay for immediate feedback
const interval = setInterval(async () => {
console.log('🔄 Continuous learning cycle triggered')
console.log(`📊 Current time: ${new Date().toLocaleTimeString()}`)
// For safe paper trading, always run analysis regardless of positions
// (since it's completely isolated and for learning purposes)
console.log('📚 Running scheduled learning analysis (paper trading mode)')
try {
await runSafeAnalysis(true) // Mark as continuous learning
} catch (error) {
console.error('❌ Error in continuous learning cycle:', error)
// Set next time even if there's an error to prevent stopping
setNextAnalysisTime(Date.now() + delay)
}
}, delay)
setLearningInterval(interval)
setNextAnalysisTime(Date.now() + 5000) // Show immediate next time (5 seconds)
console.log(`🎓 Continuous learning started - next analysis in 5 seconds, then every ${delay / 60000} minutes`)
}
const stopContinuousLearning = () => {
if (learningInterval) {
clearInterval(learningInterval)
setLearningInterval(null)
setNextAnalysisTime(null)
console.log('🛑 Continuous learning stopped')
}
}
const restartContinuousLearning = () => {
console.log('🔄 Restarting continuous learning...')
stopContinuousLearning()
// Small delay to ensure cleanup
setTimeout(() => {
startContinuousLearning()
console.log('✅ Continuous learning restarted successfully')
}, 1000)
}
useEffect(() => {
// Load paper trading data from localStorage
const savedTrades = localStorage.getItem('safePaperTrades')
const savedBalance = localStorage.getItem('safePaperBalance')
if (savedTrades) {
setPaperTrades(JSON.parse(savedTrades))
}
if (savedBalance) {
setPaperBalance(parseFloat(savedBalance))
}
// Fetch AI learning status
fetchLearningStatus()
// Cleanup continuous learning on unmount
return () => {
if (learningInterval) {
clearInterval(learningInterval)
}
}
}, [])
// Update continuous learning when timeframes change
useEffect(() => {
if (continuousLearning) {
stopContinuousLearning()
startContinuousLearning()
}
}, [selectedTimeframes])
// Save to localStorage whenever data changes
useEffect(() => {
localStorage.setItem('safePaperTrades', JSON.stringify(paperTrades))
localStorage.setItem('safePaperBalance', paperBalance.toString())
}, [paperTrades, paperBalance])
const runSafeAnalysis = async (isContinuous = false) => {
console.log(`🔄 ${isContinuous ? 'CONTINUOUS LEARNING' : 'BUTTON CLICKED'}: Starting safe analysis...`)
console.log(`🎯 Analysis Type: ${isContinuous ? 'CONTINUOUS LEARNING' : 'MANUAL'} for ${symbol}`)
console.log(`⏰ Current time: ${new Date().toLocaleString()}`)
console.log(`📊 Selected timeframes: ${selectedTimeframes.join(', ')}`)
if (isContinuous) {
console.log(`🎓 This is a CONTINUOUS LEARNING cycle - automatic analysis`)
}
console.log(`📊 Selected timeframes: ${selectedTimeframes.join(', ')}`)
setLoading(true)
setError(null)
setLastAnalysisTime(Date.now())
try {
console.log('📄 SAFE PAPER TRADING: Starting isolated analysis...')
console.log('📋 Request data:', {
symbol,
selectedTimeframes,
mode: 'PAPER_ONLY',
paperTrading: true,
isolatedMode: true,
isContinuous
})
console.log(`🌐 Making API call to /api/paper-trading-safe...`)
// SAFETY: Only call the isolated paper trading API
const response = await fetch('/api/paper-trading-safe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
symbol,
selectedTimeframes,
mode: 'PAPER_ONLY', // REQUIRED for safety
paperTrading: true,
isolatedMode: true,
isContinuous
})
})
console.log('📡 Response status:', response.status)
console.log('📡 Response ok:', response.ok)
if (!response.ok) {
const errorText = await response.text()
console.error('❌ Response error:', errorText)
throw new Error(`Analysis failed: ${response.status} - ${errorText}`)
}
const result = await response.json()
console.log('📊 Full API result:', result)
if (!result.success) {
throw new Error(result.error || 'Analysis failed')
}
console.log('✅ SAFE ANALYSIS COMPLETE:', result.analysis.recommendation)
const analysisData = {
...result.analysis,
timeframes: selectedTimeframes,
analysisType: isContinuous ? 'CONTINUOUS_LEARNING' : 'MANUAL'
}
setCurrentAnalysis(analysisData)
// Add to analysis history with timestamp
const historyEntry = {
...analysisData,
timestamp: new Date().toISOString(),
symbol: symbol,
timeframes: selectedTimeframes,
analysisId: `analysis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
}
// Keep only last 10 analyses in history
setAnalysisHistory(prev => {
const updated = [historyEntry, ...prev].slice(0, 10)
try {
localStorage.setItem('safePaperTrading_analysisHistory', JSON.stringify(updated))
console.log(`💾 Persisted ${updated.length} analysis history entries`)
} catch (error) {
console.error('⚠️ Error persisting analysis history:', error)
}
return updated
})
// Update next analysis time for both manual and continuous learning
if (continuousLearning) {
const delay = calculateOptimalDelay()
const nextTime = Date.now() + delay
setNextAnalysisTime(nextTime)
console.log(`⏰ Next analysis scheduled for: ${new Date(nextTime).toLocaleString()}`)
console.log(`⏱️ Delay: ${delay / 60000} minutes`)
}
// AUTO-EXECUTE TRADES: If auto-execute is enabled and we have a strong recommendation, execute the trade
console.log('🔍 Checking auto-execute conditions:', {
autoExecuteTrades,
recommendation: analysisData.recommendation,
confidence: analysisData.confidence,
hasAnalysisData: !!analysisData
})
if (autoExecuteTrades && analysisData.recommendation && analysisData.confidence >= 60) {
const recommendation = analysisData.recommendation.toUpperCase()
if (recommendation === 'BUY' || recommendation === 'SELL') {
console.log(`🤖 AUTO-EXECUTE: ${recommendation} signal with ${analysisData.confidence}% confidence`)
// Wait a moment for the analysis to fully update, then execute
setTimeout(() => {
try {
executeSafePaperTrade(recommendation)
console.log(`✅ AUTO-EXECUTED: ${recommendation} trade based on AI recommendation`)
} catch (error) {
console.error('❌ Auto-execute error:', error)
}
}, 1000)
} else {
console.log(`💡 AUTO-EXECUTE: HOLD signal (${recommendation}) - no trade executed`)
}
} else if (autoExecuteTrades) {
console.log(`💡 AUTO-EXECUTE: Recommendation ${analysisData.recommendation} with ${analysisData.confidence}% confidence does not meet execution criteria (need BUY/SELL with ≥60% confidence)`)
} else {
console.log(`🔍 AUTO-EXECUTE: Disabled or no valid recommendation`)
}
} catch (error) {
console.error('❌ Safe analysis error:', error)
console.error('❌ Error stack:', error.stack)
setError(error.message)
} finally {
setLoading(false)
console.log('🏁 Analysis complete, loading set to false')
}
}
const executeSafePaperTrade = (signal) => {
if (!currentAnalysis) return
const trade = {
id: Date.now(),
timestamp: new Date().toISOString(),
symbol: currentAnalysis.symbol,
timeframe: currentAnalysis.timeframe,
side: signal,
entryPrice: currentAnalysis.entry?.price || 100,
stopLoss: currentAnalysis.stopLoss?.price,
takeProfit: currentAnalysis.takeProfits?.tp1?.price,
confidence: currentAnalysis.confidence,
reasoning: currentAnalysis.reasoning,
status: 'OPEN',
momentumStatus: currentAnalysis.momentumStatus?.type,
entryQuality: currentAnalysis.entryQuality?.score,
paperMode: true,
safeMode: true
}
// Calculate position size based on risk management
const riskAmount = paperBalance * (settings.riskPerTrade / 100)
const stopDistance = Math.abs(trade.entryPrice - (trade.stopLoss || trade.entryPrice * 0.95))
trade.positionSize = Math.min(riskAmount / stopDistance, paperBalance * 0.1)
setPaperTrades(prev => [trade, ...prev])
console.log('📄 SAFE PAPER TRADE:', trade)
alert(`✅ Safe Paper Trade: ${signal} ${trade.symbol} at $${trade.entryPrice}\\n💡 This is completely isolated - no real money at risk!`)
}
const closeSafePaperTrade = (tradeId, exitPrice) => {
setPaperTrades(prev => prev.map(trade => {
if (trade.id === tradeId && trade.status === 'OPEN') {
const pnl = trade.side === 'BUY'
? (exitPrice - trade.entryPrice) * (trade.positionSize / trade.entryPrice)
: (trade.entryPrice - exitPrice) * (trade.positionSize / trade.entryPrice)
const isWinner = pnl > 0
setPaperBalance(current => current + pnl)
// Update learning insights after closing trade
updateLearningInsights(trade, pnl, isWinner)
return {
...trade,
status: 'CLOSED',
exitPrice,
exitTime: new Date().toISOString(),
pnl,
isWinner,
exitReason: 'Manual close'
}
}
return trade
}))
}
const updateLearningInsights = async (trade, pnl, isWinner) => {
try {
// Simulate AI learning from trade outcome
const learningData = {
tradeId: trade.id,
symbol: trade.symbol,
timeframe: trade.timeframe,
side: trade.side,
entryPrice: trade.entryPrice,
exitPrice: trade.exitPrice || null,
pnl,
isWinner,
confidence: trade.confidence,
reasoning: trade.reasoning,
timestamp: new Date().toISOString()
}
console.log('🧠 AI Learning from trade outcome:', learningData)
// Call learning API if available (simulated for paper trading)
setLearningInsights(prev => ({
...prev,
lastTrade: learningData,
totalTrades: (prev?.totalTrades || 0) + 1,
winners: isWinner ? (prev?.winners || 0) + 1 : (prev?.winners || 0),
learningPoints: [
...(prev?.learningPoints || []).slice(-4), // Keep last 4
{
timestamp: new Date().toISOString(),
insight: generateLearningInsight(trade, pnl, isWinner),
impact: isWinner ? 'POSITIVE' : 'NEGATIVE',
confidence: trade.confidence
}
]
}))
} catch (error) {
console.error('❌ Error updating learning insights:', error)
}
}
const generateLearningInsight = (trade, pnl, isWinner) => {
const winRate = trade.confidence
if (isWinner) {
if (winRate >= 80) {
return `High confidence (${winRate}%) trade succeeded. Reinforcing pattern recognition for ${trade.symbol} ${trade.timeframe}m setups.`
} else {
return `Medium confidence (${winRate}%) trade worked out. Learning to trust similar setups more in future.`
}
} else {
if (winRate >= 80) {
return `High confidence (${winRate}%) trade failed. Reviewing analysis criteria to prevent overconfidence in similar setups.`
} else {
return `Medium confidence (${winRate}%) trade didn't work. Adjusting risk thresholds for ${trade.timeframe}m timeframe.`
}
}
}
const fetchLearningStatus = async () => {
try {
// Fetch real AI learning status from the learning system
console.log('🧠 Fetching real AI learning status...')
// Get real learning status from the AI learning system
const response = await fetch('/api/ai-learning-status', {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
if (response.ok) {
const result = await response.json()
const realLearningData = result.data
console.log('✅ Real learning status received:', realLearningData)
setLearningInsights(prev => ({
...prev,
status: {
totalDecisions: realLearningData.totalDecisions || 0,
recentDecisions: realLearningData.totalOutcomes || 0,
successRate: (realLearningData.avgAccuracy || 0) / 100,
currentThresholds: {
emergency: 0.5,
risk: 1.5,
confidence: realLearningData.confidenceLevel || 75
},
nextTradeAdjustments: [
realLearningData.recommendation || 'Learning system initializing...',
realLearningData.nextMilestone || 'Building pattern recognition',
`Phase: ${realLearningData.phase || 'INITIALIZATION'}`
],
phase: realLearningData.phase,
winRate: realLearningData.winRate,
daysActive: realLearningData.daysActive
}
}))
} else {
// If learning API not available, create basic structure without mock data
console.log('⚠️ Learning API not available, using basic structure')
setLearningInsights(prev => ({
...prev,
status: {
totalDecisions: 0,
recentDecisions: 0,
successRate: 0,
currentThresholds: {
emergency: 0.5,
risk: 1.5,
confidence: 75
},
nextTradeAdjustments: [
'Learning system initializing...',
'Building pattern recognition database',
'Preparing adaptive decision making'
]
}
}))
}
} catch (error) {
console.error('❌ Error fetching learning status:', error)
// Minimal structure without any mock data
setLearningInsights(prev => ({
...prev,
status: {
totalDecisions: 0,
recentDecisions: 0,
successRate: 0,
currentThresholds: {
emergency: 0.5,
risk: 1.5,
confidence: 75
},
nextTradeAdjustments: ['Learning system offline']
}
}))
}
}
const resetSafePaperTrading = () => {
if (confirm('Reset all SAFE paper trading data? This cannot be undone.')) {
setPaperBalance(1000)
setPaperTrades([])
setCurrentAnalysis(null)
localStorage.removeItem('safePaperTrades')
localStorage.removeItem('safePaperBalance')
}
}
const openTrades = paperTrades.filter(t => t.status === 'OPEN')
const closedTrades = paperTrades.filter(t => t.status === 'CLOSED')
const totalPnL = closedTrades.reduce((sum, trade) => sum + (trade.pnl || 0), 0)
const winRate = closedTrades.length > 0
? Math.round((closedTrades.filter(t => (t.pnl || 0) > 0).length / closedTrades.length) * 100)
: 0
return (
<div className="space-y-6">
{/* SAFETY NOTICE */}
<div className="bg-green-900/30 border border-green-700 rounded-lg p-4">
<h2 className="text-green-400 font-bold text-lg mb-2">🛡️ SAFE PAPER TRADING MODE</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
<div>
<p className="text-green-300 mb-1">✅ Completely isolated from real trading</p>
<p className="text-green-300 mb-1">✅ No connection to live trading APIs</p>
<p className="text-green-300">✅ Zero risk of real money execution</p>
</div>
<div>
<p className="text-green-300 mb-1">🧠 AI learning through safe simulation</p>
<p className="text-green-300 mb-1">📊 Real market analysis for practice</p>
<p className="text-green-300">🎯 Perfect for confidence building</p>
</div>
</div>
</div>
{/* AI LEARNING SETUP NOTICE */}
{!continuousLearning || !autoExecuteTrades ? (
<div className="bg-blue-900/30 border border-blue-600 rounded-lg p-4">
<h3 className="text-blue-400 font-bold text-lg mb-2">🤖 Enable AI Learning from Virtual Trading</h3>
<div className="text-sm text-blue-300 mb-3">
<strong>How AI Learning Works:</strong> The system must execute virtual trades and track outcomes to learn patterns and improve predictions.
</div>
<div className="grid grid-cols-1 gap-4">
<div className="bg-blue-800/30 rounded p-3">
<h4 className="text-blue-300 font-medium mb-1">Click "🎓 Start Learning" (Auto-enables trade execution)</h4>
<p className="text-xs text-blue-200">
{continuousLearning ? '✅ Learning Active → Auto-execute Enabled' : '❌ Click "🎓 Start Learning" button below'}
</p>
<div className="mt-2 text-xs text-green-400 bg-green-900/20 px-2 py-1 rounded">
💡 <strong>Auto-Execute:</strong> Automatically enabled with learning - AI needs trade outcomes to improve
</div>
</div>
</div>
<div className="mt-3 text-xs text-blue-300 bg-blue-800/20 px-3 py-2 rounded">
<strong>Learning Process:</strong> AI analyzes → executes virtual trades → tracks outcomes → learns from results → improves predictions
</div>
</div>
) : (
<div className="bg-green-900/30 border border-green-600 rounded-lg p-4">
<h3 className="text-green-400 font-bold text-lg mb-2">✅ AI Learning System Active</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
<div className="text-green-300">
<span className="font-medium">🎓 Continuous Learning:</span> ON
</div>
<div className="text-green-300">
<span className="font-medium">🤖 Auto-Execute:</span> ON
</div>
<div className="text-green-300">
<span className="font-medium">📈 Virtual Trading:</span> Active
</div>
</div>
<div className="mt-2 text-xs text-green-300">
🧠 AI will automatically execute virtual trades based on analysis and learn from outcomes to improve performance
</div>
</div>
)}
{/* Header with Balance */}
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center space-x-4">
<h1 className="text-2xl font-bold text-white">📄 Safe Paper Trading</h1>
{continuousLearning && (
<div className="flex items-center bg-green-900/30 border border-green-600/50 rounded-lg px-3 py-2">
<div className="w-2 h-2 bg-green-400 rounded-full animate-pulse mr-2"></div>
<div className="text-sm">
<span className="text-green-400 font-medium">🎓 Learning Active</span>
{timeRemaining > 0 && (
<div className="text-xs text-green-300 font-mono">
Next cycle: {formatCountdown(timeRemaining)}
</div>
)}
</div>
</div>
)}
</div>
<div className="flex items-center space-x-4">
<div className="text-right">
<p className="text-sm text-gray-400">Virtual Balance</p>
<p className={`text-lg font-bold ${paperBalance >= 1000 ? 'text-green-400' : 'text-red-400'}`}>
${paperBalance.toFixed(2)}
</p>
</div>
<div className="text-right">
<p className="text-sm text-gray-400">Total P&L</p>
<p className={`text-lg font-bold ${totalPnL >= 0 ? 'text-green-400' : 'text-red-400'}`}>
${totalPnL.toFixed(2)}
</p>
</div>
<div className="text-right">
<p className="text-sm text-gray-400">Win Rate</p>
<p className="text-lg font-bold text-blue-400">{winRate}%</p>
</div>
</div>
</div>
{/* Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
<div className="bg-gray-700/50 rounded p-3 text-center">
<p className="text-gray-400">Open Trades</p>
<p className="text-white font-bold text-lg">{openTrades.length}</p>
</div>
<div className="bg-gray-700/50 rounded p-3 text-center">
<p className="text-gray-400">Closed Trades</p>
<p className="text-white font-bold text-lg">{closedTrades.length}</p>
</div>
<div className="bg-gray-700/50 rounded p-3 text-center">
<p className="text-gray-400">Wins</p>
<p className="text-green-400 font-bold text-lg">
{closedTrades.filter(t => (t.pnl || 0) > 0).length}
</p>
</div>
<div className="bg-gray-700/50 rounded p-3 text-center">
<p className="text-gray-400">Losses</p>
<p className="text-red-400 font-bold text-lg">
{closedTrades.filter(t => (t.pnl || 0) < 0).length}
</p>
</div>
</div>
</div>
{/* Trading Controls */}
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
<h3 className="text-lg font-bold text-white mb-4">🎯 Safe Analysis Controls</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label className="block text-sm text-gray-400 mb-2">Symbol</label>
<select
value={symbol}
onChange={(e) => setSymbol(e.target.value)}
disabled={loading || continuousLearning}
className="w-full bg-gray-700 text-white rounded px-3 py-2 disabled:opacity-50"
>
<option value="SOLUSD">SOL/USD</option>
<option value="BTCUSD">BTC/USD</option>
<option value="ETHUSD">ETH/USD</option>
</select>
</div>
<div>
<label className="block text-sm text-gray-400 mb-2">
Continuous Learning
{continuousLearning && (
<span className="ml-2 text-xs text-green-400 font-mono bg-green-900/20 px-2 py-1 rounded">
{timeRemaining > 0 ? (
<>⏱️ Next: {formatCountdown(timeRemaining)}</>
) : (
<>🔄 Analysis running...</>
)}
</span>
)}
</label>
<div className="flex gap-2">
<button
onClick={() => {
if (continuousLearning) {
stopContinuousLearning()
setContinuousLearning(false)
// Optionally disable auto-execute when stopping learning
// setAutoExecuteTrades(false)
} else {
setContinuousLearning(true)
// AUTOMATICALLY enable auto-execute when starting learning
// This is essential for AI learning - it needs trade outcomes!
setAutoExecuteTrades(true)
console.log('🤖 Auto-enabled trade execution for AI learning - system needs outcomes to learn!')
startContinuousLearning()
}
}}
disabled={loading}
className={`flex-1 py-2 px-4 rounded-lg font-medium transition-all duration-200 ${
continuousLearning
? 'bg-red-600 hover:bg-red-700 text-white'
: 'bg-green-600 hover:bg-green-700 text-white'
} disabled:opacity-50`}
>
{continuousLearning ? '🛑 Stop Learning' : '🎓 Start Learning'}
</button>
{continuousLearning && (
<button
onClick={restartContinuousLearning}
disabled={loading}
className="py-2 px-3 rounded-lg font-medium transition-all duration-200 bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50"
title="Restart continuous learning if it seems stuck"
>
🔄
</button>
)}
<button
onClick={() => {
console.log('🔄 Force refresh: Clearing stale data and fetching fresh analysis')
localStorage.removeItem('safePaperTrading_currentAnalysis')
setCurrentAnalysis(null)
runSafeAnalysis(false)
}}
disabled={loading}
className="py-2 px-4 rounded-lg font-medium transition-all duration-200 bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50"
title="Clear stale data and get fresh analysis"
>
🔄 Fresh
</button>
</div>
{/* Auto-Execute Status - Auto-managed when learning is enabled */}
<div className="mt-4 p-3 bg-gray-800 rounded-lg border border-gray-700">
<div className="flex items-center justify-between">
<div className="flex flex-col">
<span className="text-sm font-medium text-gray-300">Auto-Execute Trades</span>
<span className="text-xs text-gray-400">
{continuousLearning
? "🤖 Auto-managed with learning - executes trades ≥60% confidence for AI feedback"
: "⚠️ Enable Continuous Learning to activate auto-execute (required for AI learning)"
}
</span>
</div>
<div className={`ml-4 px-4 py-2 rounded-lg font-medium ${
continuousLearning && autoExecuteTrades
? 'bg-green-600 text-white'
: continuousLearning
? 'bg-yellow-600 text-white'
: 'bg-gray-500 text-gray-400 opacity-50'
}`}>
{continuousLearning && autoExecuteTrades ? '🤖 AUTO-ON' : continuousLearning ? '🟡 READY' : '<27> LOCKED'}
</div>
{autoExecuteTrades && continuousLearning && (
<div className="mt-2 text-xs text-yellow-400">
⚡ Paper trades will be executed automatically when AI recommends BUY/SELL with ≥60% confidence
</div>
)}
{!continuousLearning && (
<div className="mt-2 text-xs text-blue-400 bg-blue-900/20 px-2 py-1 rounded">
💡 <strong>For AI Learning:</strong> Enable "Continuous Learning" + "Auto-Execute" so the AI can learn from virtual trade outcomes
</div>
)}
</div>
</div>
</div>
{/* Multi-Timeframe Selection */}
<div className="mb-6">
<label className="block text-sm text-gray-400 mb-3">Multi-Timeframe Analysis</label>
{/* Trading Style Presets */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 mb-4">
<button
type="button"
onClick={() => setSelectedTimeframes(['5', '15', '30'])}
disabled={loading || continuousLearning}
className="group p-4 rounded-lg bg-gradient-to-br from-green-600/20 to-emerald-600/10 border border-green-600/30 hover:border-green-500/50 transition-all duration-200 disabled:opacity-50 text-left"
>
<div className="flex items-center justify-between mb-2">
<div className="text-xl">📈</div>
<div className="text-xs text-green-400 bg-green-500/20 px-2 py-1 rounded">FAST</div>
</div>
<h4 className="text-sm font-bold text-green-300 mb-1">Scalping</h4>
<div className="text-xs text-green-400/80 font-mono">5m • 15m • 30m</div>
</button>
<button
type="button"
onClick={() => setSelectedTimeframes(['60', '120'])}
disabled={loading || continuousLearning}
className="group p-4 rounded-lg bg-gradient-to-br from-blue-600/20 to-indigo-600/10 border border-blue-600/30 hover:border-blue-500/50 transition-all duration-200 disabled:opacity-50 text-left"
>
<div className="flex items-center justify-between mb-2">
<div className="text-xl">⚡</div>
<div className="text-xs text-blue-400 bg-blue-500/20 px-2 py-1 rounded">MEDIUM</div>
</div>
<h4 className="text-sm font-bold text-blue-300 mb-1">Day Trading</h4>
<div className="text-xs text-blue-400/80 font-mono">1h • 2h</div>
</button>
<button
type="button"
onClick={() => setSelectedTimeframes(['240', 'D'])}
disabled={loading || continuousLearning}
className="group p-4 rounded-lg bg-gradient-to-br from-purple-600/20 to-violet-600/10 border border-purple-600/30 hover:border-purple-500/50 transition-all duration-200 disabled:opacity-50 text-left"
>
<div className="flex items-center justify-between mb-2">
<div className="text-xl">🎯</div>
<div className="text-xs text-purple-400 bg-purple-500/20 px-2 py-1 rounded">SLOW</div>
</div>
<h4 className="text-sm font-bold text-purple-300 mb-1">Swing Trading</h4>
<div className="text-xs text-purple-400/80 font-mono">4h • 1d</div>
</button>
</div>
{/* Individual Timeframe Toggles */}
<div className="grid grid-cols-3 md:grid-cols-7 gap-2">
{timeframes.map(tf => (
<button
key={tf.value}
onClick={() => toggleTimeframe(tf.value)}
disabled={loading || continuousLearning}
className={`py-2 px-3 rounded-lg text-sm font-medium transition-all duration-200 ${
selectedTimeframes.includes(tf.value)
? 'bg-blue-600 text-white border border-blue-500'
: 'bg-gray-700 text-gray-300 border border-gray-600 hover:bg-gray-600'
} disabled:opacity-50`}
>
{tf.label}
</button>
))}
</div>
<div className="mt-2 text-xs text-gray-500">
Selected: {selectedTimeframes.length > 0 ? selectedTimeframes.map(tf =>
timeframes.find(t => t.value === tf)?.label || tf
).join(', ') : 'None'}
{selectedTimeframes.length > 0 && (
<span className="ml-2 text-blue-400">
(Analysis delay: {Math.ceil(calculateOptimalDelay() / 60000)}m)
</span>
)}
</div>
</div>
<button
onClick={() => {
console.log('🟢 BUTTON CLICK DETECTED!')
console.log('🔍 Current state - loading:', loading, 'symbol:', symbol, 'timeframes:', selectedTimeframes)
runSafeAnalysis()
}}
disabled={loading || selectedTimeframes.length === 0}
className={`w-full py-3 px-4 rounded-lg font-medium transition-all duration-200 ${
loading
? 'bg-gray-600 text-gray-400 cursor-not-allowed'
: selectedTimeframes.length === 0
? 'bg-gray-600 text-gray-400 cursor-not-allowed'
: 'bg-blue-600 hover:bg-blue-700 text-white'
}`}
>
{loading ? '🔄 Safe Analysis Running...' :
selectedTimeframes.length === 0 ? '⚠️ Select Timeframes First' :
'🛡️ Start Safe Paper Analysis'}
</button>
{/* Force Analysis Button for Testing */}
{continuousLearning && (
<button
onClick={() => {
console.log('🧪 FORCE ANALYSIS: Manual trigger for testing')
runSafeAnalysis(true)
}}
disabled={loading}
className="w-full mt-2 py-2 px-4 rounded-lg font-medium transition-all duration-200 bg-yellow-600 hover:bg-yellow-700 text-white disabled:opacity-50"
>
🧪 Force Analysis Now (Test)
</button>
)}
<div className="mt-2 text-xs text-gray-500">
✅ Real market analysis • Paper trading only • Zero trading risk
{continuousLearning && (
<span className="block mt-1 text-green-400">
🎓 Continuous learning active - System automatically analyzes every {Math.ceil(calculateOptimalDelay() / 60000)} minutes
{timeRemaining > 0 && (
<span className="ml-2 text-green-300">
(Next: {formatCountdown(timeRemaining)})
</span>
)}
</span>
)}
</div>
{/* Clear Data Controls */}
{(currentAnalysis || paperTrades.length > 0 || analysisHistory.length > 0) && (
<div className="mt-4 pt-4 border-t border-gray-700">
<div className="flex items-center justify-between">
<div className="text-sm text-gray-400">
<p>Analysis History: {analysisHistory.length} entries</p>
<p>Paper Trades: {paperTrades.length} trades</p>
</div>
<button
onClick={() => {
if (confirm('Clear all analysis history and paper trading data? This cannot be undone.')) {
// Stop continuous learning first
if (continuousLearning) {
stopContinuousLearning()
setContinuousLearning(false)
}
setCurrentAnalysis(null)
setPaperTrades([])
setAnalysisHistory([])
setLearningInsights(null)
setPaperBalance(1000)
// Clear localStorage
localStorage.removeItem('safePaperTrading_currentAnalysis')
localStorage.removeItem('safePaperTrading_paperTrades')
localStorage.removeItem('safePaperTrading_analysisHistory')
localStorage.removeItem('safePaperTrading_learningInsights')
localStorage.removeItem('safePaperTrading_paperBalance')
localStorage.removeItem('safePaperTrading_continuousLearning')
console.log('🧹 Cleared all safe paper trading data')
}
}}
className="py-1 px-3 rounded text-xs font-medium transition-all duration-200 bg-gray-600 hover:bg-gray-500 text-gray-300"
>
🧹 Clear All Data
</button>
</div>
</div>
)}
</div>
{/* Error Display */}
{error && (
<div className="bg-red-900/30 border border-red-700 rounded-lg p-4">
<p className="text-red-400">❌ Error: {error}</p>
</div>
)}
{/* Current Analysis Results */}
{currentAnalysis && (
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
<h3 className="text-lg font-bold text-white mb-4">📊 Safe Analysis Results</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div className="bg-gray-700/50 rounded p-3">
<p className="text-gray-400 text-sm">Recommendation</p>
<p className={`font-bold text-lg ${
currentAnalysis.recommendation === 'BUY' ? 'text-green-400' :
currentAnalysis.recommendation === 'SELL' ? 'text-red-400' : 'text-yellow-400'
}`}>
{currentAnalysis.recommendation}
</p>
</div>
<div className="bg-gray-700/50 rounded p-3">
<p className="text-gray-400 text-sm">Confidence</p>
<p className="font-bold text-lg text-blue-400">{currentAnalysis.confidence}%</p>
</div>
<div className="bg-gray-700/50 rounded p-3">
<p className="text-gray-400 text-sm">Timeframes</p>
<p className="font-bold text-sm text-purple-400">
{currentAnalysis.timeframes?.map(tf =>
timeframes.find(t => t.value === tf)?.label || tf
).join(', ') || 'Single'}
</p>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div className="bg-gray-700/50 rounded p-3">
<p className="text-gray-400 text-sm">Entry Price</p>
<p className="font-bold text-lg text-white">${currentAnalysis.entry?.price?.toFixed(2) || 'N/A'}</p>
</div>
<div className="bg-gray-700/50 rounded p-3">
<p className="text-gray-400 text-sm">Analysis Mode</p>
<p className="font-bold text-sm text-indigo-400">
{currentAnalysis.analysisMode === 'CONTINUOUS_LEARNING' ? '🎓 Learning' : '👤 Manual'}
</p>
</div>
<div className="bg-gray-700/50 rounded p-3">
<p className="text-gray-400 text-sm">Primary Focus</p>
<p className="font-bold text-sm text-cyan-400">
{currentAnalysis.primaryTimeframe ?
timeframes.find(t => t.value === currentAnalysis.primaryTimeframe)?.label || currentAnalysis.primaryTimeframe
: 'N/A'}
</p>
</div>
</div>
{/* Action Buttons */}
{currentAnalysis.recommendation !== 'HOLD' && currentAnalysis.tradeDecision?.allowed && (
<div className="flex space-x-4 mb-4">
<button
onClick={() => executeSafePaperTrade('BUY')}
disabled={currentAnalysis.recommendation !== 'BUY'}
className={`flex-1 py-2 px-4 rounded font-medium ${
currentAnalysis.recommendation === 'BUY'
? 'bg-green-600 hover:bg-green-700 text-white'
: 'bg-gray-600 text-gray-400 cursor-not-allowed'
}`}
>
📄 Safe Paper BUY
</button>
<button
onClick={() => executeSafePaperTrade('SELL')}
disabled={currentAnalysis.recommendation !== 'SELL'}
className={`flex-1 py-2 px-4 rounded font-medium ${
currentAnalysis.recommendation === 'SELL'
? 'bg-red-600 hover:bg-red-700 text-white'
: 'bg-gray-600 text-gray-400 cursor-not-allowed'
}`}
>
📄 Safe Paper SELL
</button>
</div>
)}
{/* Analysis Details */}
<div className="bg-gray-700/30 rounded p-4">
<h4 className="text-white font-medium mb-2">Analysis Reasoning:</h4>
<pre className="text-gray-300 text-sm whitespace-pre-wrap">
{typeof currentAnalysis.reasoning === 'string'
? currentAnalysis.reasoning
: typeof currentAnalysis.reasoning === 'object'
? JSON.stringify(currentAnalysis.reasoning, null, 2)
: 'Analysis reasoning not available'}
</pre>
</div>
{/* Toggle Detailed Analysis */}
<button
onClick={() => setShowDetailedAnalysis(!showDetailedAnalysis)}
className="w-full mt-4 py-2 px-4 bg-purple-600 hover:bg-purple-700 text-white rounded-lg font-medium transition-all duration-200"
>
{showDetailedAnalysis ? '📊 Hide Detailed Analysis' : '🔍 Show Detailed Analysis'}
</button>
</div>
)}
{/* Detailed Market Analysis Panel */}
{currentAnalysis && showDetailedAnalysis && (
<div className="bg-gradient-to-br from-blue-900/30 to-purple-900/30 rounded-lg p-6 border border-blue-700/50">
<div className="flex items-center justify-between mb-4">
<h3 className="text-xl font-bold text-white flex items-center">
🧠 Market Summary
{currentAnalysis.timeframes && currentAnalysis.timeframes.length > 1 && (
<span className="ml-2 text-sm text-purple-400 bg-purple-500/20 px-2 py-1 rounded">
{currentAnalysis.timeframes.length} Timeframes
</span>
)}
</h3>
<div className="text-sm text-blue-300">
{currentAnalysis.analysisMode === 'CONTINUOUS_LEARNING'
? 'Continuous learning analysis with multi-timeframe insights'
: 'Comprehensive multi-layout analysis with timeframe risk assessment and cross-layout insights'
}
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
{/* Market Sentiment */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-green-400 font-medium mb-2">Market Sentiment</h4>
<p className="text-2xl font-bold text-white">{currentAnalysis.marketSentiment || 'NEUTRAL'}</p>
</div>
{/* Recommendation */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-blue-400 font-medium mb-2">Recommendation</h4>
<p className={`text-2xl font-bold ${
currentAnalysis.recommendation === 'BUY' ? 'text-green-400' :
currentAnalysis.recommendation === 'SELL' ? 'text-red-400' : 'text-yellow-400'
}`}>
{currentAnalysis.recommendation}
</p>
<p className="text-sm text-gray-300">{currentAnalysis.confidence}% confidence</p>
</div>
{/* Resistance Levels */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-red-400 font-medium mb-2">Resistance Levels</h4>
<p className="text-white font-mono">
{currentAnalysis.keyLevels?.resistance?.join(', ') ||
`$${(currentAnalysis.entry?.price * 1.02 || 164).toFixed(2)}, $${(currentAnalysis.entry?.price * 1.05 || 168).toFixed(2)}`}
</p>
</div>
{/* Support Levels */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-green-400 font-medium mb-2">Support Levels</h4>
<p className="text-white font-mono">
{currentAnalysis.keyLevels?.support?.join(', ') ||
`$${(currentAnalysis.entry?.price * 0.98 || 160).toFixed(2)}, $${(currentAnalysis.entry?.price * 0.95 || 156).toFixed(2)}`}
</p>
</div>
</div>
{/* Trading Setup */}
<div className="bg-purple-900/20 rounded-lg p-4 mb-4">
<h4 className="text-purple-300 font-medium mb-3">Trading Setup</h4>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
{/* Entry Point */}
<div>
<div className="flex items-center mb-2">
<span className="text-yellow-400 mr-2">🎯</span>
<span className="text-yellow-400 font-medium">Entry Point</span>
</div>
<p className="text-white font-mono text-lg">${currentAnalysis.entry?.price?.toFixed(2) || 'N/A'}</p>
<p className="text-sm text-gray-400">
{typeof currentAnalysis.entry?.reasoning === 'string'
? currentAnalysis.entry.reasoning
: typeof currentAnalysis.entry?.reasoning === 'object'
? JSON.stringify(currentAnalysis.entry.reasoning)
: currentAnalysis.summary || 'Real market analysis entry point'}
</p>
</div>
{/* Stop Loss */}
<div>
<div className="flex items-center mb-2">
<span className="text-red-400 mr-2">⭕</span>
<span className="text-red-400 font-medium">Stop Loss</span>
</div>
<p className="text-white font-mono text-lg">${currentAnalysis.stopLoss?.price?.toFixed(2) || 'N/A'}</p>
<p className="text-sm text-gray-400">
{typeof currentAnalysis.stopLoss?.reasoning === 'string'
? currentAnalysis.stopLoss.reasoning
: typeof currentAnalysis.stopLoss?.reasoning === 'object'
? JSON.stringify(currentAnalysis.stopLoss.reasoning)
: 'Real market analysis stop loss level'}
</p>
</div>
{/* Take Profit Targets */}
<div>
<div className="flex items-center mb-2">
<span className="text-blue-400 mr-2">💎</span>
<span className="text-blue-400 font-medium">Take Profit Targets</span>
</div>
<div className="space-y-1">
<div>
<span className="text-blue-400 font-medium">TP1: </span>
<span className="text-white font-mono">${currentAnalysis.takeProfits?.tp1?.price?.toFixed(2) || 'N/A'}</span>
</div>
{currentAnalysis.takeProfits?.tp2 && (
<div>
<span className="text-blue-400 font-medium">TP2: </span>
<span className="text-white font-mono">${currentAnalysis.takeProfits.tp2.price?.toFixed(2)}</span>
</div>
)}
</div>
<p className="text-sm text-gray-400 mt-1">
{typeof currentAnalysis.takeProfits?.reasoning === 'string'
? currentAnalysis.takeProfits.reasoning
: typeof currentAnalysis.takeProfits?.reasoning === 'object'
? JSON.stringify(currentAnalysis.takeProfits.reasoning)
: 'Real market analysis target levels'}
</p>
</div>
</div>
</div>
{/* Risk Management */}
<div className="bg-gray-800/40 rounded-lg p-4">
<h4 className="text-orange-400 font-medium mb-3">Risk Management</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div className="flex items-center justify-between mb-2">
<span className="text-gray-300">Risk/Reward Ratio</span>
<span className="text-orange-400 font-bold">
{currentAnalysis.riskToReward || 'N/A'}
</span>
</div>
<div className="flex items-center mb-2">
<span className="text-yellow-400 mr-2">⚠️</span>
<span className="text-yellow-400 font-medium">Confirmation Trigger</span>
</div>
<p className="text-gray-300 text-sm">
{typeof currentAnalysis.confirmationTrigger === 'string'
? currentAnalysis.confirmationTrigger
: typeof currentAnalysis.confirmationTrigger === 'object'
? JSON.stringify(currentAnalysis.confirmationTrigger)
: 'Real market confirmation signals from analysis'}
</p>
</div>
<div>
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-gray-400">Trend:</span>
<span className="text-white">
{typeof currentAnalysis.trendAnalysis === 'object'
? (currentAnalysis.trendAnalysis?.direction || 'Analyzing...')
: currentAnalysis.trendAnalysis || 'Analyzing...'}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Momentum:</span>
<span className="text-white">
{typeof currentAnalysis.momentumAnalysis === 'object'
? (currentAnalysis.momentumAnalysis?.status || 'Analyzing...')
: currentAnalysis.momentumAnalysis || 'Analyzing...'}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Volume:</span>
<span className="text-white">
{typeof currentAnalysis.volumeAnalysis === 'object'
? (currentAnalysis.volumeAnalysis?.trend || 'Analyzing...')
: currentAnalysis.volumeAnalysis || 'Analyzing...'}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Timeframe Risk:</span>
<span className="text-white">
{typeof currentAnalysis.timeframeRisk === 'object'
? (currentAnalysis.timeframeRisk?.assessment || 'Medium')
: currentAnalysis.timeframeRisk || 'Medium'}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
)}
{/* AI Learning Insights Panel */}
{learningInsights && (
<div className="bg-gradient-to-br from-indigo-900/30 to-purple-900/30 rounded-lg p-6 border border-indigo-700/50">
<h3 className="text-xl font-bold text-white mb-4 flex items-center">
🧠 AI Learning Insights
<span className="ml-2 text-sm text-indigo-300">Real-time learning from trade outcomes</span>
</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
{/* Learning Status */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-indigo-400 font-medium mb-2">Learning Status</h4>
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-gray-400">Total Decisions:</span>
<span className="text-white font-bold">{learningInsights.status?.totalDecisions || 0}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Success Rate:</span>
<span className="text-green-400 font-bold">
{((learningInsights.status?.successRate || 0) * 100).toFixed(1)}%
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Paper Trades:</span>
<span className="text-blue-400 font-bold">{learningInsights.totalTrades || 0}</span>
</div>
</div>
</div>
{/* Win/Loss Analysis */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-green-400 font-medium mb-2">Trade Outcome</h4>
{learningInsights.lastTrade ? (
<div className="space-y-2">
<div className={`flex items-center ${learningInsights.lastTrade.isWinner ? 'text-green-400' : 'text-red-400'}`}>
<span className="mr-2">{learningInsights.lastTrade.isWinner ? '✅' : '❌'}</span>
<span className="font-bold">
{learningInsights.lastTrade.isWinner ? 'WINNER' : 'LOSER'}
</span>
</div>
<div className="text-sm text-gray-400">
Last: {learningInsights.lastTrade.symbol} ${learningInsights.lastTrade.pnl?.toFixed(2)}
</div>
<div className="text-sm text-gray-400">
Confidence: {learningInsights.lastTrade.confidence}%
</div>
</div>
) : (
<p className="text-gray-400 text-sm">No trades yet</p>
)}
</div>
{/* Current Adjustments */}
<div className="bg-gray-800/60 rounded-lg p-4">
<h4 className="text-purple-400 font-medium mb-2">AI Adjustments</h4>
<div className="space-y-1">
{learningInsights.status?.nextTradeAdjustments?.slice(0, 3).map((adjustment, index) => (
<div key={index} className="text-xs text-gray-300 flex items-start">
<span className="text-purple-400 mr-1">•</span>
<span>{adjustment}</span>
</div>
)) || (
<p className="text-gray-400 text-sm">Analyzing patterns...</p>
)}
</div>
</div>
</div>
{/* Learning Reflection */}
{learningInsights.learningPoints && learningInsights.learningPoints.length > 0 && (
<div className="bg-gray-800/40 rounded-lg p-4">
<h4 className="text-indigo-300 font-medium mb-3">AI Reflection & Learning</h4>
<div className="space-y-3">
{learningInsights.learningPoints.slice(-3).map((point, index) => (
<div key={index} className={`p-3 rounded border-l-4 ${
point.impact === 'POSITIVE' ? 'bg-green-900/20 border-green-500' : 'bg-red-900/20 border-red-500'
}`}>
<div className="flex items-center justify-between mb-1">
<span className={`text-sm font-medium ${
point.impact === 'POSITIVE' ? 'text-green-400' : 'text-red-400'
}`}>
{point.impact === 'POSITIVE' ? '📈 Positive Learning' : '📉 Learning from Loss'}
</span>
<span className="text-xs text-gray-500">
{new Date(point.timestamp).toLocaleTimeString()}
</span>
</div>
<p className="text-gray-300 text-sm">{point.insight}</p>
</div>
))}
</div>
</div>
)}
{/* What AI is Using for Next Trade */}
<div className="bg-blue-900/20 rounded-lg p-4 mt-4">
<h4 className="text-blue-300 font-medium mb-3">🔮 AI Database for Next Trade</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<h5 className="text-blue-400 text-sm font-medium mb-2">Current Thresholds:</h5>
<div className="space-y-1 text-xs">
<div className="flex justify-between">
<span className="text-gray-400">Emergency Distance:</span>
<span className="text-white">{learningInsights.status?.currentThresholds?.emergency || 0.5}%</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Risk Distance:</span>
<span className="text-white">{learningInsights.status?.currentThresholds?.risk || 1.5}%</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Min Confidence:</span>
<span className="text-white">{learningInsights.status?.currentThresholds?.confidence || 75}%</span>
</div>
</div>
</div>
<div>
<h5 className="text-blue-400 text-sm font-medium mb-2">Pattern Recognition:</h5>
<div className="space-y-1 text-xs text-gray-300">
<div>• {symbol} multi-timeframe: {learningInsights.status?.totalDecisions || 0} total decisions in database</div>
<div>• Success rate: {((learningInsights.status?.successRate || 0) * 100).toFixed(1)}%</div>
<div>• Learning phase: {learningInsights.status?.phase || 'INITIALIZATION'}</div>
<div>• Days active: {learningInsights.status?.daysActive || 0} days</div>
{currentAnalysis?.timeframes && currentAnalysis.timeframes.length > 1 && (
<div>• Current analysis: {currentAnalysis.timeframes.map(tf =>
timeframes.find(t => t.value === tf)?.label || tf
).join(' + ')} confluence</div>
)}
</div>
</div>
</div>
</div>
</div>
)}
{/* Open Trades */}
{openTrades.length > 0 && (
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
<h3 className="text-lg font-bold text-white mb-4">📈 Open Paper Positions</h3>
<div className="space-y-3">
{openTrades.map(trade => (
<div key={trade.id} className="bg-gray-700/50 rounded p-4 flex justify-between items-center">
<div className="flex-1">
<div className="flex items-center space-x-4">
<span className={`px-2 py-1 rounded text-xs font-medium ${
trade.side === 'BUY' ? 'bg-green-600 text-white' : 'bg-red-600 text-white'
}`}>
{trade.side}
</span>
<span className="text-white font-medium">{trade.symbol}</span>
<span className="text-gray-400">${trade.entryPrice}</span>
<span className="text-gray-400">Size: ${trade.positionSize?.toFixed(2)}</span>
</div>
<div className="text-xs text-gray-400 mt-1">
Entry: {new Date(trade.timestamp).toLocaleString()} |
Confidence: {trade.confidence}%
</div>
</div>
<button
onClick={() => {
const exitPrice = prompt(`Exit price for ${trade.symbol}:`, trade.entryPrice)
if (exitPrice) closeSafePaperTrade(trade.id, parseFloat(exitPrice))
}}
className="bg-yellow-600 hover:bg-yellow-700 text-white px-3 py-1 rounded text-sm"
>
Close
</button>
</div>
))}
</div>
</div>
)}
{/* Trade History */}
{closedTrades.length > 0 && (
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
<div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-bold text-white">📈 Safe Paper Trade History</h3>
<button
onClick={resetSafePaperTrading}
className="bg-red-600 hover:bg-red-700 text-white px-3 py-2 rounded text-sm"
>
Reset All Data
</button>
</div>
<div className="space-y-2 max-h-96 overflow-y-auto">
{closedTrades.slice(0, 20).map(trade => (
<div key={trade.id} className={`p-3 rounded border-l-4 ${
(trade.pnl || 0) >= 0 ? 'bg-green-900/20 border-green-500' : 'bg-red-900/20 border-red-500'
}`}>
<div className="flex justify-between items-center">
<div className="flex items-center space-x-4">
<span className={`px-2 py-1 rounded text-xs font-medium ${
trade.side === 'BUY' ? 'bg-green-600 text-white' : 'bg-red-600 text-white'
}`}>
{trade.side}
</span>
<span className="text-white">{trade.symbol}</span>
<span className="text-gray-400">${trade.entryPrice} → ${trade.exitPrice}</span>
<span className={`font-medium ${
(trade.pnl || 0) >= 0 ? 'text-green-400' : 'text-red-400'
}`}>
${(trade.pnl || 0).toFixed(2)}
</span>
<span className={`text-xs px-2 py-1 rounded ${
trade.isWinner ? 'bg-green-600 text-white' : 'bg-red-600 text-white'
}`}>
{trade.isWinner ? 'WIN' : 'LOSS'}
</span>
</div>
</div>
<div className="text-xs text-gray-400 mt-1">
{new Date(trade.timestamp).toLocaleDateString()} | Confidence: {trade.confidence}%
</div>
</div>
))}
</div>
</div>
)}
{/* Analysis History Panel */}
{analysisHistory.length > 0 && (
<div className="bg-gradient-to-br from-gray-800/30 to-gray-900/30 rounded-lg p-6 border border-gray-700/50">
<div className="flex items-center justify-between mb-4">
<h3 className="text-xl font-bold text-white flex items-center">
📊 Analysis History
<span className="ml-2 text-sm text-gray-400 bg-gray-700/50 px-2 py-1 rounded">
{analysisHistory.length} entries
</span>
</h3>
<span className="text-sm text-gray-400">Recent analyses are automatically saved</span>
</div>
<div className="space-y-3 max-h-96 overflow-y-auto">
{analysisHistory.map((analysis, index) => (
<div key={analysis.analysisId || index} className="bg-gray-800/60 rounded-lg p-4 border border-gray-700">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center space-x-3">
<span className={`text-lg font-bold ${
analysis.recommendation === 'BUY' ? 'text-green-400' :
analysis.recommendation === 'SELL' ? 'text-red-400' : 'text-yellow-400'
}`}>
{analysis.recommendation}
</span>
<span className="text-blue-400 font-bold">{analysis.confidence}%</span>
<span className="text-sm text-gray-400">
{analysis.symbol} • {analysis.timeframes?.join(', ')}
</span>
</div>
<div className="text-xs text-gray-500">
{new Date(analysis.timestamp).toLocaleString()}
</div>
</div>
<div className="grid grid-cols-3 gap-4 text-sm">
<div>
<span className="text-gray-400">Entry: </span>
<span className="text-white font-mono">${analysis.entry?.price?.toFixed(2) || 'N/A'}</span>
</div>
<div>
<span className="text-gray-400">Stop: </span>
<span className="text-white font-mono">${analysis.stopLoss?.price?.toFixed(2) || 'N/A'}</span>
</div>
<div>
<span className="text-gray-400">Target: </span>
<span className="text-white font-mono">${analysis.takeProfits?.tp1?.price?.toFixed(2) || 'N/A'}</span>
</div>
</div>
{analysis.analysisType === 'CONTINUOUS_LEARNING' && (
<div className="mt-2 text-xs text-purple-400 flex items-center">
🎓 <span className="ml-1">Continuous learning analysis</span>
</div>
)}
</div>
))}
</div>
</div>
)}
</div>
)
}