feat: enhance paper trading with comprehensive AI analysis and learning insights

New Features:
- 📊 Detailed Market Analysis Panel (similar to pro trading interface)
  * Market sentiment, recommendation, resistance/support levels
  * Detailed trading setup with entry/exit points
  * Risk management with R:R ratios and confirmation triggers
  * Technical indicators (RSI, OBV, VWAP) analysis

- 🧠 AI Learning Insights Panel
  * Real-time learning status and success rates
  * Winner/Loser trade outcome tracking
  * AI reflection messages explaining what was learned
  * Current thresholds and pattern recognition data

- 🔮 AI Database Integration
  * Shows what AI learned from previous trades
  * Current confidence thresholds and risk parameters
  * Pattern recognition for symbol/timeframe combinations
  * Next trade adjustments based on learning

- 🎓 Intelligent Learning from Outcomes
  * Automatic trade outcome analysis (winner/loser)
  * AI generates learning insights from each trade result
  * Confidence adjustment based on trade performance
  * Pattern reinforcement or correction based on results

- Beautiful gradient panels with color-coded sections
- Clear winner/loser indicators with visual feedback
- Expandable detailed analysis view
- Real-time learning progress tracking

- Completely isolated paper trading (no real money risk)
- Real market data integration for authentic learning
- Safe practice environment with professional analysis tools

This provides a complete AI learning trading simulation where users can:
1. Get real market analysis with detailed reasoning
2. Execute safe paper trades with zero risk
3. See immediate feedback on trade outcomes
4. Learn from AI reflections and insights
5. Understand how AI adapts and improves over time
This commit is contained in:
mindesbunister
2025-08-02 17:56:02 +02:00
parent 33690f51fa
commit 416f72181e
28 changed files with 4665 additions and 45 deletions

View File

@@ -0,0 +1,423 @@
import OpenAI from 'openai'
import fs from 'fs/promises'
import path from 'path'
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
})
export interface EnhancedAnalysisResult {
summary: string
marketSentiment: 'BULLISH' | 'BEARISH' | 'NEUTRAL'
keyLevels: {
support: number[]
resistance: number[]
}
recommendation: 'BUY' | 'SELL' | 'HOLD'
confidence: number // 0-100
reasoning: string
// Enhanced Anti-Chasing Analysis
momentumStatus: {
type: 'BUILDING' | 'EXHAUSTED' | 'NEUTRAL'
direction: 'UP' | 'DOWN' | 'SIDEWAYS'
exhaustionSignals: string[]
reversalProbability: number // 0-100
}
// Multi-Timeframe Validation
timeframeAlignment: {
trend: '4H' | '1H' | '15M' // Primary trend timeframe
alignment: 'STRONG' | 'WEAK' | 'CONFLICTED'
conflictWarnings: string[]
}
// Enhanced Entry Conditions
entryQuality: {
score: number // 0-100
requiredConfirmations: string[]
missingConfirmations: string[]
riskLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'EXTREME'
}
// Risk-Adjusted Trading Levels
entry?: {
price: number
buffer?: string
rationale: string
timeframeRisk: 'LOW' | 'MEDIUM' | 'HIGH'
}
stopLoss?: {
price: number
rationale: string
atrMultiple: number // ATR-based stop calculation
}
takeProfits?: {
tp1?: {
price: number
description: string
probabilityReach: number // 0-100
}
tp2?: {
price: number
description: string
probabilityReach: number // 0-100
}
}
riskToReward?: string
// Advanced Confirmations
confirmationTrigger?: string
invalidationLevel?: number
// Position Sizing Guidance
positionSizing?: {
riskPercentage: number // Recommended risk per trade
maxPositionSize: number // Maximum recommended position
volatilityAdjustment: number // Adjustment for current volatility
}
}
export class EnhancedAntiChasingAI {
async analyzeWithAntiChasing(filenameOrPath: string): Promise<EnhancedAnalysisResult | null> {
try {
let imagePath: string
if (path.isAbsolute(filenameOrPath)) {
imagePath = filenameOrPath
} else {
const screenshotsDir = path.join(process.cwd(), 'screenshots')
imagePath = path.join(screenshotsDir, filenameOrPath)
}
const imageBuffer = await fs.readFile(imagePath)
const base64Image = imageBuffer.toString('base64')
const prompt = `You are an expert trading analyst specializing in ANTI-MOMENTUM CHASING and HIGH-PROBABILITY setups. Your goal is to prevent losses from entering trades after momentum has exhausted.
**CRITICAL MISSION: PREVENT MOMENTUM CHASING LOSSES**
Your analysis must focus on:
1. **MOMENTUM EXHAUSTION DETECTION** - Identify when moves are ENDING, not beginning
2. **MULTI-TIMEFRAME VALIDATION** - Ensure all timeframes agree before entry
3. **HIGH-PROBABILITY REVERSALS** - Only recommend trades with strong reversal signals
4. **RISK-ADJUSTED ENTRIES** - Match position size to timeframe risk
**ANTI-CHASING METHODOLOGY:**
**MOMENTUM EXHAUSTION SIGNALS:**
- **RSI DIVERGENCE**: Price making new highs/lows but RSI showing divergence
- **VOLUME EXHAUSTION**: Decreasing volume on continued price movement
- **CANDLE PATTERNS**: Doji, shooting stars, hammers at key levels
- **MULTIPLE REJECTIONS**: 2+ rejections at support/resistance
- **OVEREXTENSION**: Price far from moving averages (>2 ATR)
**TIMEFRAME RISK ASSESSMENT:**
- **15M Charts**: HIGH RISK - Require 85%+ confidence, tight stops
- **1H Charts**: MEDIUM RISK - Require 80%+ confidence, moderate stops
- **4H Charts**: LOW RISK - Require 75%+ confidence, wider stops
- **Daily Charts**: LOWEST RISK - Require 70%+ confidence, structural stops
**ENTRY QUALITY CHECKLIST:**
✅ **Momentum Exhausted**: Not chasing active moves
✅ **Multiple Confirmations**: 3+ indicators agree
✅ **Structure Support**: Near key support/resistance
✅ **Volume Confirmation**: Volume supports the setup
✅ **Risk/Reward**: Minimum 1:2 ratio
✅ **Invalidation Clear**: Know exactly when wrong
**FORBIDDEN SETUPS (NEVER RECOMMEND):**
❌ **Chasing Breakouts**: Price already moved >2% rapidly
❌ **FOMO Entries**: Strong moves without pullbacks
❌ **Single Indicator**: Only one confirmation signal
❌ **Against Trend**: Counter-trend without clear reversal
❌ **Poor R:R**: Risk/Reward worse than 1:2
❌ **Unclear Stops**: No obvious stop loss level
**ANALYSIS PROCESS:**
1. **IDENTIFY MOMENTUM STATE**:
- Is momentum BUILDING (early in move) or EXHAUSTED (late in move)?
- Look for divergences, volume patterns, overextension
2. **CHECK TIMEFRAME ALIGNMENT**:
- Do multiple timeframes agree on direction?
- Is this the right timeframe for this setup?
3. **VALIDATE ENTRY QUALITY**:
- Count confirmation signals (need 3+ for entry)
- Assess risk level and position sizing needs
4. **CALCULATE RISK-ADJUSTED LEVELS**:
- Entry: Based on structure and confirmation
- Stop Loss: ATR-based, below/above key structure
- Take Profit: Conservative targets with high probability
**RESPONSE FORMAT** (JSON only):
{
"summary": "Anti-chasing analysis focusing on momentum exhaustion and high-probability setups",
"marketSentiment": "BULLISH|BEARISH|NEUTRAL",
"keyLevels": {
"support": [visible support levels],
"resistance": [visible resistance levels]
},
"recommendation": "BUY|SELL|HOLD",
"confidence": 75,
"reasoning": "Detailed reasoning focusing on momentum state and entry quality",
"momentumStatus": {
"type": "BUILDING|EXHAUSTED|NEUTRAL",
"direction": "UP|DOWN|SIDEWAYS",
"exhaustionSignals": ["List specific exhaustion signals seen"],
"reversalProbability": 65
},
"timeframeAlignment": {
"trend": "4H|1H|15M",
"alignment": "STRONG|WEAK|CONFLICTED",
"conflictWarnings": ["Any timeframe conflicts"]
},
"entryQuality": {
"score": 85,
"requiredConfirmations": ["List of confirmations present"],
"missingConfirmations": ["List of missing confirmations"],
"riskLevel": "LOW|MEDIUM|HIGH|EXTREME"
},
"entry": {
"price": 150.50,
"buffer": "±0.25",
"rationale": "Entry based on exhaustion signals and structure",
"timeframeRisk": "LOW|MEDIUM|HIGH"
},
"stopLoss": {
"price": 148.00,
"rationale": "Stop below key structure level",
"atrMultiple": 1.5
},
"takeProfits": {
"tp1": {
"price": 152.00,
"description": "Conservative target at structure",
"probabilityReach": 75
},
"tp2": {
"price": 154.00,
"description": "Extended target if momentum continues",
"probabilityReach": 45
}
},
"riskToReward": "1:2.5",
"confirmationTrigger": "Wait for specific confirmation before entry",
"invalidationLevel": 149.00,
"positionSizing": {
"riskPercentage": 1.0,
"maxPositionSize": 10,
"volatilityAdjustment": 0.8
}
}
**CRITICAL REQUIREMENTS:**
- If momentum appears to be chasing, recommend HOLD regardless of other signals
- Require minimum 3 confirmations for any BUY/SELL recommendation
- Always provide clear invalidation levels
- Match position sizing to timeframe risk
- Focus on HIGH-PROBABILITY setups only
Analyze the chart with EXTREME FOCUS on preventing momentum chasing losses.`
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "user",
content: [
{ type: "text", text: prompt },
{
type: "image_url",
image_url: {
url: `data:image/png;base64,${base64Image}`,
detail: "high"
}
}
]
}
],
max_tokens: 2000,
temperature: 0.1
})
const content = response.choices[0]?.message?.content
if (!content) return null
console.log('🛡️ Anti-chasing AI response:', content.substring(0, 200) + '...')
// Extract JSON from response
const match = content.match(/\{[\s\S]*\}/)
if (!match) {
console.error('No JSON found in anti-chasing response')
return null
}
const json = match[0]
const result = JSON.parse(json)
// Validate anti-chasing requirements
if (result.entryQuality?.score < 70) {
console.log('⚠️ Entry quality too low - overriding to HOLD')
result.recommendation = 'HOLD'
result.reasoning = `Entry quality score ${result.entryQuality.score} is below minimum threshold. ${result.reasoning}`
}
if (result.momentumStatus?.type === 'EXHAUSTED' && result.confidence > 80) {
console.log('✅ High-quality exhaustion setup detected')
} else if (result.momentumStatus?.type === 'BUILDING') {
console.log('⚠️ Potential momentum chasing detected - increasing requirements')
result.confidence = Math.max(0, result.confidence - 20)
}
return result as EnhancedAnalysisResult
} catch (error) {
console.error('❌ Enhanced anti-chasing analysis failed:', error)
return null
}
}
async analyzeMultipleWithAntiChasing(filenamesOrPaths: string[]): Promise<EnhancedAnalysisResult | null> {
try {
// Read all image files and convert to base64
const images = await Promise.all(
filenamesOrPaths.map(async (filenameOrPath) => {
let imagePath: string
if (path.isAbsolute(filenameOrPath)) {
imagePath = filenameOrPath
} else {
const screenshotsDir = path.join(process.cwd(), 'screenshots')
imagePath = path.join(screenshotsDir, filenameOrPath)
}
const imageBuffer = await fs.readFile(imagePath)
const base64Image = imageBuffer.toString('base64')
return {
type: "image_url" as const,
image_url: {
url: `data:image/png;base64,${base64Image}`,
detail: "high" as const
}
}
})
)
const timeframeInfo = filenamesOrPaths.map(f => {
const filename = path.basename(f)
if (filename.includes('240')) return '4H'
if (filename.includes('60')) return '1H'
if (filename.includes('15')) return '15M'
return 'Unknown'
}).join(', ')
const prompt = `You are analyzing ${filenamesOrPaths.length} charts (${timeframeInfo}) with ANTI-MOMENTUM CHASING focus.
**MISSION: PREVENT MOMENTUM CHASING ACROSS MULTIPLE TIMEFRAMES**
**MULTI-TIMEFRAME ANTI-CHASING RULES:**
1. **TIMEFRAME HIERARCHY**:
- 4H: Primary trend direction (most important)
- 1H: Entry confirmation and timing
- 15M: Precise entry point and quick confirmations
2. **ALIGNMENT REQUIREMENTS**:
- ALL timeframes must agree on direction for entry
- Higher timeframes override lower timeframes
- If conflict exists, recommend HOLD
3. **MOMENTUM EXHAUSTION VALIDATION**:
- Check each timeframe for exhaustion signals
- Look for divergences across timeframes
- Ensure not chasing moves on any timeframe
4. **MULTI-TIMEFRAME CONFIRMATION**:
- Need confirmation on AT LEAST 2 timeframes
- Higher timeframe structure + lower timeframe entry
- Volume confirmation across timeframes
**ANALYSIS REQUIREMENTS:**
For each timeframe:
- Identify momentum state (building/exhausted/neutral)
- Check for exhaustion signals and reversals
- Validate entry quality and confirmations
- Assess risk level for that timeframe
Cross-timeframe validation:
- Ensure no conflicts between timeframes
- Confirm entry timing on appropriate timeframe
- Validate stop loss placement across timeframes
**FORBIDDEN MULTI-TIMEFRAME SETUPS:**
❌ Timeframes pointing in different directions
❌ Chasing momentum on any timeframe
❌ Entry without multi-timeframe confirmation
❌ Risk/reward not suitable for highest timeframe
Provide comprehensive multi-timeframe anti-chasing analysis in the same JSON format, with additional focus on timeframe alignment and cross-validation.`
const messages = [
{
role: "user" as const,
content: [
{ type: "text" as const, text: prompt },
...images
]
}
]
console.log(`🛡️ Analyzing ${filenamesOrPaths.length} timeframes with anti-chasing focus...`)
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages,
max_tokens: 2500,
temperature: 0.1
})
const content = response.choices[0]?.message?.content
if (!content) {
throw new Error('No response from OpenAI')
}
const jsonMatch = content.match(/\{[\s\S]*\}/)
if (!jsonMatch) {
throw new Error('No JSON found in multi-timeframe response')
}
const analysis = JSON.parse(jsonMatch[0])
// Enhanced validation for multi-timeframe
if (analysis.timeframeAlignment?.alignment === 'CONFLICTED') {
console.log('⚠️ Timeframe conflict detected - overriding to HOLD')
analysis.recommendation = 'HOLD'
analysis.confidence = Math.min(analysis.confidence, 40)
}
console.log('✅ Multi-timeframe anti-chasing analysis complete')
return analysis as EnhancedAnalysisResult
} catch (error: any) {
console.error('❌ Multi-timeframe anti-chasing analysis failed:', error.message)
return null
}
}
}
export const enhancedAntiChasingAI = new EnhancedAntiChasingAI()

View File

@@ -0,0 +1,305 @@
/**
* Enhanced Risk Management System
*
* Addresses the core issues that caused 47% account loss:
* 1. Proper position sizing based on account balance and risk tolerance
* 2. Dynamic stop losses based on market volatility (ATR)
* 3. Timeframe-appropriate risk management
* 4. Anti-overtrading mechanisms
* 5. Emergency stop loss protection
*/
// import { getDB } from './db'
export interface RiskAssessment {
accountBalance: number
currentRisk: number // Percentage of account at risk
maxPositionSize: number // Maximum $ amount for next trade
recommendedSize: number // Recommended $ amount for next trade
stopLossDistance: number // Distance to stop loss in $
riskRewardRatio: number
leverageRecommendation: number
timeframeRisk: 'LOW' | 'MEDIUM' | 'HIGH' | 'EXTREME'
coolingOffRequired: boolean
riskWarnings: string[]
}
export interface TradeRiskParameters {
symbol: string
direction: 'LONG' | 'SHORT'
entryPrice: number
stopLoss: number
takeProfit: number
timeframe: string
currentBalance: number
recentLosses: number // Recent consecutive losses
}
export class EnhancedRiskManager {
private readonly MAX_RISK_PER_TRADE = 1.0 // 1% max risk per trade
private readonly MAX_TOTAL_RISK = 5.0 // 5% max total account risk
private readonly COOLING_OFF_HOURS = 24 // Hours to wait after 2 consecutive losses
private readonly MAX_CONSECUTIVE_LOSSES = 2
// ATR multipliers for different timeframes
private readonly ATR_MULTIPLIERS: Record<string, number> = {
'5': 1.0, // 5m: Tight stops
'15': 1.5, // 15m: Moderate stops
'30': 2.0, // 30m: Wider stops
'60': 2.5, // 1h: Standard stops
'240': 3.0, // 4h: Wide stops
'D': 4.0 // Daily: Very wide stops
}
// Risk level based on timeframe
private readonly TIMEFRAME_RISK: Record<string, string> = {
'5': 'EXTREME',
'15': 'HIGH',
'30': 'HIGH',
'60': 'MEDIUM',
'240': 'LOW',
'D': 'LOW'
}
async assessTradeRisk(params: TradeRiskParameters): Promise<RiskAssessment> {
const {
symbol,
direction,
entryPrice,
stopLoss,
takeProfit,
timeframe,
currentBalance,
recentLosses
} = params
console.log('🛡️ Enhanced Risk Assessment Starting...')
console.log(`💰 Account Balance: $${currentBalance}`)
console.log(`📊 Trade: ${direction} ${symbol} @ $${entryPrice}`)
console.log(`🛑 Stop Loss: $${stopLoss}`)
console.log(`🎯 Take Profit: $${takeProfit}`)
console.log(`⏰ Timeframe: ${timeframe}`)
console.log(`📉 Recent Losses: ${recentLosses}`)
const warnings: string[] = []
// Calculate stop loss distance
const stopLossDistance = Math.abs(entryPrice - stopLoss)
const stopLossPercentage = (stopLossDistance / entryPrice) * 100
// Calculate risk/reward ratio
const takeProfitDistance = Math.abs(takeProfit - entryPrice)
const riskRewardRatio = takeProfitDistance / stopLossDistance
console.log(`📏 Stop Loss Distance: $${stopLossDistance.toFixed(2)} (${stopLossPercentage.toFixed(2)}%)`)
console.log(`📈 Risk/Reward Ratio: 1:${riskRewardRatio.toFixed(2)}`)
// Check if cooling off period is required
const coolingOffRequired = recentLosses >= this.MAX_CONSECUTIVE_LOSSES
if (coolingOffRequired) {
warnings.push(`🚨 COOLING OFF: ${recentLosses} consecutive losses detected. Wait ${this.COOLING_OFF_HOURS}h before next trade.`)
}
// Get timeframe risk level
const timeframeRisk = this.TIMEFRAME_RISK[timeframe] || 'HIGH'
// Adjust max risk based on timeframe and recent performance
let adjustedMaxRisk = this.MAX_RISK_PER_TRADE
if (timeframeRisk === 'EXTREME') {
adjustedMaxRisk = 0.5 // 0.5% for very short timeframes
warnings.push('⚠️ EXTREME RISK: Very short timeframe detected. Risk reduced to 0.5%')
} else if (timeframeRisk === 'HIGH') {
adjustedMaxRisk = 0.75 // 0.75% for high risk timeframes
warnings.push('⚠️ HIGH RISK: Short timeframe detected. Risk reduced to 0.75%')
}
// Further reduce risk after losses
if (recentLosses >= 1) {
adjustedMaxRisk *= 0.5 // Halve risk after any recent loss
warnings.push(`📉 Risk halved due to ${recentLosses} recent loss(es)`)
}
// Calculate position sizes
const riskAmount = currentBalance * (adjustedMaxRisk / 100)
const maxPositionSize = currentBalance * 0.1 // Never more than 10% of account
const recommendedSize = Math.min(riskAmount / (stopLossPercentage / 100), maxPositionSize)
console.log(`💵 Risk Amount: $${riskAmount.toFixed(2)} (${adjustedMaxRisk}% of balance)`)
console.log(`📦 Max Position Size: $${maxPositionSize.toFixed(2)}`)
console.log(`✅ Recommended Size: $${recommendedSize.toFixed(2)}`)
// Risk/Reward validation
if (riskRewardRatio < 1.5) {
warnings.push(`⚠️ POOR R:R: Risk/Reward ${riskRewardRatio.toFixed(2)} is below minimum 1.5`)
}
// Stop loss distance validation
if (stopLossPercentage > 5) {
warnings.push(`⚠️ WIDE STOP: ${stopLossPercentage.toFixed(2)}% stop loss is very wide`)
}
// Calculate current account risk
const currentRisk = await this.calculateCurrentAccountRisk(currentBalance)
if (currentRisk > this.MAX_TOTAL_RISK) {
warnings.push(`🚨 MAX RISK: Current account risk ${currentRisk.toFixed(1)}% exceeds maximum ${this.MAX_TOTAL_RISK}%`)
}
// Leverage recommendation based on timeframe and risk
let leverageRecommendation = 1
if (timeframeRisk === 'LOW' && riskRewardRatio >= 2) {
leverageRecommendation = 2
} else if (timeframeRisk === 'MEDIUM' && riskRewardRatio >= 2.5) {
leverageRecommendation = 1.5
}
const assessment: RiskAssessment = {
accountBalance: currentBalance,
currentRisk,
maxPositionSize,
recommendedSize,
stopLossDistance,
riskRewardRatio,
leverageRecommendation,
timeframeRisk: timeframeRisk as any,
coolingOffRequired,
riskWarnings: warnings
}
console.log('🛡️ Risk Assessment Complete:')
console.log(` Current Risk: ${currentRisk.toFixed(1)}%`)
console.log(` Recommended Size: $${recommendedSize.toFixed(2)}`)
console.log(` R:R Ratio: 1:${riskRewardRatio.toFixed(2)}`)
console.log(` Timeframe Risk: ${timeframeRisk}`)
console.log(` Warnings: ${warnings.length}`)
return assessment
}
async calculateCurrentAccountRisk(currentBalance: number): Promise<number> {
try {
// For now, return 0 as a safe default
// TODO: Implement database integration when available
console.log('📊 Current Account Risk: Database not available, returning 0%')
return 0
} catch (error) {
console.error('❌ Error calculating account risk:', error)
return 0
}
}
async getRecentLossCount(): Promise<number> {
try {
// For now, return 0 as a safe default
// TODO: Implement database integration when available
console.log('📉 Recent consecutive losses: Database not available, returning 0')
return 0
} catch (error) {
console.error('❌ Error getting recent loss count:', error)
return 0
}
}
calculateDynamicStopLoss(
entryPrice: number,
direction: 'LONG' | 'SHORT',
timeframe: string,
atr?: number
): number {
// Use ATR if available, otherwise use percentage-based stop
const atrMultiplier = this.ATR_MULTIPLIERS[timeframe] || 2.0
let stopDistance: number
if (atr && atr > 0) {
stopDistance = atr * atrMultiplier
console.log(`📏 ATR-based stop: ${atr} * ${atrMultiplier} = ${stopDistance}`)
} else {
// Fallback to percentage-based stops
const percentageStop = timeframe === '5' ? 0.5 :
timeframe === '15' ? 1.0 :
timeframe === '60' ? 1.5 : 2.0
stopDistance = entryPrice * (percentageStop / 100)
console.log(`📏 Percentage-based stop: ${percentageStop}% = ${stopDistance}`)
}
const stopLoss = direction === 'LONG'
? entryPrice - stopDistance
: entryPrice + stopDistance
console.log(`🛑 Dynamic Stop Loss: $${stopLoss.toFixed(2)} (${direction})`)
return parseFloat(stopLoss.toFixed(2))
}
async shouldAllowTrade(params: TradeRiskParameters): Promise<{
allowed: boolean
reason: string
riskAssessment: RiskAssessment
}> {
const riskAssessment = await this.assessTradeRisk(params)
// Check cooling off period
if (riskAssessment.coolingOffRequired) {
return {
allowed: false,
reason: 'Cooling off period required after consecutive losses',
riskAssessment
}
}
// Check if account risk is too high
if (riskAssessment.currentRisk > this.MAX_TOTAL_RISK) {
return {
allowed: false,
reason: `Total account risk ${riskAssessment.currentRisk.toFixed(1)}% exceeds maximum ${this.MAX_TOTAL_RISK}%`,
riskAssessment
}
}
// Check risk/reward ratio
if (riskAssessment.riskRewardRatio < 1.5) {
return {
allowed: false,
reason: `Risk/Reward ratio ${riskAssessment.riskRewardRatio.toFixed(2)} is below minimum 1.5`,
riskAssessment
}
}
// Check if recommended size is too small
if (riskAssessment.recommendedSize < 10) {
return {
allowed: false,
reason: 'Recommended position size too small - market conditions may be unsuitable',
riskAssessment
}
}
return {
allowed: true,
reason: 'Trade approved by risk management',
riskAssessment
}
}
async recordTradeDecision(
decision: 'APPROVED' | 'REJECTED',
reason: string,
riskAssessment: RiskAssessment
): Promise<void> {
try {
// For now, just log the decision
// TODO: Implement database integration when available
console.log(`📝 Risk decision recorded: ${decision} - ${reason}`)
console.log(` Account Balance: $${riskAssessment.accountBalance}`)
console.log(` Current Risk: ${riskAssessment.currentRisk}%`)
console.log(` Recommended Size: $${riskAssessment.recommendedSize}`)
console.log(` R:R Ratio: 1:${riskAssessment.riskRewardRatio}`)
} catch (error) {
console.error('❌ Error recording risk decision:', error)
}
}
}
export const enhancedRiskManager = new EnhancedRiskManager()

View File

@@ -300,21 +300,19 @@ class SimpleAutomation {
// Increment error counter
this.stats.consecutiveErrors = (this.stats.consecutiveErrors || 0) + 1;
// If too many consecutive errors, slow down but NEVER stop completely
if (this.stats.consecutiveErrors >= 20) { // Increased from 3 to 20
console.warn(`⚠️ HIGH ERROR COUNT: ${this.stats.consecutiveErrors} consecutive failures. Slowing down but continuing...`);
// Add extra delay instead of stopping
await new Promise(resolve => setTimeout(resolve, 30000)); // 30 second delay
// Reset error count to prevent infinite accumulation
this.stats.consecutiveErrors = Math.floor(this.stats.consecutiveErrors / 2);
} else if (this.stats.consecutiveErrors >= 10) {
console.warn(`⚠️ NETWORK ISSUES: ${this.stats.consecutiveErrors} consecutive failures. Adding delay...`);
// Add delay for network issues
await new Promise(resolve => setTimeout(resolve, 10000)); // 10 second delay
// If too many consecutive errors, stop automation
if (this.stats.consecutiveErrors >= 3) {
console.error('🚨 TOO MANY ERRORS: Stopping automation after', this.stats.consecutiveErrors, 'consecutive failures');
this.isRunning = false;
this.stats.status = 'Stopped due to errors';
if (this.intervalId) {
clearTimeout(this.intervalId); // Changed from clearInterval to clearTimeout
this.intervalId = null;
}
return;
}
// NEVER STOP AUTOMATION - Money Printing Machine must keep running!
console.log(`⚠️ Error ${this.stats.consecutiveErrors}/3 - Will retry next cycle`);
}
}