From e3eff629a3dbbec77f8b2acc0624aaf2220b9a96 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Sat, 26 Jul 2025 10:40:05 +0200 Subject: [PATCH] Fix: Resolve SL Learner database errors and enhance automation - Fixed Prisma schema: Added @default(cuid()) to ai_learning_data.id field - Fixed all updatedAt fields: Added @updatedAt decorators across all models - Enhanced position-aware automation with intelligent DCA/doubling down logic - Added safe automation starter script with position awareness - Resolved 'Argument id is missing' database creation errors - All AI learning data can now be created without Prisma errors Database schema now properly auto-generates IDs and timestamps for: - ai_learning_data records - All model updatedAt fields - Prevents Enhanced Risk Manager database failures --- lib/position-aware-automation.js | 248 ++++++++++++++++++++++++++++++- prisma/prisma/dev.db | Bin 3215360 -> 3215360 bytes prisma/schema.prisma | 16 +- start-automation-safe.js | 87 +++++++++++ 4 files changed, 336 insertions(+), 15 deletions(-) create mode 100755 start-automation-safe.js diff --git a/lib/position-aware-automation.js b/lib/position-aware-automation.js index eef209b..b146c08 100644 --- a/lib/position-aware-automation.js +++ b/lib/position-aware-automation.js @@ -235,14 +235,248 @@ class PositionAwareAutomation { console.log(`πŸ’° Current PnL: $${positionData.position.unrealizedPnl}`); console.log(`🎯 Distance to SL: ${positionData.stopLossProximity.distancePercent}%`); - // Here you would run your analysis to decide: - // 1. Close position early - // 2. Move stop loss - // 3. Double down - // 4. Do nothing + try { + // Run AI analysis to determine market reversal potential + const analysis = await this.runAIAnalysisForDCA(positionData); + + if (analysis && analysis.recommendation === 'DCA_DOUBLE_DOWN') { + console.log('🎯 AI DECISION: Market showing reversal signs - DOUBLING DOWN'); + console.log(`πŸ“ˆ Confidence: ${analysis.confidence}%`); + console.log(`πŸ’° DCA Amount: ${analysis.dcaAmount} SOL`); + console.log(`🎯 New Average: $${analysis.newAveragePrice}`); + + // Execute DCA trade + await this.executeDCATradeAction(analysis, positionData); + + } else if (analysis && analysis.recommendation === 'CLOSE_EARLY') { + console.log('πŸ›‘ AI DECISION: No reversal signs - CLOSING EARLY to minimize loss'); + console.log(`πŸ“‰ Confidence: ${analysis.confidence}%`); + + // Execute early close + await this.executeEarlyCloseAction(positionData); + + } else { + console.log('⏸️ AI DECISION: HOLD position - unclear signals'); + console.log('⏰ Will re-analyze in 30 seconds'); + } + + } catch (error) { + console.error('❌ Emergency analysis failed:', error); + console.log('⏰ Next check in 30 seconds due to high risk'); + } + } + + async runAIAnalysisForDCA(positionData) { + console.log('🧠 Running AI DCA Analysis...'); - console.log('πŸ€– ANALYSIS DECISION: [Would run AI analysis here]'); - console.log('⏰ Next check in 30 seconds due to high risk'); + try { + // Get fresh market analysis + const response = await fetch('http://localhost:3000/api/analysis-optimized', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + symbol: positionData.position.symbol.replace('-PERP', 'USD'), + timeframes: ['5', '15', '1h'], + layouts: ['ai'], + analyze: true, + dcaMode: true, // Special DCA analysis mode + currentPosition: positionData.position + }) + }); + + if (!response.ok) { + throw new Error(`Analysis failed: ${response.status}`); + } + + const analysisData = await response.json(); + const analysis = analysisData.analysis; + + if (!analysis) { + console.log('❌ No analysis returned'); + return null; + } + + // Determine DCA strategy based on AI analysis + const dcaDecision = this.evaluateDCAOpportunity(analysis, positionData); + + return dcaDecision; + + } catch (error) { + console.error('❌ AI DCA analysis failed:', error); + return null; + } + } + + evaluateDCAOpportunity(analysis, positionData) { + const currentPrice = positionData.position.currentPrice; + const entryPrice = positionData.position.entryPrice; + const unrealizedPnl = positionData.position.unrealizedPnl; + const confidence = analysis.confidence || 0; + + // Calculate price movement from entry + const priceMovement = ((currentPrice - entryPrice) / entryPrice) * 100; + const isLongPosition = positionData.position.side === 'long'; + + console.log(`πŸ“Š DCA Evaluation:`); + console.log(` Price Movement: ${priceMovement.toFixed(2)}%`); + console.log(` AI Confidence: ${confidence}%`); + console.log(` Analysis: ${analysis.recommendation}`); + + // DCA Logic for LONG positions + if (isLongPosition) { + // Price has dropped significantly (good DCA opportunity) + const hasDropped = priceMovement < -2; // 2%+ drop + const aiSaysBuy = analysis.recommendation?.toLowerCase().includes('buy'); + const highConfidence = confidence > 75; + const oversoldSignals = analysis.technicalIndicators?.rsi < 35; // Oversold + + if (hasDropped && aiSaysBuy && highConfidence) { + const dcaAmount = this.calculateDCAAmount(positionData); + const newAveragePrice = this.calculateNewAveragePrice( + positionData.position.size, + entryPrice, + dcaAmount, + currentPrice + ); + + return { + recommendation: 'DCA_DOUBLE_DOWN', + confidence: confidence, + dcaAmount: dcaAmount, + newAveragePrice: newAveragePrice, + reasoning: `AI detects reversal: ${analysis.reasoning || 'Strong buy signal'}` + }; + } + } + + // DCA Logic for SHORT positions + if (!isLongPosition) { + // Price has risen significantly (good DCA opportunity for shorts) + const hasRisen = priceMovement > 2; // 2%+ rise + const aiSaysSell = analysis.recommendation?.toLowerCase().includes('sell'); + const highConfidence = confidence > 75; + const overboughtSignals = analysis.technicalIndicators?.rsi > 65; // Overbought + + if (hasRisen && aiSaysSell && highConfidence) { + const dcaAmount = this.calculateDCAAmount(positionData); + const newAveragePrice = this.calculateNewAveragePrice( + positionData.position.size, + entryPrice, + dcaAmount, + currentPrice + ); + + return { + recommendation: 'DCA_DOUBLE_DOWN', + confidence: confidence, + dcaAmount: dcaAmount, + newAveragePrice: newAveragePrice, + reasoning: `AI detects short opportunity: ${analysis.reasoning || 'Strong sell signal'}` + }; + } + } + + // If no DCA opportunity but low confidence, suggest early close + if (confidence < 40 && Math.abs(unrealizedPnl) > 20) { + return { + recommendation: 'CLOSE_EARLY', + confidence: 100 - confidence, // Inverse confidence for closing + reasoning: 'Low AI confidence + significant loss suggests early exit' + }; + } + + return { + recommendation: 'HOLD', + confidence: confidence, + reasoning: 'No clear DCA or exit signals' + }; + } + + calculateDCAAmount(positionData) { + // Calculate safe DCA amount (max 50% of current position) + const currentSize = positionData.position.size; + const maxDCASize = currentSize * 0.5; // Max 50% of current position + + // Could also factor in available balance, but for now use conservative 50% + return Math.min(maxDCASize, 2.0); // Cap at 2 SOL for safety + } + + calculateNewAveragePrice(currentSize, currentEntryPrice, dcaAmount, dcaPrice) { + const totalValue = (currentSize * currentEntryPrice) + (dcaAmount * dcaPrice); + const totalSize = currentSize + dcaAmount; + return totalValue / totalSize; + } + + async executeDCATradeAction(analysis, positionData) { + console.log('🎯 EXECUTING DCA TRADE...'); + + try { + const tradeParams = { + symbol: positionData.position.symbol, + side: positionData.position.side === 'long' ? 'BUY' : 'SELL', + amount: analysis.dcaAmount, + orderType: 'MARKET', + leverage: 10, // Use moderate leverage for DCA + stopLoss: 1.0, + takeProfit: 3.0, + isExecution: true, + dcaMode: true, + analysis: analysis + }; + + const response = await fetch('http://localhost:3000/api/trading/execute', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(tradeParams) + }); + + const result = await response.json(); + + if (result.success) { + console.log('βœ… DCA TRADE EXECUTED SUCCESSFULLY!'); + console.log(`πŸ’° Added ${analysis.dcaAmount} SOL to position`); + console.log(`πŸ“Š New Average Price: $${analysis.newAveragePrice.toFixed(4)}`); + } else { + console.error('❌ DCA trade failed:', result.error); + } + + } catch (error) { + console.error('❌ Error executing DCA trade:', error); + } + } + + async executeEarlyCloseAction(positionData) { + console.log('πŸ›‘ EXECUTING EARLY CLOSE...'); + + try { + const closeParams = { + symbol: positionData.position.symbol, + side: positionData.position.side === 'long' ? 'SELL' : 'BUY', + amount: positionData.position.size, + orderType: 'MARKET', + isExecution: true, + earlyClose: true, + reason: 'Emergency early close due to low AI confidence' + }; + + const response = await fetch('http://localhost:3000/api/trading/execute', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(closeParams) + }); + + const result = await response.json(); + + if (result.success) { + console.log('βœ… POSITION CLOSED EARLY'); + console.log(`πŸ’° Final P&L: ${positionData.position.unrealizedPnl >= 0 ? '+' : ''}$${positionData.position.unrealizedPnl.toFixed(2)}`); + } else { + console.error('❌ Early close failed:', result.error); + } + + } catch (error) { + console.error('❌ Error executing early close:', error); + } } async stop() { diff --git a/prisma/prisma/dev.db b/prisma/prisma/dev.db index 74467d52771f30dbc858063e5c448a7dc474e518..1f487704717d15918a2e166c1f749dfd573eb0df 100644 GIT binary patch delta 587 zcmZwDJ8V*66bJC{qd?)_mY1}EK*8$+v~u}yp*pl0)42GkI(0B90*%FTLAg|mA+{>H zi;Zp6eAc9e8n+rkV(g7h)O4|l(Zt=@#L2-$69*Un#Kg(rcXG~f9yxQ3EjkB_e!9FA zI7yf1Ctgj^*Q@-8!1|4Z7^*zqltZ1Ym%o1-4r%2&1p{<}5lmo)Zm@tA1Q4MIdcg*E zaDWqBunXMK2mRmyFZf_L_#ps67=X_1Fzf*d_QF2c4+r#eJ@O!Io~7f&zQez?oC7@C z4*%x07xFNF)Rc!kN^V*yF_t)5oKEDf9m!->H9c!s(Ka?C5QT$q2nOM>zOflQ``OqT z$d9+I5@!v0%VAr$-M8f_r#I=iuplT)CxYC+CZFOikzL~Rt+-qNv?f36;l+3HK7LnZ zQSPZzueRNk_3dUndA?itM#|Jrc%@~XX zbCpV}m}9tlW~h8)=yD-DIg>7RE$YujmiuY2th{u#7c93G&EXme5i*!WDGF?zIQ|eSfDM{7Dm5b+2$Hqo4jL|2fJM~|G XN$Mn!|{e#^?{|W5WwR)BBUFv{??0WJbl{3Zs1bHqGu&>8qnlHjBh@{4P-| zqFAw9)Ok>qLbl9+2MbtX0Bm4~K@dO$2ROk6Zt#E?d@uyVAb}r7U=+q60OKG-5JC`! z{b`L4(FjtkqMcB$srrSad(Ex0B_Z;-Jv2X=b;k>+5!o<93+LQKl|zQRO9|mJW 0) { + positions.forEach((pos, idx) => { + console.log(` ${idx + 1}. ${pos.symbol} ${pos.side.toUpperCase()} ${pos.size} SOL`); + console.log(` Entry: $${pos.entryPrice.toFixed(4)}, Current: $${pos.markPrice.toFixed(4)}`); + console.log(` P&L: ${pos.unrealizedPnl >= 0 ? '+' : ''}$${pos.unrealizedPnl.toFixed(2)}`); + }); + } + console.log(''); + + // 2. Start automation with position-aware configuration + console.log('2. Starting position-aware automation...'); + const automationConfig = { + symbol: 'SOLUSD', + mode: 'LIVE', // Set to LIVE for real trading + selectedTimeframes: ['5', '15'], // Scalping timeframes + enableTrading: true, // Enable real trades + tradingAmount: 100, // Position size in USD + maxLeverage: 10, // Maximum leverage + riskPercentage: 2, // 2% risk per trade + maxDailyTrades: 5, // Maximum 5 trades per day + stopLoss: 1.0, // 1% stop loss + takeProfit: 2.0, // 2% take profit + dexProvider: 'DRIFT' + }; + + const automationResponse = await axios.post(`${BASE_URL}/api/automation/start`, automationConfig); + + if (automationResponse.data.success) { + console.log('βœ… Automation started successfully!'); + console.log(`πŸ“Š Mode: ${automationConfig.mode}`); + console.log(`πŸ’° Trading: ${automationConfig.enableTrading ? 'ENABLED' : 'SIMULATION ONLY'}`); + console.log(`🎯 Symbol: ${automationConfig.symbol}`); + console.log(`⏱️ Timeframes: ${automationConfig.selectedTimeframes.join(', ')}`); + + if (positions.length > 0) { + console.log('\n🎯 INTELLIGENT BEHAVIOR:'); + console.log(' βœ… Will monitor existing position for stop loss proximity'); + console.log(' βœ… Will switch to DCA/doubling down if price approaches SL'); + console.log(' βœ… Will scan for new opportunities only after position closes'); + } else { + console.log('\n🎯 SCANNING MODE:'); + console.log(' βœ… Will scan for new entry opportunities'); + console.log(' βœ… Will execute trades based on AI analysis'); + } + + } else { + console.error('❌ Failed to start automation:', automationResponse.data.error); + } + + // 3. Check final status + console.log('\n3. Checking automation status...'); + const statusResponse = await axios.get(`${BASE_URL}/api/automation/status`); + console.log(`πŸ“Š Status: ${JSON.stringify(statusResponse.data, null, 2)}`); + + } catch (error) { + console.error('❌ Error starting automation:', error.response?.data || error.message); + } +} + +// Run the automation starter +startAutomationSafely() + .then(() => { + console.log('\nβœ… Automation startup completed'); + }) + .catch((error) => { + console.error('❌ Startup failed:', error); + });