Files
trading_bot_v3/lib/paper-trading-config.ts
mindesbunister 33690f51fa feat: implement real data paper trading system
- Replace mock data with real market analysis in paper trading
- Safe paper trading API now uses live TradingView screenshots and OpenAI analysis
- Maintain complete isolation from live trading while using real market conditions
- Fix Docker build error in automation trade route (removed unreachable code)
- Add safety redirects to prevent accidental live trading access
- Real data includes: live charts, technical indicators, current market conditions
- Analysis time: 30-180s for genuine market analysis vs 5s for mock data
- All safety blocks maintained for zero trading risk learning environment

Tested and verified:
 Container builds and runs successfully
 Real screenshot capture working (TradingView integration)
 OpenAI analysis processing real market data
 Safety systems prevent any actual trading
 Paper trading provides realistic learning experience
2025-08-02 10:22:36 +02:00

166 lines
5.1 KiB
TypeScript

/**
* 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<string, number> = new Map()
private lastAnalysis: Map<string, number> = 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)
}
}
}