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!
This commit is contained in:
@@ -17,16 +17,34 @@ export async function POST(request) {
|
|||||||
|
|
||||||
console.log('📋 Superior Config:', config)
|
console.log('📋 Superior Config:', config)
|
||||||
|
|
||||||
// Use the proven scalp preset parallel technique
|
// Define trading presets matching the main automation system
|
||||||
const SCALP_TIMEFRAMES = [
|
const TRADING_PRESETS = {
|
||||||
{ name: '1m', tv: '1' },
|
'scalp': [
|
||||||
{ name: '3m', tv: '3' },
|
{ name: '5m', tv: '5' },
|
||||||
{ name: '5m', tv: '5' },
|
{ name: '15m', tv: '15' }
|
||||||
{ name: '15m', tv: '15' },
|
],
|
||||||
{ name: '30m', tv: '30' },
|
'day-trading': [
|
||||||
{ name: '1h', tv: '60' },
|
{ name: '1h', tv: '60' },
|
||||||
{ name: '4h', tv: '240' }
|
{ name: '4h', tv: '240' }
|
||||||
]
|
],
|
||||||
|
'swing-trading': [
|
||||||
|
{ name: '4h', tv: '240' },
|
||||||
|
{ name: '1D', tv: '1D' }
|
||||||
|
],
|
||||||
|
'extended': [
|
||||||
|
{ name: '1m', tv: '1' },
|
||||||
|
{ name: '3m', tv: '3' },
|
||||||
|
{ name: '5m', tv: '5' },
|
||||||
|
{ name: '15m', tv: '15' },
|
||||||
|
{ name: '30m', tv: '30' },
|
||||||
|
{ name: '1h', tv: '60' },
|
||||||
|
{ name: '4h', tv: '240' },
|
||||||
|
{ name: '1D', tv: '1D' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get timeframes for the selected preset
|
||||||
|
const selectedTimeframes = TRADING_PRESETS[config.preset] || TRADING_PRESETS['scalp']
|
||||||
|
|
||||||
// For single timeframe compatibility
|
// For single timeframe compatibility
|
||||||
if (body.timeframe) {
|
if (body.timeframe) {
|
||||||
@@ -69,11 +87,11 @@ export async function POST(request) {
|
|||||||
|
|
||||||
// Multi-timeframe parallel capture
|
// Multi-timeframe parallel capture
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
console.log(`🔄 Starting parallel capture of ${SCALP_TIMEFRAMES.length} timeframes...`)
|
console.log(`🔄 Starting parallel capture of ${selectedTimeframes.length} timeframes for ${config.preset} preset...`)
|
||||||
|
|
||||||
const capturePromises = SCALP_TIMEFRAMES.map(async (tf, index) => {
|
const capturePromises = selectedTimeframes.map(async (tf, index) => {
|
||||||
try {
|
try {
|
||||||
console.log(`📸 [${index + 1}/${SCALP_TIMEFRAMES.length}] Starting ${tf.name} (${tf.tv})...`)
|
console.log(`📸 [${index + 1}/${selectedTimeframes.length}] Starting ${tf.name} (${tf.tv})...`)
|
||||||
|
|
||||||
const response = await fetch('http://localhost:9001/api/enhanced-screenshot', {
|
const response = await fetch('http://localhost:9001/api/enhanced-screenshot', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -129,8 +147,8 @@ export async function POST(request) {
|
|||||||
|
|
||||||
console.log('✅ SUPERIOR PARALLEL CAPTURE COMPLETED!')
|
console.log('✅ SUPERIOR PARALLEL CAPTURE COMPLETED!')
|
||||||
console.log(`⏱️ Duration: ${duration.toFixed(2)}s`)
|
console.log(`⏱️ Duration: ${duration.toFixed(2)}s`)
|
||||||
console.log(`📸 Screenshots: ${totalScreenshots}/${SCALP_TIMEFRAMES.length * config.layouts.length}`)
|
console.log(`📸 Screenshots: ${totalScreenshots}/${selectedTimeframes.length * config.layouts.length}`)
|
||||||
console.log(`🎯 Success: ${successful.length}/${SCALP_TIMEFRAMES.length}`)
|
console.log(`🎯 Success: ${successful.length}/${selectedTimeframes.length}`)
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -140,10 +158,10 @@ export async function POST(request) {
|
|||||||
duration: duration,
|
duration: duration,
|
||||||
totalScreenshots: totalScreenshots,
|
totalScreenshots: totalScreenshots,
|
||||||
successfulTimeframes: successful.length,
|
successfulTimeframes: successful.length,
|
||||||
totalTimeframes: SCALP_TIMEFRAMES.length,
|
totalTimeframes: selectedTimeframes.length,
|
||||||
successRate: ((successful.length / SCALP_TIMEFRAMES.length) * 100).toFixed(1),
|
successRate: ((successful.length / selectedTimeframes.length) * 100).toFixed(1),
|
||||||
results: results,
|
results: results,
|
||||||
message: `Parallel capture completed: ${successful.length}/${SCALP_TIMEFRAMES.length} timeframes in ${duration.toFixed(2)}s`
|
message: `Parallel capture completed: ${successful.length}/${selectedTimeframes.length} timeframes in ${duration.toFixed(2)}s`
|
||||||
})
|
})
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -162,12 +180,19 @@ export async function GET() {
|
|||||||
endpoints: {
|
endpoints: {
|
||||||
POST: '/api/superior-screenshot - Superior parallel analysis'
|
POST: '/api/superior-screenshot - Superior parallel analysis'
|
||||||
},
|
},
|
||||||
|
presets: {
|
||||||
|
'scalp': '2 timeframes (5m, 15m) - Scalping strategy',
|
||||||
|
'day-trading': '2 timeframes (1h, 4h) - Day trading strategy',
|
||||||
|
'swing-trading': '2 timeframes (4h, 1D) - Swing trading strategy',
|
||||||
|
'extended': '8 timeframes (1m-1D) - Comprehensive analysis'
|
||||||
|
},
|
||||||
features: [
|
features: [
|
||||||
'Parallel multi-timeframe capture',
|
'Parallel multi-timeframe capture',
|
||||||
'Scalp preset (7 timeframes)',
|
'Intelligent preset detection',
|
||||||
'Single timeframe compatibility',
|
'Single timeframe compatibility',
|
||||||
'Proven efficiency (100% success rate)',
|
'Proven efficiency (100% success rate)',
|
||||||
'API-managed browser sessions'
|
'API-managed browser sessions',
|
||||||
|
'No hardcoded 7-timeframe limitation'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { enhancedScreenshotService } from './enhanced-screenshot-robust'
|
import { superiorScreenshotService } from './superior-screenshot-service'
|
||||||
import { aiAnalysisService } from './ai-analysis'
|
import { aiAnalysisService } from './ai-analysis'
|
||||||
import { automatedCleanupService } from './automated-cleanup-service'
|
import { automatedCleanupService } from './automated-cleanup-service'
|
||||||
import aggressiveCleanup from './aggressive-cleanup'
|
import aggressiveCleanup from './aggressive-cleanup'
|
||||||
@@ -69,7 +69,7 @@ export class AutoTradingService {
|
|||||||
|
|
||||||
// Force cleanup all browser sessions
|
// Force cleanup all browser sessions
|
||||||
try {
|
try {
|
||||||
await enhancedScreenshotService.cleanup()
|
await superiorScreenshotService.cleanup()
|
||||||
await aggressiveCleanup.forceCleanup()
|
await aggressiveCleanup.forceCleanup()
|
||||||
console.log('✅ Trading service stopped and cleaned up')
|
console.log('✅ Trading service stopped and cleaned up')
|
||||||
} catch (cleanupError) {
|
} catch (cleanupError) {
|
||||||
@@ -80,60 +80,103 @@ export class AutoTradingService {
|
|||||||
private async runTradingCycle(config: TradingConfig): Promise<void> {
|
private async runTradingCycle(config: TradingConfig): Promise<void> {
|
||||||
console.log(`🔄 Running trading cycle ${this.currentCycle}...`)
|
console.log(`🔄 Running trading cycle ${this.currentCycle}...`)
|
||||||
|
|
||||||
// Process each timeframe sequentially to avoid resource conflicts
|
try {
|
||||||
for (const timeframe of config.timeframes) {
|
console.log(`\n📊 Processing ${config.symbol} with ${config.timeframes.length} timeframes...`)
|
||||||
if (!this.isRunning) break // Check if service was stopped
|
|
||||||
|
|
||||||
try {
|
// Determine trading strategy based on timeframes for intelligent parallel capture
|
||||||
console.log(`\n📊 Processing ${config.symbol} ${timeframe}...`)
|
const timeframeSet = new Set(config.timeframes)
|
||||||
|
let preset: 'scalp' | 'day-trading' | 'swing-trading' | 'custom' = 'custom'
|
||||||
// Capture screenshots with robust cleanup
|
|
||||||
const screenshots = await enhancedScreenshotService.captureWithLogin({
|
// Detect strategy based on timeframe patterns
|
||||||
symbol: config.symbol,
|
if (timeframeSet.has('5') && timeframeSet.has('15') && config.timeframes.length === 2) {
|
||||||
timeframe: timeframe,
|
preset = 'scalp'
|
||||||
layouts: config.layouts,
|
console.log('🎯 Detected: SCALP trading strategy')
|
||||||
analyze: false // We'll analyze separately
|
} 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')
|
||||||
|
}
|
||||||
|
|
||||||
if (screenshots.length > 0) {
|
// Capture screenshots using superior parallel technique
|
||||||
console.log(`✅ Captured ${screenshots.length} screenshots for ${timeframe}`)
|
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
|
||||||
|
}
|
||||||
|
|
||||||
// Analyze screenshots
|
if (!result.screenshots || result.screenshots.length === 0) {
|
||||||
|
console.warn(`⚠️ No screenshots for ${result.timeframeName}`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
console.log(`\n🤖 Analyzing ${result.timeframeName} (${result.screenshots.length} screenshots)...`)
|
||||||
|
|
||||||
let analysis = null
|
let analysis = null
|
||||||
if (screenshots.length === 1) {
|
if (result.screenshots.length === 1) {
|
||||||
analysis = await aiAnalysisService.analyzeScreenshot(screenshots[0])
|
analysis = await aiAnalysisService.analyzeScreenshot(result.screenshots[0])
|
||||||
} else if (screenshots.length > 1) {
|
} else if (result.screenshots.length > 1) {
|
||||||
analysis = await aiAnalysisService.analyzeMultipleScreenshots(screenshots)
|
analysis = await aiAnalysisService.analyzeMultipleScreenshots(result.screenshots)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (analysis) {
|
if (analysis) {
|
||||||
console.log(`✅ Analysis completed for ${timeframe}`)
|
console.log(`✅ Analysis completed for ${result.timeframeName}`)
|
||||||
console.log(`📈 Sentiment: ${analysis.marketSentiment || 'Unknown'}`)
|
console.log(`📈 Sentiment: ${analysis.marketSentiment || 'Unknown'}`)
|
||||||
console.log(`🎯 Recommendation: ${analysis.recommendation}, Confidence: ${analysis.confidence}%`)
|
console.log(`🎯 Recommendation: ${analysis.recommendation}, Confidence: ${analysis.confidence}%`)
|
||||||
|
|
||||||
// Here you would implement your trading logic based on analysis
|
// Process trading logic based on analysis
|
||||||
await this.processAnalysisForTrading(analysis, config.symbol, timeframe)
|
await this.processAnalysisForTrading(analysis, config.symbol, result.timeframeName)
|
||||||
} else {
|
} else {
|
||||||
console.warn(`⚠️ No analysis returned for ${timeframe}`)
|
console.warn(`⚠️ No analysis returned for ${result.timeframeName}`)
|
||||||
}
|
}
|
||||||
} catch (analysisError) {
|
} catch (analysisError) {
|
||||||
console.error(`❌ Analysis failed for ${timeframe}:`, analysisError)
|
console.error(`❌ Analysis failed for ${result.timeframeName}:`, analysisError)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.error(`❌ No screenshots captured for ${timeframe}`)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Small delay between timeframes to prevent overwhelming the system
|
console.error(`❌ No screenshots captured using superior parallel technique`)
|
||||||
if (config.timeframes.indexOf(timeframe) < config.timeframes.length - 1) {
|
|
||||||
console.log('⏳ Brief pause before next timeframe...')
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Error processing ${timeframe}:`, error)
|
|
||||||
// Continue with next timeframe even if one fails
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`❌ Error in trading cycle:`, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`✅ Trading cycle ${this.currentCycle} completed`)
|
console.log(`✅ Trading cycle ${this.currentCycle} completed`)
|
||||||
|
|||||||
@@ -3,26 +3,33 @@
|
|||||||
* Uses the proven scalp preset parallel API technique for maximum efficiency
|
* Uses the proven scalp preset parallel API technique for maximum efficiency
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Scalping-focused timeframes (most commonly used)
|
// Trading strategy presets matching the main automation system
|
||||||
const SCALP_TIMEFRAMES = [
|
const SCALP_TIMEFRAMES = [
|
||||||
{ name: '1m', tv: '1', description: 'Ultra-short scalping' },
|
|
||||||
{ name: '3m', tv: '3', description: 'Short scalping' },
|
|
||||||
{ name: '5m', tv: '5', description: 'Standard scalping' },
|
{ name: '5m', tv: '5', description: 'Standard scalping' },
|
||||||
{ name: '15m', tv: '15', description: 'Swing scalping' },
|
{ name: '15m', tv: '15', description: 'Swing scalping' }
|
||||||
{ name: '30m', tv: '30', description: 'Longer scalping' },
|
]
|
||||||
{ name: '1h', tv: '60', description: 'Context timeframe' },
|
|
||||||
{ name: '4h', tv: '240', description: 'Trend context' }
|
const DAY_TRADING_TIMEFRAMES = [
|
||||||
|
{ name: '1h', tv: '60', description: 'Hourly analysis' },
|
||||||
|
{ name: '4h', tv: '240', description: 'Four-hour trend' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const SWING_TRADING_TIMEFRAMES = [
|
||||||
|
{ name: '4h', tv: '240', description: 'Four-hour trend' },
|
||||||
|
{ name: '1D', tv: '1D', description: 'Daily analysis' }
|
||||||
]
|
]
|
||||||
|
|
||||||
// Additional timeframes for comprehensive analysis
|
// Additional timeframes for comprehensive analysis
|
||||||
const EXTENDED_TIMEFRAMES = [
|
const EXTENDED_TIMEFRAMES = [
|
||||||
|
{ name: '1m', tv: '1', description: 'Ultra-short scalping' },
|
||||||
|
{ name: '3m', tv: '3', description: 'Short scalping' },
|
||||||
{ name: '2m', tv: '2', description: 'Very short scalping' },
|
{ name: '2m', tv: '2', description: 'Very short scalping' },
|
||||||
{ name: '10m', tv: '10', description: 'Medium scalping' },
|
{ name: '10m', tv: '10', description: 'Medium scalping' },
|
||||||
|
{ name: '30m', tv: '30', description: 'Longer scalping' },
|
||||||
{ name: '45m', tv: '45', description: 'Extended scalping' },
|
{ name: '45m', tv: '45', description: 'Extended scalping' },
|
||||||
{ name: '2h', tv: '120', description: 'Medium trend' },
|
{ name: '2h', tv: '120', description: 'Medium trend' },
|
||||||
{ name: '6h', tv: '360', description: 'Long trend' },
|
{ name: '6h', tv: '360', description: 'Long trend' },
|
||||||
{ name: '12h', tv: '720', description: 'Daily trend' },
|
{ name: '12h', tv: '720', description: 'Daily trend' },
|
||||||
{ name: '1D', tv: '1D', description: 'Daily analysis' },
|
|
||||||
{ name: '3D', tv: '3D', description: 'Multi-day trend' },
|
{ name: '3D', tv: '3D', description: 'Multi-day trend' },
|
||||||
{ name: '1W', tv: '1W', description: 'Weekly analysis' }
|
{ name: '1W', tv: '1W', description: 'Weekly analysis' }
|
||||||
]
|
]
|
||||||
@@ -31,7 +38,7 @@ export interface SuperiorScreenshotConfig {
|
|||||||
symbol: string
|
symbol: string
|
||||||
timeframes?: string[] // If not provided, uses SCALP_TIMEFRAMES
|
timeframes?: string[] // If not provided, uses SCALP_TIMEFRAMES
|
||||||
layouts?: string[] // Default: ['ai', 'diy']
|
layouts?: string[] // Default: ['ai', 'diy']
|
||||||
preset?: 'scalp' | 'extended' | 'all' | 'custom'
|
preset?: 'scalp' | 'day-trading' | 'swing-trading' | 'extended' | 'all' | 'custom'
|
||||||
analyze?: boolean // Whether to run AI analysis
|
analyze?: boolean // Whether to run AI analysis
|
||||||
apiUrl?: string // API endpoint (default: http://localhost:9001)
|
apiUrl?: string // API endpoint (default: http://localhost:9001)
|
||||||
}
|
}
|
||||||
@@ -73,11 +80,17 @@ export class SuperiorScreenshotService {
|
|||||||
case 'scalp':
|
case 'scalp':
|
||||||
timeframesToCapture = SCALP_TIMEFRAMES
|
timeframesToCapture = SCALP_TIMEFRAMES
|
||||||
break
|
break
|
||||||
|
case 'day-trading':
|
||||||
|
timeframesToCapture = DAY_TRADING_TIMEFRAMES
|
||||||
|
break
|
||||||
|
case 'swing-trading':
|
||||||
|
timeframesToCapture = SWING_TRADING_TIMEFRAMES
|
||||||
|
break
|
||||||
case 'extended':
|
case 'extended':
|
||||||
timeframesToCapture = [...SCALP_TIMEFRAMES, ...EXTENDED_TIMEFRAMES]
|
timeframesToCapture = [...SCALP_TIMEFRAMES, ...DAY_TRADING_TIMEFRAMES, ...SWING_TRADING_TIMEFRAMES, ...EXTENDED_TIMEFRAMES]
|
||||||
break
|
break
|
||||||
case 'all':
|
case 'all':
|
||||||
timeframesToCapture = [...SCALP_TIMEFRAMES, ...EXTENDED_TIMEFRAMES]
|
timeframesToCapture = [...SCALP_TIMEFRAMES, ...DAY_TRADING_TIMEFRAMES, ...SWING_TRADING_TIMEFRAMES, ...EXTENDED_TIMEFRAMES]
|
||||||
break
|
break
|
||||||
case 'custom':
|
case 'custom':
|
||||||
if (config.timeframes) {
|
if (config.timeframes) {
|
||||||
@@ -214,7 +227,7 @@ export class SuperiorScreenshotService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scalp preset - optimized for scalping strategies
|
* Scalp preset - optimized for scalping strategies (5m, 15m)
|
||||||
*/
|
*/
|
||||||
async captureScalpPreset(symbol: string, analyze: boolean = false): Promise<ScreenshotResult[]> {
|
async captureScalpPreset(symbol: string, analyze: boolean = false): Promise<ScreenshotResult[]> {
|
||||||
return this.captureParallel({
|
return this.captureParallel({
|
||||||
@@ -225,6 +238,30 @@ export class SuperiorScreenshotService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Day trading preset - moderate timeframes (1h, 4h)
|
||||||
|
*/
|
||||||
|
async captureDayTradingPreset(symbol: string, analyze: boolean = false): Promise<ScreenshotResult[]> {
|
||||||
|
return this.captureParallel({
|
||||||
|
symbol,
|
||||||
|
preset: 'day-trading',
|
||||||
|
layouts: ['ai', 'diy'],
|
||||||
|
analyze
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swing trading preset - longer timeframes (4h, 1D)
|
||||||
|
*/
|
||||||
|
async captureSwingTradingPreset(symbol: string, analyze: boolean = false): Promise<ScreenshotResult[]> {
|
||||||
|
return this.captureParallel({
|
||||||
|
symbol,
|
||||||
|
preset: 'swing-trading',
|
||||||
|
layouts: ['ai', 'diy'],
|
||||||
|
analyze
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extended preset - comprehensive timeframe analysis
|
* Extended preset - comprehensive timeframe analysis
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user