Files
trading_bot_v3/lib/auto-trading-service.ts
mindesbunister 0087490386 Integrate superior parallel screenshot system into main automation
BREAKING CHANGES:
- Replace enhancedScreenshotService with superiorScreenshotService throughout system
- Update trading presets to match actual strategy definitions:
  * Scalp: 5m, 15m (was 7 timeframes)
  * Day Trading: 1h, 4h (NEW)
  * Swing Trading: 4h, 1D (NEW)
  * Extended: All timeframes for comprehensive analysis
- Auto-trading service now uses intelligent parallel capture
- Enhanced-screenshot API restored with superior backend
- AI analysis service updated for compatibility
- Superior screenshot API supports all presets

PERFORMANCE IMPROVEMENTS:
- Parallel capture for ALL timeframes regardless of count
- Intelligent preset detection based on timeframe patterns
- No more hardcoded 7-timeframe limitation
- Backwards compatibility maintained

The system now uses the superior parallel approach for ANY timeframe selection,
whether it's 2 timeframes (scalp/day/swing) or 8+ timeframes (extended).
No more sequential delays - everything is parallel!
2025-07-26 12:24:30 +02:00

307 lines
11 KiB
TypeScript

import { superiorScreenshotService } from './superior-screenshot-service'
import { aiAnalysisService } from './ai-analysis'
import { automatedCleanupService } from './automated-cleanup-service'
import aggressiveCleanup from './aggressive-cleanup'
export interface TradingConfig {
symbol: string
timeframes: string[]
layouts: string[]
intervalMs: number // How often to run analysis
maxCycles?: number // Optional limit for testing
}
export class AutoTradingService {
private isRunning = false
private currentCycle = 0
private config: TradingConfig | null = null
async start(config: TradingConfig) {
if (this.isRunning) {
console.log('⚠️ Trading service already running')
return
}
this.isRunning = true
this.config = config
this.currentCycle = 0
console.log('🚀 Starting automated trading service with robust cleanup...')
console.log('🔧 Config:', config)
// Start background cleanup service
automatedCleanupService.start(30000) // Every 30 seconds
// Start aggressive cleanup system
aggressiveCleanup.startPeriodicCleanup()
try {
while (this.isRunning && (!config.maxCycles || this.currentCycle < config.maxCycles)) {
this.currentCycle++
console.log(`\n🔄 === TRADING CYCLE ${this.currentCycle} ===`)
await this.runTradingCycle(config)
if (this.isRunning) {
console.log(`⏳ Waiting ${config.intervalMs/1000} seconds until next cycle...`)
await new Promise(resolve => setTimeout(resolve, config.intervalMs))
}
}
if (config.maxCycles && this.currentCycle >= config.maxCycles) {
console.log(`✅ Completed ${this.currentCycle} cycles (reached max limit)`)
}
} catch (error) {
console.error('❌ Trading service error:', error)
} finally {
await this.stop()
}
}
async stop() {
console.log('🛑 Stopping automated trading service...')
this.isRunning = false
// Stop cleanup services
automatedCleanupService.stop()
aggressiveCleanup.stop()
// Force cleanup all browser sessions
try {
await superiorScreenshotService.cleanup()
await aggressiveCleanup.forceCleanup()
console.log('✅ Trading service stopped and cleaned up')
} catch (cleanupError) {
console.error('❌ Error during final cleanup:', cleanupError)
}
}
private async runTradingCycle(config: TradingConfig): Promise<void> {
console.log(`🔄 Running trading cycle ${this.currentCycle}...`)
try {
console.log(`\n📊 Processing ${config.symbol} with ${config.timeframes.length} timeframes...`)
// Determine trading strategy based on timeframes for intelligent parallel capture
const timeframeSet = new Set(config.timeframes)
let preset: 'scalp' | 'day-trading' | 'swing-trading' | 'custom' = 'custom'
// Detect strategy based on timeframe patterns
if (timeframeSet.has('5') && timeframeSet.has('15') && config.timeframes.length === 2) {
preset = 'scalp'
console.log('🎯 Detected: SCALP trading strategy')
} else if (timeframeSet.has('60') && timeframeSet.has('240') && config.timeframes.length === 2) {
preset = 'day-trading'
console.log('🎯 Detected: DAY TRADING strategy')
} else if (timeframeSet.has('240') && timeframeSet.has('1D') && config.timeframes.length === 2) {
preset = 'swing-trading'
console.log('🎯 Detected: SWING TRADING strategy')
} else {
preset = 'custom'
console.log('🎯 Using: CUSTOM timeframe configuration')
}
// Capture screenshots using superior parallel technique
let screenshots: any[] = []
let allResults: any[] = []
if (preset === 'custom') {
// Custom timeframes - use parallel capture with custom preset
console.log('🚀 Using superior parallel capture with custom timeframes...')
allResults = await superiorScreenshotService.captureParallel({
symbol: config.symbol,
preset: 'custom',
timeframes: config.timeframes,
layouts: config.layouts,
analyze: false
})
} else {
// Standard preset - use optimized preset method
console.log(`🚀 Using superior parallel capture with ${preset} preset...`)
allResults = await superiorScreenshotService.captureParallel({
symbol: config.symbol,
preset: preset,
layouts: config.layouts,
analyze: false
})
}
// Extract successful screenshots for analysis
screenshots = allResults
.filter(result => result.success && result.screenshots)
.flatMap(result => result.screenshots || [])
if (screenshots.length > 0) {
console.log(`✅ Superior parallel capture completed: ${screenshots.length} screenshots`)
// Process results by timeframe for detailed analysis
for (const result of allResults) {
if (!result.success) {
console.error(`❌ Failed to capture ${result.timeframeName}: ${result.error}`)
continue
}
if (!result.screenshots || result.screenshots.length === 0) {
console.warn(`⚠️ No screenshots for ${result.timeframeName}`)
continue
}
try {
console.log(`\n🤖 Analyzing ${result.timeframeName} (${result.screenshots.length} screenshots)...`)
let analysis = null
if (result.screenshots.length === 1) {
analysis = await aiAnalysisService.analyzeScreenshot(result.screenshots[0])
} else if (result.screenshots.length > 1) {
analysis = await aiAnalysisService.analyzeMultipleScreenshots(result.screenshots)
}
if (analysis) {
console.log(`✅ Analysis completed for ${result.timeframeName}`)
console.log(`📈 Sentiment: ${analysis.marketSentiment || 'Unknown'}`)
console.log(`🎯 Recommendation: ${analysis.recommendation}, Confidence: ${analysis.confidence}%`)
// Process trading logic based on analysis
await this.processAnalysisForTrading(analysis, config.symbol, result.timeframeName)
} else {
console.warn(`⚠️ No analysis returned for ${result.timeframeName}`)
}
} catch (analysisError) {
console.error(`❌ Analysis failed for ${result.timeframeName}:`, analysisError)
}
}
} else {
console.error(`❌ No screenshots captured using superior parallel technique`)
}
} catch (error) {
console.error(`❌ Error in trading cycle:`, error)
}
console.log(`✅ Trading cycle ${this.currentCycle} completed`)
// Run post-cycle cleanup to ensure no browser processes are left running
try {
await aggressiveCleanup.runPostAnalysisCleanup()
} catch (cleanupError) {
console.error('❌ Error in post-cycle cleanup:', cleanupError)
}
}
private async processAnalysisForTrading(analysis: any, symbol: string, timeframe: string): Promise<void> {
try {
console.log(`🎯 Processing trading analysis for ${symbol} ${timeframe}...`)
// Extract key trading signals from analysis
const sentiment = analysis.marketSentiment
const confidence = analysis.confidence || 0
const recommendation = analysis.recommendation
console.log(`📊 Sentiment: ${sentiment}, Recommendation: ${recommendation}, Confidence: ${confidence}%`)
if (analysis.keyLevels) {
console.log(`📈 Support levels: ${analysis.keyLevels.support.join(', ')}`)
console.log(`📉 Resistance levels: ${analysis.keyLevels.resistance.join(', ')}`)
}
// Trading decision logic
if (confidence >= 70) {
if (sentiment === 'BULLISH' && recommendation === 'BUY') {
console.log('🟢 HIGH CONFIDENCE BULLISH - Consider long position')
// await this.executeLongTrade(symbol, timeframe, analysis)
} else if (sentiment === 'BEARISH' && recommendation === 'SELL') {
console.log('🔴 HIGH CONFIDENCE BEARISH - Consider short position')
// await this.executeShortTrade(symbol, timeframe, analysis)
}
} else if (confidence >= 50) {
console.log('🟡 MODERATE CONFIDENCE - Monitor for confirmation')
} else {
console.log('⚪ LOW CONFIDENCE - Hold current positions')
}
} catch (error) {
console.error('❌ Error processing trading analysis:', error)
}
}
// Example trading execution methods (implement with your preferred exchange)
private async executeLongTrade(symbol: string, timeframe: string, analysis: any): Promise<void> {
console.log(`🟢 Executing LONG trade for ${symbol} based on ${timeframe} analysis`)
// Implement actual trading logic here
// This could use Drift Protocol, Jupiter DEX, or other trading interfaces
}
private async executeShortTrade(symbol: string, timeframe: string, analysis: any): Promise<void> {
console.log(`🔴 Executing SHORT trade for ${symbol} based on ${timeframe} analysis`)
// Implement actual trading logic here
}
// Status methods
getStatus() {
return {
isRunning: this.isRunning,
currentCycle: this.currentCycle,
config: this.config
}
}
getCurrentCycle(): number {
return this.currentCycle
}
isServiceRunning(): boolean {
return this.isRunning
}
}
// Example usage configurations
export const TRADING_CONFIGS = {
// Scalping configuration - frequent analysis of short timeframes
scalping: {
symbol: 'SOLUSD',
timeframes: ['5m', '15m'],
layouts: ['ai', 'diy'],
intervalMs: 5 * 60 * 1000, // Every 5 minutes
maxCycles: 100 // Limit for testing
},
// Day trading configuration - moderate frequency on intraday timeframes
dayTrading: {
symbol: 'SOLUSD',
timeframes: ['1h', '4h'],
layouts: ['ai', 'diy'],
intervalMs: 30 * 60 * 1000, // Every 30 minutes
maxCycles: 50 // Limit for testing
},
// Swing trading configuration - less frequent analysis of longer timeframes
swingTrading: {
symbol: 'SOLUSD',
timeframes: ['4h', '1d'],
layouts: ['ai', 'diy'],
intervalMs: 2 * 60 * 60 * 1000, // Every 2 hours
maxCycles: 24 // Limit for testing
}
}
// Singleton instance
export const autoTradingService = new AutoTradingService()
// Example startup function
export async function startTradingBot(configName: keyof typeof TRADING_CONFIGS = 'dayTrading') {
const config = TRADING_CONFIGS[configName]
if (!config) {
throw new Error(`Unknown trading configuration: ${configName}`)
}
console.log(`🚀 Starting trading bot with ${configName} configuration`)
await autoTradingService.start(config)
}
// Graceful shutdown
export async function stopTradingBot() {
console.log('🛑 Stopping trading bot...')
await autoTradingService.stop()
}