feat: Add automation V2 page with multi-timeframe support

- Complete multi-timeframe selection UI (5m, 15m, 30m, 1h, 2h, 4h, 1d)
- Checkbox-based timeframe selection with visual indicators
- Quick preset buttons (Scalping, Day Trading, Swing Trading)
- Auto-sizing position calculator based on balance percentage
- Leverage position size calculations and display
- Properly formatted wallet balance display (fixed decimal places)
- Real-time balance integration with usage percentages
- Clean, fresh codebase without Docker volume mount issues
- Full feature parity with original automation page plus enhancements

Accessible at /automation-v2 route
This commit is contained in:
mindesbunister
2025-07-23 08:32:42 +02:00
parent ef3619627d
commit 730629a271
7 changed files with 1666 additions and 26 deletions

View File

@@ -413,7 +413,7 @@ export class AutomationService {
console.log(`🚀 Executing ${config.mode} trade: ${analysis.recommendation} ${config.symbol}`)
const side = analysis.recommendation === 'BUY' ? 'BUY' : 'SELL'
const amount = this.calculateTradeAmount(config, analysis)
const amount = await this.calculateTradeAmount(config, analysis)
const leverage = Math.min(config.maxLeverage, 3) // Cap at 3x for safety
let tradeResult: any = null
@@ -559,20 +559,58 @@ export class AutomationService {
}
}
private calculateTradeAmount(config: AutomationConfig, analysis: AnalysisResult): number {
// Base amount from config
let amount = config.tradingAmount
private async calculateTradeAmount(config: AutomationConfig, analysis: AnalysisResult): Promise<number> {
try {
// Fetch actual account balance from Drift
console.log('💰 Fetching account balance for position sizing...')
const balanceResponse = await fetch(`http://localhost:3000/api/drift/balance`)
if (!balanceResponse.ok) {
console.log('⚠️ Failed to fetch balance, using fallback calculation')
// Fallback to config amount
let amount = Math.min(config.tradingAmount, 35) // Cap at $35 max
const riskAdjustment = config.riskPercentage / 100
return Math.max(amount * riskAdjustment, 5)
}
// Adjust based on confidence
const confidenceMultiplier = Math.min(analysis.confidence / 100, 1)
amount *= confidenceMultiplier
const balanceData = await balanceResponse.json()
const availableBalance = parseFloat(balanceData.availableBalance || '0')
console.log(`💰 Available balance: $${availableBalance}`)
// Adjust based on risk percentage
const riskAdjustment = config.riskPercentage / 100
amount *= riskAdjustment
if (availableBalance <= 0) {
throw new Error('No available balance')
}
// Ensure minimum trade amount
return Math.max(amount, 10)
// Calculate position size based on risk percentage of available balance
const riskAmount = availableBalance * (config.riskPercentage / 100)
// Adjust based on confidence (reduce risk for low confidence signals)
const confidenceMultiplier = Math.min(analysis.confidence / 100, 1)
let amount = riskAmount * confidenceMultiplier
// Apply leverage to get position size
amount *= Math.min(config.maxLeverage, 10)
// Ensure minimum trade amount but cap at available balance
amount = Math.max(amount, 5) // Minimum $5 position
amount = Math.min(amount, availableBalance * 0.8) // Never use more than 80% of balance
console.log(`📊 Position sizing calculation:`)
console.log(` - Available balance: $${availableBalance}`)
console.log(` - Risk percentage: ${config.riskPercentage}%`)
console.log(` - Risk amount: $${riskAmount.toFixed(2)}`)
console.log(` - Confidence multiplier: ${confidenceMultiplier}`)
console.log(` - Leverage: ${Math.min(config.maxLeverage, 10)}x`)
console.log(` - Final position size: $${amount.toFixed(2)}`)
return Math.round(amount * 100) / 100 // Round to 2 decimal places
} catch (error) {
console.log(`⚠️ Error calculating trade amount: ${error instanceof Error ? error.message : String(error)}`)
// Safe fallback - use small fixed amount
return 5
}
}
private parseRiskReward(rrString: string): number {