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
This commit is contained in:
mindesbunister
2025-07-26 10:40:05 +02:00
parent 8cfb13f728
commit e3eff629a3
4 changed files with 336 additions and 15 deletions

View File

@@ -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() {