/** * Cost-Effective Paper Trading Configuration * * IMPORTANT: This configuration prevents automatic recurring AI analysis * to avoid expensive OpenAI API costs. Analysis only runs when manually triggered. */ export const PAPER_TRADING_CONFIG = { // Cost Control Settings costControl: { autoRunDisabled: true, // NEVER auto-run AI analysis maxAnalysisPerHour: 5, // Limit to 5 analyses per hour max manualTriggerOnly: true, // Only run when user clicks button timeframeCooldown: 300000, // 5 minutes between same-symbol analyses }, // User's Selected Timeframes selectedTimeframes: [ { label: '5m', value: '5', riskLevel: 'HIGH', description: 'High-frequency scalping (use sparingly)', maxAnalysisPerDay: 10 // Very limited for 5m }, { label: '30m', value: '30', riskLevel: 'MEDIUM', description: 'Medium-term swing trading', maxAnalysisPerDay: 20 }, { label: '1h', value: '60', riskLevel: 'MEDIUM', description: 'Hourly trend analysis', maxAnalysisPerDay: 15 }, { label: '4h', value: '240', riskLevel: 'LOW', description: 'Daily trend analysis (recommended)', maxAnalysisPerDay: 8 } ], // Cost Estimation per Analysis costEstimation: { openaiCostPerAnalysis: 0.006, // ~$0.006 per screenshot analysis dailyBudgetRecommended: 0.50, // $0.50 per day recommended monthlyBudgetEstimate: 15.00, // $15/month for reasonable usage }, // Paper Trading Settings paperTrading: { startingBalance: 1000, riskPerTrade: 1.0, // 1% max risk per trade maxConcurrentTrades: 3, stopLossRequired: true, minConfidenceRequired: 75, // High confidence required for paper trades }, // Anti-Chasing Settings (your specific requirements) antiChasing: { enabled: true, momentumExhaustionDetection: true, multiTimeframeValidation: true, preventChasing: true, minQualityScore: 70, // Entry quality must be 70/100+ } } // Usage tracking to prevent excessive API calls export class PaperTradingUsageTracker { private static instance: PaperTradingUsageTracker private analysisCount: Map = new Map() private lastAnalysis: Map = new Map() private dailyCount = 0 private lastReset = new Date().getDate() static getInstance(): PaperTradingUsageTracker { if (!PaperTradingUsageTracker.instance) { PaperTradingUsageTracker.instance = new PaperTradingUsageTracker() } return PaperTradingUsageTracker.instance } canRunAnalysis(symbol: string, timeframe: string): { allowed: boolean, reason?: string } { // Reset daily count if new day const currentDay = new Date().getDate() if (currentDay !== this.lastReset) { this.dailyCount = 0 this.lastReset = currentDay this.analysisCount.clear() } const key = `${symbol}_${timeframe}` const now = Date.now() const lastRun = this.lastAnalysis.get(key) || 0 const timeSinceLastRun = now - lastRun // Check cooldown period (5 minutes) if (timeSinceLastRun < PAPER_TRADING_CONFIG.costControl.timeframeCooldown) { const remainingTime = Math.ceil((PAPER_TRADING_CONFIG.costControl.timeframeCooldown - timeSinceLastRun) / 1000 / 60) return { allowed: false, reason: `Cooldown active. Wait ${remainingTime} minutes before analyzing ${symbol} ${timeframe} again.` } } // Check hourly limit const hourlyCount = this.getHourlyCount() if (hourlyCount >= PAPER_TRADING_CONFIG.costControl.maxAnalysisPerHour) { return { allowed: false, reason: `Hourly limit reached (${PAPER_TRADING_CONFIG.costControl.maxAnalysisPerHour} analyses/hour). Wait for next hour.` } } // Check daily limit for timeframe const timeframeConfig = PAPER_TRADING_CONFIG.selectedTimeframes.find(tf => tf.value === timeframe) const dailyLimit = timeframeConfig?.maxAnalysisPerDay || 10 const dailyCountForTimeframe = this.analysisCount.get(timeframe) || 0 if (dailyCountForTimeframe >= dailyLimit) { return { allowed: false, reason: `Daily limit reached for ${timeframe} timeframe (${dailyLimit} analyses/day).` } } return { allowed: true } } recordAnalysis(symbol: string, timeframe: string): void { const key = `${symbol}_${timeframe}` this.lastAnalysis.set(key, Date.now()) this.analysisCount.set(timeframe, (this.analysisCount.get(timeframe) || 0) + 1) this.dailyCount++ } private getHourlyCount(): number { const oneHourAgo = Date.now() - (60 * 60 * 1000) let count = 0 for (const [, timestamp] of this.lastAnalysis) { if (timestamp > oneHourAgo) { count++ } } return count } getUsageStats() { return { dailyCount: this.dailyCount, estimatedDailyCost: this.dailyCount * PAPER_TRADING_CONFIG.costEstimation.openaiCostPerAnalysis, hourlyCount: this.getHourlyCount(), timeframeCounts: Object.fromEntries(this.analysisCount) } } }