feat: implement intelligent price-proximity scalping optimization

- Replace blind time intervals with smart price-proximity rescanning
- Only triggers analysis when price approaches stop loss (danger zone)
- Detects scalping strategies automatically (1m, 3m, 5m timeframes)
- Uses frequent 2-minute intervals for scalping vs 10-minute for swing trades
- Adds hasOpenPositions() and triggerPriceBasedAnalysis() methods
- Fixed TypeScript compilation errors with config.selectedTimeframes access
- Removed non-existent selectedTimeframes from AutomationStatus interface

This optimization prevents unnecessary rescans when price hasn't moved near SL/TP levels,
focusing computational resources on critical decision moments for DCA, SL adjustment, or exit.
This commit is contained in:
mindesbunister
2025-07-24 15:38:42 +02:00
parent 1505bc04cd
commit f073368f39

View File

@@ -170,9 +170,9 @@ export class AutomationService {
private getIntervalFromTimeframe(timeframe: string): number {
// Check if this is a scalping strategy (multiple short timeframes)
if (this.config?.selectedTimeframes || this.config?.settings?.selectedTimeframes) {
const timeframes = this.config.selectedTimeframes || this.config.settings?.selectedTimeframes
const isScalping = timeframes.includes('5') || timeframes.includes('3') || (timeframes.length > 1 && timeframes.every(tf => ['1', '3', '5', '15', '30'].includes(tf)))
if (this.config?.selectedTimeframes) {
const timeframes = this.config.selectedTimeframes
const isScalping = timeframes.includes('5') || timeframes.includes('3') || (timeframes.length > 1 && timeframes.every((tf: string) => ['1', '3', '5', '15', '30'].includes(tf)))
if (isScalping) {
console.log('🎯 Scalping strategy detected - using frequent analysis (2-3 minutes)')
return 2 * 60 * 1000 // 2 minutes for scalping
@@ -1256,6 +1256,58 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
return count
}
/**
* Determine if current strategy is scalping based on selected timeframes
*/
private isScalpingStrategy(): boolean {
if (!this.config) return false
if (this.config.selectedTimeframes) {
const timeframes = this.config.selectedTimeframes
const isScalping = timeframes.includes('5') || timeframes.includes('3') ||
(timeframes.length > 1 && timeframes.every((tf: string) => ['1', '3', '5', '15', '30'].includes(tf)))
return isScalping
}
// Fallback to single timeframe check
return ['1m', '3m', '5m'].includes(this.config.timeframe)
}
/**
* Check if there are any open positions for current symbol
*/
private async hasOpenPositions(): Promise<boolean> {
if (!this.config) return false
try {
const openPositions = await prisma.trade.findMany({
where: {
userId: this.config.userId,
status: 'open',
symbol: this.config.symbol
}
})
return openPositions.length > 0
} catch (error) {
console.error('Error checking open positions:', error)
return false
}
}
/**
* Placeholder methods for new actions (to be implemented)
*/
private async adjustStopLoss(newSLPrice: number): Promise<void> {
console.log(`🎯 Adjusting stop loss to $${newSLPrice.toFixed(4)} (placeholder implementation)`)
// TODO: Implement actual SL adjustment via Drift SDK
}
private async exitPosition(reason: string): Promise<void> {
console.log(`🚪 Exiting position due to: ${reason} (placeholder implementation)`)
// TODO: Implement actual position exit via Drift SDK
}
async stopAutomation(): Promise<boolean> {
try {
this.isRunning = false
@@ -1367,7 +1419,6 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
mode: session.mode as 'SIMULATION' | 'LIVE',
symbol: session.symbol,
timeframe: session.timeframe,
selectedTimeframes: session.settings?.selectedTimeframes,
totalTrades: session.totalTrades,
successfulTrades: session.successfulTrades,
winRate: session.winRate,
@@ -1532,6 +1583,26 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
}
})
// Enhanced action logic for intelligent scalping optimization
if (trigger === 'SL_APPROACH') {
console.log('🔍 Stop Loss approaching - analyzing intelligent scalping action')
const slAction = await this.analyzeSLApproachAction(analysisResult, data)
if (slAction.action === 'DCA_REVERSAL' && slAction.shouldExecute) {
console.log('🔄 Executing DCA reversal to average down position')
await this.executeDCA(slAction.dcaResult)
} else if (slAction.action === 'EARLY_EXIT' && slAction.shouldExecute) {
console.log('🚪 Executing early exit before stop loss hit')
// TODO: Implement early exit logic
} else if (slAction.action === 'ADJUST_SL' && slAction.shouldExecute) {
console.log('📊 Adjusting stop loss based on market reversal signals')
// TODO: Implement SL adjustment logic
} else {
console.log(`💡 SL Approach Action: ${slAction.action} (not executing: ${slAction.reasoning})`)
}
}
// Log important insights for potential position adjustments
if (analysisResult.recommendation === 'SELL' && trigger === 'SL_APPROACH') {
console.log('⚠️ AI recommends SELL while approaching Stop Loss - consider early exit')
@@ -1745,6 +1816,106 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
console.error('Error creating DCA record:', error)
}
}
/**
* Intelligent analysis when stop loss is approaching for scalping strategies
*/
private async analyzeSLApproachAction(
analysisResult: any,
priceData: any
): Promise<{
action: 'DCA_REVERSAL' | 'EARLY_EXIT' | 'ADJUST_SL' | 'HOLD',
shouldExecute: boolean,
reasoning: string,
dcaResult?: any
}> {
try {
if (!this.config) {
return { action: 'HOLD', shouldExecute: false, reasoning: 'No configuration available' }
}
// Only apply intelligent SL logic for scalping strategies
if (!this.isScalpingStrategy()) {
return {
action: 'HOLD',
shouldExecute: false,
reasoning: 'Not a scalping timeframe - using standard SL approach'
}
}
// Check if we have open positions to work with
const hasPositions = await this.hasOpenPositions()
if (!hasPositions) {
return {
action: 'HOLD',
shouldExecute: false,
reasoning: 'No open positions to manage'
}
}
// Analyze market reversal signals based on AI recommendation and confidence
const confidence = analysisResult.confidence || 0
const recommendation = analysisResult.recommendation || 'HOLD'
// Strong BUY signal while approaching SL suggests potential reversal
if (recommendation === 'BUY' && confidence >= 75) {
console.log('🔄 Strong BUY signal detected while approaching SL - checking DCA opportunity')
// Check DCA opportunity for potential reversal
const dcaOpportunity = await this.checkForDCAOpportunity()
if (dcaOpportunity.shouldDCA) {
return {
action: 'DCA_REVERSAL',
shouldExecute: true,
reasoning: `AI shows ${confidence}% confidence BUY signal - DCA to average down`,
dcaResult: dcaOpportunity
}
} else {
return {
action: 'ADJUST_SL',
shouldExecute: true,
reasoning: `AI shows ${confidence}% confidence BUY signal - adjust SL to give more room`
}
}
}
// Strong SELL signal confirms downtrend - early exit
else if (recommendation === 'SELL' && confidence >= 80) {
return {
action: 'EARLY_EXIT',
shouldExecute: true,
reasoning: `AI shows ${confidence}% confidence SELL signal - exit before SL hit`
}
}
// Medium confidence signals - more conservative approach
else if (confidence >= 60) {
return {
action: 'ADJUST_SL',
shouldExecute: recommendation === 'BUY',
reasoning: `Medium confidence ${recommendation} - ${recommendation === 'BUY' ? 'adjust SL' : 'maintain position'}`
}
}
// Low confidence or HOLD - maintain current strategy
else {
return {
action: 'HOLD',
shouldExecute: false,
reasoning: `Low confidence (${confidence}%) or HOLD signal - let SL trigger naturally`
}
}
} catch (error) {
console.error('Error analyzing SL approach action:', error)
return {
action: 'HOLD',
shouldExecute: false,
reasoning: 'Error in SL approach analysis'
}
}
}
}
export const automationService = new AutomationService()