// Test Position Scaling DCA - Proper DCA Implementation // This demonstrates how DCA should work: adjust existing position + SL/TP instead of creating new orders async function testPositionScalingDCA() { try { console.log('=== Testing Position Scaling DCA System ===\n'); const baseUrl = process.env.INTERNAL_API_URL || 'http://localhost:9001'; // 1. Check current position console.log('🔍 Checking current position...'); const positionResponse = await fetch(`${baseUrl}/api/drift/positions`); const positionData = await positionResponse.json(); if (!positionData.success || positionData.positions.length === 0) { console.log('❌ No existing position found. Need a position to test DCA scaling.'); console.log('💡 Create a position first, then test the scaling feature.'); return; } const currentPosition = positionData.positions[0]; console.log('✅ Current position found:'); console.log(` ${currentPosition.side} ${currentPosition.size.toFixed(4)} ${currentPosition.symbol}`); console.log(` Entry Price: $${currentPosition.entryPrice.toFixed(4)}`); console.log(` Current Value: $${(currentPosition.size * currentPosition.entryPrice).toFixed(2)}`); console.log(''); // 2. Check existing orders (SL/TP) console.log('📋 Checking existing SL/TP orders...'); const ordersResponse = await fetch(`${baseUrl}/api/drift/orders`); const ordersData = await ordersResponse.json(); if (ordersData.success && ordersData.orders.length > 0) { const reduceOnlyOrders = ordersData.orders.filter(order => order.reduceOnly && order.status === 'OPEN' ); console.log(` Found ${reduceOnlyOrders.length} existing SL/TP orders:`); reduceOnlyOrders.forEach(order => { console.log(` - ${order.orderType}: ${order.side} @ $${order.triggerPrice.toFixed(4)}`); }); } else { console.log(' No existing SL/TP orders found'); } console.log(''); // 3. Create mock AI analysis for optimal levels const mockAIAnalysis = { recommendation: currentPosition.side.toLowerCase() === 'long' ? 'BUY' : 'SELL', confidence: 85, reasoning: 'Test DCA scaling with AI-calculated optimal levels', stopLoss: { price: currentPosition.side.toLowerCase() === 'long' ? currentPosition.entryPrice * 0.98 // 2% below for long : currentPosition.entryPrice * 1.02, // 2% above for short reasoning: 'AI-calculated optimal stop loss level' }, takeProfits: { tp1: { price: currentPosition.side.toLowerCase() === 'long' ? currentPosition.entryPrice * 1.05 // 5% above for long : currentPosition.entryPrice * 0.95, // 5% below for short reasoning: 'AI-calculated optimal take profit level' } } }; console.log('🧠 Mock AI Analysis for DCA:'); console.log(` Recommendation: ${mockAIAnalysis.recommendation} (${mockAIAnalysis.confidence}%)`); console.log(` AI Stop Loss: $${mockAIAnalysis.stopLoss.price.toFixed(4)}`); console.log(` AI Take Profit: $${mockAIAnalysis.takeProfits.tp1.price.toFixed(4)}`); console.log(''); // 4. Execute position scaling DCA const dcaAmount = 25; // Add $25 to position console.log(`💰 Executing Position Scaling DCA: Adding $${dcaAmount}`); console.log('🔧 This will:'); console.log(' 1. Cancel existing SL/TP orders'); console.log(' 2. Add to position size'); console.log(' 3. Calculate new average entry price'); console.log(' 4. Place new SL/TP for ENTIRE scaled position'); console.log(''); const scalingResponse = await fetch(`${baseUrl}/api/drift/scale-position`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dcaAmount: dcaAmount, analysis: mockAIAnalysis }) }); const scalingResult = await scalingResponse.json(); if (scalingResult.success) { console.log('✅ POSITION SCALING SUCCESSFUL!'); console.log(''); console.log('📊 SCALING RESULTS:'); console.log(' ═══ BEFORE ═══'); console.log(` Size: ${scalingResult.scalingResult.originalSize.toFixed(4)} SOL`); console.log(` Entry: $${scalingResult.scalingResult.originalEntryPrice.toFixed(4)}`); console.log(` Value: $${scalingResult.scalingResult.originalValue.toFixed(2)}`); console.log(''); console.log(' ═══ DCA ADDITION ═══'); console.log(` Added: ${scalingResult.scalingResult.dcaSize.toFixed(4)} SOL @ $${scalingResult.scalingResult.dcaPrice.toFixed(4)}`); console.log(` Value: $${scalingResult.scalingResult.dcaValue.toFixed(2)}`); console.log(''); console.log(' ═══ AFTER (SCALED) ═══'); console.log(` Size: ${scalingResult.scalingResult.newTotalSize.toFixed(4)} SOL`); console.log(` Average: $${scalingResult.scalingResult.newAveragePrice.toFixed(4)}`); console.log(` Value: $${scalingResult.scalingResult.newTotalValue.toFixed(2)}`); console.log(''); console.log('🛡️ NEW RISK MANAGEMENT:'); console.log(` Stop Loss: $${scalingResult.scalingResult.newStopLoss.toFixed(4)} (for ENTIRE position)`); console.log(` Take Profit: $${scalingResult.scalingResult.newTakeProfit.toFixed(4)} (for ENTIRE position)`); console.log(` Used AI Levels: ${scalingResult.scalingResult.usedAILevels ? 'YES' : 'NO'}`); console.log(''); console.log('🔗 TRANSACTION IDs:'); console.log(` DCA Trade: ${scalingResult.scalingResult.dcaTxId || 'N/A'}`); console.log(` Stop Loss: ${scalingResult.scalingResult.stopLossTxId || 'N/A'}`); console.log(` Take Profit: ${scalingResult.scalingResult.takeProfitTxId || 'N/A'}`); } else { console.log('❌ POSITION SCALING FAILED:'); console.log(` Error: ${scalingResult.error}`); if (scalingResult.details) { console.log(` Details: ${scalingResult.details}`); } } console.log('\n=== POSITION SCALING vs FRAGMENTED ORDERS ==='); console.log('✅ GOOD (Position Scaling):'); console.log(' • ONE position with adjusted size and average price'); console.log(' • ONE stop loss order covering entire position'); console.log(' • ONE take profit order covering entire position'); console.log(' • Clean order book, unified risk management'); console.log(''); console.log('❌ BAD (Fragmented Orders - what caused 24+ orders):'); console.log(' • Multiple separate positions'); console.log(' • Multiple separate stop loss orders'); console.log(' • Multiple separate take profit orders'); console.log(' • Messy order book, complex risk management'); console.log(''); console.log('💡 SOLUTION: Always use position scaling for DCA!'); console.log('\n=== Test Complete ==='); } catch (error) { console.error('❌ Test failed:', error.message); console.error(error.stack); } } // Run test console.log('🚀 Starting Position Scaling DCA Test...\n'); testPositionScalingDCA();