#!/usr/bin/env node /** * Simplified Stop Loss Decision Learning System * * Uses existing AILearningData schema for learning integration */ const { getDB } = require('./db'); class SimplifiedStopLossLearner { constructor() { this.decisionHistory = []; this.learningThresholds = { emergencyDistance: 1.0, highRiskDistance: 2.0, mediumRiskDistance: 5.0 }; } async log(message) { const timestamp = new Date().toISOString(); console.log(`[${timestamp}] 🧠 SL Learner: ${message}`); } /** * Record an AI decision for learning (using existing schema) */ async recordDecision(decisionData) { try { const decision = { userId: 'system', // System decisions analysisData: { type: 'STOP_LOSS_DECISION', decision: decisionData.decision, reasoning: decisionData.reasoning, confidence: decisionData.confidence, distanceFromSL: decisionData.distanceFromSL, marketConditions: decisionData.marketConditions || {}, timestamp: new Date().toISOString() }, marketConditions: decisionData.marketConditions || {}, timeframe: decisionData.timeframe || '1h', symbol: decisionData.symbol || 'SOLUSD' }; const prisma = await getDB(); const record = await prisma.ai_learning_data.create({ data: decision }); await this.log(`📝 Recorded decision ${record.id} for learning: ${decisionData.decision}`); this.decisionHistory.push(decision); return record.id; } catch (error) { await this.log(`❌ Error recording decision: ${error.message}`); return null; } } /** * Update decision outcome for learning */ async updateDecisionOutcome(decisionId, outcomeData) { try { const prisma = await getDB(); await prisma.ai_learning_data.update({ where: { id: decisionId }, data: { outcome: outcomeData.outcome, actualPrice: outcomeData.price, feedbackData: { outcome: outcomeData.outcome, pnlImpact: outcomeData.pnlImpact, timeToOutcome: outcomeData.timeToOutcome, wasCorrect: outcomeData.wasCorrect, learningScore: outcomeData.learningScore }, updatedAt: new Date() } }); await this.log(`✅ Updated decision ${decisionId} with outcome: ${outcomeData.outcome}`); } catch (error) { await this.log(`❌ Error updating decision outcome: ${error.message}`); } } /** * Analyze historical decisions for patterns */ async analyzeDecisionPatterns() { try { const prisma = await getDB(); const decisions = await prisma.ai_learning_data.findMany({ where: { analysisData: { string_contains: '"type":"STOP_LOSS_DECISION"' } }, orderBy: { createdAt: 'desc' }, take: 50 }); if (decisions.length === 0) { await this.log(`📊 No stop loss decisions found for pattern analysis`); return this.learningThresholds; } // Basic pattern analysis const patterns = { emergencyDecisions: decisions.filter(d => d.analysisData?.distanceFromSL < 1.0 ), highRiskDecisions: decisions.filter(d => d.analysisData?.distanceFromSL >= 1.0 && d.analysisData?.distanceFromSL < 2.0 ), successfulExits: decisions.filter(d => d.outcome === 'PROFIT' || d.outcome === 'BREAK_EVEN' ) }; await this.log(`📊 Analyzed ${decisions.length} decisions. Emergency: ${patterns.emergencyDecisions.length}, High Risk: ${patterns.highRiskDecisions.length}, Successful: ${patterns.successfulExits.length}`); // Update thresholds based on success rates if (patterns.successfulExits.length > 5) { const avgSuccessDistance = patterns.successfulExits .map(d => d.analysisData?.distanceFromSL || 2.0) .reduce((a, b) => a + b, 0) / patterns.successfulExits.length; this.learningThresholds.emergencyDistance = Math.max(0.5, avgSuccessDistance - 1.0); this.learningThresholds.highRiskDistance = Math.max(1.0, avgSuccessDistance); } return this.learningThresholds; } catch (error) { await this.log(`❌ Error analyzing decision patterns: ${error.message}`); return this.learningThresholds; } } /** * Generate smart recommendation based on learning (alias for compatibility) */ async getSmartRecommendation(currentSituation) { return await this.generateSmartRecommendation(currentSituation); } /** * Generate smart recommendation based on learning */ async generateSmartRecommendation(currentSituation) { try { const patterns = await this.analyzeDecisionPatterns(); const { distanceFromSL, marketConditions, position } = currentSituation; // Find similar situations const prisma = await getDB(); const similarDecisions = await prisma.ai_learning_data.findMany({ where: { analysisData: { string_contains: '"type":"STOP_LOSS_DECISION"' }, symbol: position?.symbol || 'SOLUSD' }, orderBy: { createdAt: 'desc' }, take: 20 }); let recommendation = 'HOLD'; let confidence = 0.5; let reasoning = 'Default decision based on distance thresholds'; if (distanceFromSL < patterns.emergencyDistance) { recommendation = 'EMERGENCY_EXIT'; confidence = 0.9; reasoning = `Critical proximity (${distanceFromSL}%) to stop loss requires immediate action`; } else if (distanceFromSL < patterns.highRiskDistance) { recommendation = 'ENHANCED_MONITORING'; confidence = 0.7; reasoning = `High risk zone (${distanceFromSL}%) - increased monitoring and preparation for exit`; } else if (distanceFromSL < patterns.mediumRiskDistance) { recommendation = 'MONITOR'; confidence = 0.6; reasoning = `Medium risk zone (${distanceFromSL}%) - standard monitoring`; } // Adjust based on similar situations const successfulSimilar = similarDecisions.filter(d => d.outcome === 'PROFIT' || d.outcome === 'BREAK_EVEN' ); if (successfulSimilar.length > 0) { const avgSuccessAction = successfulSimilar .map(d => d.analysisData?.decision) .filter(Boolean); if (avgSuccessAction.length > 0) { const mostSuccessfulAction = avgSuccessAction .reduce((a, b, _, arr) => arr.filter(v => v === a).length >= arr.filter(v => v === b).length ? a : b ); if (mostSuccessfulAction !== recommendation) { reasoning += `. Learning suggests ${mostSuccessfulAction} based on ${successfulSimilar.length} similar situations`; confidence = Math.min(0.95, confidence + 0.1); } } } await this.log(`🎯 Smart recommendation: ${recommendation} (${Math.round(confidence * 100)}% confidence)`); return { recommendation, confidence, reasoning, learnedThresholds: patterns }; } catch (error) { await this.log(`❌ Error generating smart recommendation: ${error.message}`); return { recommendation: 'HOLD', confidence: 0.5, reasoning: `Default decision - learning system error: ${error.message}`, learnedThresholds: this.learningThresholds }; } } /** * Get learning status */ async getLearningStatus() { try { const prisma = await getDB(); const totalDecisions = await prisma.ai_learning_data.count({ where: { analysisData: { string_contains: '"type":"STOP_LOSS_DECISION"' } } }); const recentDecisions = await prisma.ai_learning_data.count({ where: { analysisData: { string_contains: '"type":"STOP_LOSS_DECISION"' }, createdAt: { gte: new Date(Date.now() - 24 * 60 * 60 * 1000) // Last 24 hours } } }); return { totalDecisions, recentDecisions, thresholds: this.learningThresholds, isActive: totalDecisions > 0 }; } catch (error) { await this.log(`❌ Error getting learning status: ${error.message}`); return { totalDecisions: 0, recentDecisions: 0, thresholds: this.learningThresholds, isActive: false }; } } } module.exports = SimplifiedStopLossLearner;