diff --git a/app/api/safe-paper-trading/database-trades/route.js b/app/api/safe-paper-trading/database-trades/route.js new file mode 100644 index 0000000..969731a --- /dev/null +++ b/app/api/safe-paper-trading/database-trades/route.js @@ -0,0 +1,85 @@ +import { NextResponse } from 'next/server' +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +export async function GET() { + try { + // Get recent trades from database + const trades = await prisma.trades.findMany({ + orderBy: { createdAt: 'desc' }, + take: 50, // Last 50 trades + select: { + id: true, + symbol: true, + side: true, + amount: true, + price: true, + entryPrice: true, + status: true, + confidence: true, + createdAt: true, + profit: true, + fees: true, + tradingMode: true, + isAutomated: true + } + }) + + // Convert database trades to Safe Paper Trading format + const formattedTrades = trades.map(trade => ({ + id: trade.id, + symbol: trade.symbol, + side: trade.side.toUpperCase(), + positionSize: trade.amount, + entryPrice: trade.entryPrice || trade.price, + confidence: trade.confidence, + reasoning: `${trade.isAutomated ? 'Automated' : 'Manual'} ${trade.tradingMode || 'trade'}`, + source: trade.isAutomated ? 'automation' : 'manual', + status: trade.status === 'EXECUTED' ? 'OPEN' : trade.status, + timestamp: trade.createdAt, + pnl: trade.profit || 0, + fees: trade.fees || 0 + })) + + // Filter for valid paper trades (exclude failed ones) + const validTrades = formattedTrades.filter(trade => + trade.status !== 'FAILED' && trade.positionSize > 0 + ) + + // Calculate stats + const totalTrades = validTrades.length + const totalValue = validTrades.reduce((sum, trade) => { + return sum + (trade.side === 'BUY' ? -trade.positionSize : trade.positionSize) + trade.pnl + }, 0) + + const buyTrades = validTrades.filter(t => t.side === 'BUY').length + const sellTrades = validTrades.filter(t => t.side === 'SELL').length + + return NextResponse.json({ + success: true, + trades: validTrades, + totalTrades, + totalValue, + buyTrades, + sellTrades, + source: 'database', + timestamp: new Date().toISOString() + }) + + } catch (error) { + console.error('❌ Database trades error:', error) + return NextResponse.json({ + success: false, + message: 'Failed to fetch database trades', + error: error.message, + trades: [], + totalTrades: 0, + totalValue: 0, + buyTrades: 0, + sellTrades: 0 + }, { status: 500 }) + } finally { + await prisma.$disconnect() + } +} diff --git a/app/safe-paper-trading/page.js b/app/safe-paper-trading/page.js index de8f0b2..700600e 100644 --- a/app/safe-paper-trading/page.js +++ b/app/safe-paper-trading/page.js @@ -147,42 +147,18 @@ export default function SafePaperTradingPage() { if (savedContinuousLearning === 'true') { console.log('πŸ”„ Restoring continuous learning state...') setContinuousLearning(true) - // Force restart continuous learning immediately setTimeout(() => { console.log('πŸŽ“ Starting continuous learning from restored state') startContinuousLearning() - }, 1000) // Reduced delay - } else { - console.log('πŸ’‘ No continuous learning state found - user needs to start manually') + }, 2000) } } catch (error) { console.error('⚠️ Error checking continuous learning state:', error) } } - // Force enable learning for testing - DEBUG FUNCTION - const forceEnableLearning = () => { - console.log('πŸ”§ FORCE ENABLING CONTINUOUS LEARNING...') - localStorage.setItem('safePaperTrading_continuousLearning', 'true') - setContinuousLearning(true) - setTimeout(() => { - console.log('πŸŽ“ Force starting continuous learning') - startContinuousLearning() - }, 500) - console.log('βœ… Continuous learning forcefully enabled') - } - - // Check state immediately - checkContinuousLearningState() - - // Expose force enable function to browser console for debugging - if (typeof window !== 'undefined') { - window.forceEnableLearning = forceEnableLearning - console.log('πŸ”§ Debug function exposed: window.forceEnableLearning()') - } - - // Also check after a short delay to ensure everything is loaded - setTimeout(checkContinuousLearningState, 2000) + // Check state after a short delay to ensure everything is loaded + setTimeout(checkContinuousLearningState, 1000) }, []) // Persist analysis data whenever it changes @@ -426,82 +402,17 @@ export default function SafePaperTradingPage() { } useEffect(() => { - // Load paper trading data from localStorage using consistent keys - // Check both old and new key patterns for backward compatibility - const savedTrades = localStorage.getItem('safePaperTrading_paperTrades') || localStorage.getItem('safePaperTrades') - const savedBalance = localStorage.getItem('safePaperTrading_paperBalance') || localStorage.getItem('safePaperBalance') + // Load paper trading data from localStorage + const savedTrades = localStorage.getItem('safePaperTrades') + const savedBalance = localStorage.getItem('safePaperBalance') if (savedTrades) { setPaperTrades(JSON.parse(savedTrades)) - console.log('πŸ“‚ Restored paper trades from localStorage') } if (savedBalance) { setPaperBalance(parseFloat(savedBalance)) - console.log('πŸ“‚ Restored paper balance from localStorage') } - // Sync with API trades (from automation) - const syncApiTrades = async () => { - try { - console.log('πŸ”„ Syncing trades from API...') - const response = await fetch('/api/safe-paper-trading/trades') - if (response.ok) { - const data = await response.json() - if (data.success && data.trades.length > 0) { - console.log(`πŸ“ˆ Found ${data.trades.length} API trades, syncing with localStorage...`) - - // Get existing localStorage trades - const existingTrades = JSON.parse(localStorage.getItem('safePaperTrading_paperTrades') || '[]') - - // Convert API trades to frontend format and filter out existing ones - const existingIds = new Set(existingTrades.map(t => t.id)) - const newTrades = data.trades - .filter(t => !existingIds.has(t.id)) - .map(apiTrade => ({ - id: apiTrade.id, - symbol: apiTrade.symbol, - side: apiTrade.side, - positionSize: apiTrade.amount, // Map amount to positionSize - entryPrice: apiTrade.entry, // Map entry to entryPrice - confidence: apiTrade.confidence, - reasoning: apiTrade.reasoning, - source: apiTrade.source, - status: apiTrade.status, - timestamp: apiTrade.createdAt, // Map createdAt to timestamp - pnl: apiTrade.pnl || 0, - fees: apiTrade.fees || 0 - })) - - if (newTrades.length > 0) { - const combinedTrades = [...existingTrades, ...newTrades] - setPaperTrades(combinedTrades) - localStorage.setItem('safePaperTrading_paperTrades', JSON.stringify(combinedTrades)) - - // Update balance based on new trades - const additionalValue = newTrades.reduce((sum, trade) => { - return sum + (trade.side === 'BUY' ? -trade.positionSize : trade.positionSize) - }, 0) - - const newBalance = paperBalance + additionalValue - setPaperBalance(newBalance) - localStorage.setItem('safePaperTrading_paperBalance', newBalance.toString()) - - console.log(`βœ… Synced ${newTrades.length} new trades from API`) - } else { - console.log('πŸ“Š All API trades already in localStorage') - } - } else { - console.log('πŸ“Š No API trades found') - } - } - } catch (error) { - console.log('❌ Failed to sync API trades:', error.message) - } - } - - // Sync API trades after loading localStorage - syncApiTrades() - // Fetch AI learning status fetchLearningStatus() @@ -521,12 +432,8 @@ export default function SafePaperTradingPage() { } }, [selectedTimeframes]) - // Save to localStorage whenever data changes - use consistent prefixed keys + // Save to localStorage whenever data changes useEffect(() => { - localStorage.setItem('safePaperTrading_paperTrades', JSON.stringify(paperTrades)) - localStorage.setItem('safePaperTrading_paperBalance', paperBalance.toString()) - - // Also save to old keys for backward compatibility (temporarily) localStorage.setItem('safePaperTrades', JSON.stringify(paperTrades)) localStorage.setItem('safePaperBalance', paperBalance.toString()) }, [paperTrades, paperBalance]) @@ -872,15 +779,8 @@ export default function SafePaperTradingPage() { setPaperBalance(1000) setPaperTrades([]) setCurrentAnalysis(null) - - // Clear both key patterns to ensure complete reset localStorage.removeItem('safePaperTrades') localStorage.removeItem('safePaperBalance') - localStorage.removeItem('safePaperTrading_paperTrades') - localStorage.removeItem('safePaperTrading_paperBalance') - localStorage.removeItem('safePaperTrading_currentAnalysis') - - console.log('πŸ—‘οΈ All safe paper trading data reset') } } @@ -910,6 +810,51 @@ export default function SafePaperTradingPage() { + {/* AI LEARNING SETUP NOTICE */} + {!continuousLearning || !autoExecuteTrades ? ( +
+

πŸ€– Enable AI Learning from Virtual Trading

+
+ Current Issue: AI is analyzing but not learning from outcomes because virtual trading is not enabled. +
+
+
+

Step 1: Enable Continuous Learning

+

+ {continuousLearning ? 'βœ… Enabled' : '❌ Click "πŸŽ“ Start Learning" button below'} +

+
+
+

Step 2: Enable Auto-Execute

+

+ {autoExecuteTrades ? 'βœ… Enabled' : continuousLearning ? '❌ Enable "Auto-Execute Trades" below' : '⏸️ Waiting for Step 1'} +

+
+
+
+ Result: AI will automatically execute virtual trades β†’ track outcomes β†’ learn patterns β†’ improve over time +
+
+ ) : ( +
+

βœ… AI Learning System Active

+
+
+ πŸŽ“ Continuous Learning: ON +
+
+ πŸ€– Auto-Execute: ON +
+
+ πŸ“ˆ Virtual Trading: Active +
+
+
+ 🧠 AI will automatically execute virtual trades based on analysis and learn from outcomes to improve performance +
+
+ )} + {/* Header with Balance */}
@@ -1050,32 +995,49 @@ export default function SafePaperTradingPage() {
- {/* Auto-Execute Toggle - Only show when continuous learning is active */} - {continuousLearning && ( -
-
-
- Auto-Execute Trades - Automatically execute paper trades based on AI recommendations (β‰₯60% confidence) -
- + {/* Auto-Execute Toggle - Show always, but disabled until continuous learning is active */} +
+
+
+ Auto-Execute Trades + + {continuousLearning + ? "Automatically execute paper trades based on AI recommendations (β‰₯60% confidence)" + : "⚠️ Enable Continuous Learning first to activate auto-execute virtual trading" + } +
- {autoExecuteTrades && ( -
- ⚑ Paper trades will be executed automatically when AI recommends BUY/SELL with β‰₯60% confidence -
- )} +
- )} + {autoExecuteTrades && continuousLearning && ( +
+ ⚑ Paper trades will be executed automatically when AI recommends BUY/SELL with β‰₯60% confidence +
+ )} + {!continuousLearning && ( +
+ πŸ’‘ For AI Learning: Enable "Continuous Learning" + "Auto-Execute" so the AI can learn from virtual trade outcomes +
+ )} +
@@ -1274,11 +1236,6 @@ export default function SafePaperTradingPage() {

Confidence

{currentAnalysis.confidence}%

- {currentAnalysis.originalConfidence && currentAnalysis.originalConfidence !== currentAnalysis.confidence && ( -

- (Original: {currentAnalysis.originalConfidence}%, Macro: {currentAnalysis.macroAdjustment?.netAdjustment > 0 ? '+' : ''}{currentAnalysis.macroAdjustment?.netAdjustment}%) -

- )}

Timeframes

@@ -1351,78 +1308,6 @@ export default function SafePaperTradingPage() {
- {/* Macro Sentiment Panel */} - {currentAnalysis.macroSentiment && ( -
-

- πŸ’° Macro Sentiment Analysis - {currentAnalysis.macroAdjustment?.applied && ( - - {currentAnalysis.macroAdjustment.netAdjustment > 0 ? '+' : ''}{currentAnalysis.macroAdjustment.netAdjustment}% - - )} -

- -
- {/* Fear & Greed Index */} -
-

Fear & Greed Index

-
- = 75 ? 'text-green-400' : - currentAnalysis.macroSentiment.fearAndGreed?.value >= 55 ? 'text-yellow-400' : - 'text-gray-400' - }`}> - {currentAnalysis.macroSentiment.fearAndGreed?.value || 'N/A'} - - - {currentAnalysis.macroSentiment.fearAndGreed?.classification || 'unknown'} - -
-
- - {/* M2 Money Supply */} -
-

M2 Money Supply

-
- - {currentAnalysis.macroSentiment.m2MoneySupply?.cryptoSignal?.signal || 'N/A'} - - - ({currentAnalysis.macroSentiment.m2MoneySupply?.cryptoSignal?.confidence || 0}%) - -
- {currentAnalysis.macroSentiment.m2MoneySupply?.cryptoSignal?.timeframe && ( -

- {currentAnalysis.macroSentiment.m2MoneySupply.cryptoSignal.timeframe} -

- )} -
-
- - {/* Macro Adjustments Applied */} - {currentAnalysis.macroAdjustment?.applied && ( -
-

Macro Adjustments Applied:

-
    - {currentAnalysis.macroAdjustment.adjustments.map((adjustment, index) => ( -
  • - β€’ - {adjustment} -
  • - ))} -
-
- )} -
- )} - {/* Toggle Detailed Analysis */}