/** * Simple DCA Test - Direct Implementation * Tests DCA logic without TypeScript compilation issues */ // Simplified DCA analysis logic (extracted from TypeScript version) function analyzeDCAOpportunity(params) { const { currentPosition, accountStatus, marketData, maxLeverageAllowed } = params console.log('๐Ÿ”„ AI DCA Analysis:', { position: `${currentPosition.side} ${currentPosition.size} @ $${currentPosition.entryPrice}`, currentPrice: `$${marketData.price}`, pnl: `$${currentPosition.unrealizedPnl.toFixed(2)}`, availableBalance: `$${accountStatus.availableBalance.toFixed(2)}` }) // Step 1: Analyze reversal potential const reversalAnalysis = analyzeReversalPotential(currentPosition, marketData) if (!reversalAnalysis.hasReversalPotential) { return { shouldDCA: false, dcaAmount: 0, newAveragePrice: currentPosition.entryPrice, newStopLoss: currentPosition.stopLoss, newTakeProfit: currentPosition.takeProfit, newLeverage: accountStatus.leverage, newLiquidationPrice: accountStatus.liquidationPrice, riskAssessment: 'HIGH', reasoning: reversalAnalysis.reasoning, confidence: 0 } } // Step 2: Calculate safe DCA amount const dcaCalculation = calculateSafeDCAAmount(currentPosition, accountStatus, marketData, maxLeverageAllowed) if (dcaCalculation.dcaAmount === 0) { return { shouldDCA: false, dcaAmount: 0, newAveragePrice: currentPosition.entryPrice, newStopLoss: currentPosition.stopLoss, newTakeProfit: currentPosition.takeProfit, newLeverage: accountStatus.leverage, newLiquidationPrice: accountStatus.liquidationPrice, riskAssessment: 'HIGH', reasoning: dcaCalculation.reasoning, confidence: 0 } } // Step 3: Calculate new position parameters const newPositionSize = currentPosition.size + dcaCalculation.dcaAmount const newAveragePrice = calculateNewAveragePrice( currentPosition.size, currentPosition.entryPrice, dcaCalculation.dcaAmount, marketData.price ) // Step 4: Calculate new stop loss and take profit const newSLTP = calculateNewStopLossAndTakeProfit( currentPosition.side, newAveragePrice, newPositionSize, marketData, reversalAnalysis.confidence ) // Step 5: Calculate new leverage and liquidation price const newLeverage = calculateNewLeverage(newPositionSize, newAveragePrice, accountStatus.accountValue, dcaCalculation.dcaAmount) const newLiquidationPrice = calculateNewLiquidationPrice(newAveragePrice, newLeverage, currentPosition.side) // Step 6: Final risk assessment const riskAssessment = assessDCARisk(newLeverage, newLiquidationPrice, newSLTP.stopLoss, accountStatus.availableBalance, dcaCalculation.dcaAmount) return { shouldDCA: true, dcaAmount: dcaCalculation.dcaAmount, newAveragePrice, newStopLoss: newSLTP.stopLoss, newTakeProfit: newSLTP.takeProfit, newLeverage, newLiquidationPrice, riskAssessment, reasoning: `${reversalAnalysis.reasoning}. ${dcaCalculation.reasoning}. New average: $${newAveragePrice.toFixed(4)} with ${newLeverage.toFixed(1)}x leverage.`, confidence: reversalAnalysis.confidence } } function analyzeReversalPotential(position, marketData) { const priceMovement = ((marketData.price - position.entryPrice) / position.entryPrice) * 100 const isMovingAgainstPosition = (position.side === 'long' && priceMovement < 0) || (position.side === 'short' && priceMovement > 0) if (!isMovingAgainstPosition) { return { hasReversalPotential: false, reasoning: "Price moving in our favor - no DCA needed", confidence: 0 } } let confidence = 0 const reasons = [] // Factor 1: Price drop magnitude const movementMagnitude = Math.abs(priceMovement) if (movementMagnitude >= 1 && movementMagnitude <= 5) { confidence += 30 reasons.push(`${movementMagnitude.toFixed(1)}% movement creates DCA opportunity`) } else if (movementMagnitude > 5 && movementMagnitude <= 10) { confidence += 40 reasons.push(`${movementMagnitude.toFixed(1)}% movement shows strong discount`) } else if (movementMagnitude > 10) { confidence += 20 reasons.push(`${movementMagnitude.toFixed(1)}% movement may indicate trend change`) } // Factor 2: 24h price change context if (marketData.priceChange24h !== undefined) { if (position.side === 'long' && marketData.priceChange24h < -3) { confidence += 25 reasons.push("24h downtrend creates long DCA opportunity") } else if (position.side === 'short' && marketData.priceChange24h > 3) { confidence += 25 reasons.push("24h uptrend creates short DCA opportunity") } } // Factor 3: Support/Resistance levels if (marketData.support && position.side === 'long' && marketData.price <= marketData.support * 1.02) { confidence += 20 reasons.push("Price near support level") } if (marketData.resistance && position.side === 'short' && marketData.price >= marketData.resistance * 0.98) { confidence += 20 reasons.push("Price near resistance level") } // Factor 4: RSI oversold/overbought if (marketData.rsi !== undefined) { if (position.side === 'long' && marketData.rsi < 35) { confidence += 15 reasons.push("RSI oversold - reversal likely") } else if (position.side === 'short' && marketData.rsi > 65) { confidence += 15 reasons.push("RSI overbought - reversal likely") } } const hasReversalPotential = confidence >= 50 return { hasReversalPotential, reasoning: hasReversalPotential ? reasons.join(", ") : `Insufficient reversal signals (${confidence}% confidence)`, confidence } } function calculateSafeDCAAmount(position, accountStatus, marketData, maxLeverageAllowed) { // Simple leverage calculation (using basic 3x leverage for DCA) const maxDCAUSD = accountStatus.availableBalance * 0.3 // Use 30% of available balance const leveragedDCAAmount = maxDCAUSD * 3 // 3x leverage for safety const dcaTokenAmount = leveragedDCAAmount / marketData.price // Ensure DCA doesn't make position too large const currentPositionValue = position.size * position.entryPrice const maxPositionValue = accountStatus.accountValue * 2 // Max 2x account value const remainingCapacity = maxPositionValue - currentPositionValue const finalDCAAmount = Math.min( dcaTokenAmount, remainingCapacity / marketData.price, position.size * 0.4 // Max 40% of current position size ) if (finalDCAAmount < 0.01) { return { dcaAmount: 0, reasoning: "Insufficient available balance or position capacity for safe DCA" } } return { dcaAmount: finalDCAAmount, reasoning: `Safe DCA: ${finalDCAAmount.toFixed(4)} tokens using 3x leverage` } } function calculateNewAveragePrice(currentSize, currentPrice, dcaSize, dcaPrice) { const totalValue = (currentSize * currentPrice) + (dcaSize * dcaPrice) const totalSize = currentSize + dcaSize return totalValue / totalSize } function calculateNewStopLossAndTakeProfit(side, newAveragePrice, newPositionSize, marketData, confidence) { const baseStopLossPercent = 2.5 // Base 2.5% stop loss const baseTakeProfitPercent = confidence > 70 ? 7 : 5 // Higher TP if very confident let stopLoss, takeProfit if (side === 'long') { stopLoss = newAveragePrice * (1 - baseStopLossPercent / 100) takeProfit = newAveragePrice * (1 + baseTakeProfitPercent / 100) } else { stopLoss = newAveragePrice * (1 + baseStopLossPercent / 100) takeProfit = newAveragePrice * (1 - baseTakeProfitPercent / 100) } return { stopLoss, takeProfit } } function calculateNewLeverage(newPositionSize, newAveragePrice, accountValue, dcaAmount) { const totalPositionValue = newPositionSize * newAveragePrice return totalPositionValue / accountValue } function calculateNewLiquidationPrice(averagePrice, leverage, side) { if (side === 'long') { return averagePrice * (1 - 1/leverage) } else { return averagePrice * (1 + 1/leverage) } } function assessDCARisk(newLeverage, liquidationPrice, stopLoss, availableBalance, dcaAmount) { const liquidationBuffer = Math.abs(liquidationPrice - stopLoss) / stopLoss * 100 const balanceUsagePercent = (dcaAmount * liquidationPrice) / availableBalance * 100 if (newLeverage <= 4 && liquidationBuffer >= 15 && balanceUsagePercent <= 30) return 'LOW' if (newLeverage <= 8 && liquidationBuffer >= 10 && balanceUsagePercent <= 50) return 'MEDIUM' return 'HIGH' } // Test the DCA system with SOL screenshot data async function testSOLDCA() { console.log('๐Ÿงช Testing AI DCA Manager with SOL Position Data') console.log('=' .repeat(60)) // Real data from the screenshot const testParams = { currentPosition: { side: 'long', size: 2.69, // SOL amount from screenshot entryPrice: 185.98, currentPrice: 183.87, unrealizedPnl: -6.73, // From screenshot (red, losing position) stopLoss: 181.485, // From screenshot takeProfit: 187.12 // From screenshot }, accountStatus: { accountValue: 2789.44, // Max amount from screenshot availableBalance: 1200, // Estimated available (conservative) leverage: 15.2, // Current leverage from screenshot liquidationPrice: 177.198 // From screenshot }, marketData: { price: 183.87, priceChange24h: -6.75, // From screenshot (red, declining) volume: 245000000, rsi: 30, // Oversold territory (estimated) support: 180.0, // Support level estimate resistance: 189.0 // Resistance level estimate }, maxLeverageAllowed: 20 } console.log('๐Ÿ“Š Current SOL Position Analysis:') console.log(` Position: ${testParams.currentPosition.side.toUpperCase()} ${testParams.currentPosition.size} SOL`) console.log(` Entry Price: $${testParams.currentPosition.entryPrice}`) console.log(` Current Price: $${testParams.currentPosition.currentPrice}`) console.log(` Price Drop: ${(((testParams.currentPosition.currentPrice - testParams.currentPosition.entryPrice) / testParams.currentPosition.entryPrice) * 100).toFixed(2)}%`) console.log(` Unrealized PnL: $${testParams.currentPosition.unrealizedPnl.toFixed(2)} ๐Ÿ“‰`) console.log(` Current Leverage: ${testParams.accountStatus.leverage}x`) console.log(` Available Balance: $${testParams.accountStatus.availableBalance}`) console.log(` 24h Change: ${testParams.marketData.priceChange24h}% ๐Ÿ“‰`) console.log() // Run DCA analysis console.log('๐Ÿ” Running AI DCA Analysis...') const dcaResult = analyzeDCAOpportunity(testParams) console.log() console.log('๐Ÿ“ˆ AI DCA Decision:') console.log('=' .repeat(30)) console.log(` Should DCA: ${dcaResult.shouldDCA ? 'โœ… YES' : 'โŒ NO'}`) console.log(` Confidence: ${dcaResult.confidence}%`) console.log(` Risk Level: ${dcaResult.riskAssessment}`) console.log(` AI Reasoning: ${dcaResult.reasoning}`) console.log() if (dcaResult.shouldDCA) { console.log('๐Ÿ’ฐ DCA Execution Plan:') console.log('=' .repeat(25)) console.log(` DCA Amount: ${dcaResult.dcaAmount?.toFixed(4)} SOL`) console.log(` DCA Price: $${testParams.currentPosition.currentPrice} (current market)`) console.log(` New Average Price: $${dcaResult.newAveragePrice?.toFixed(4)}`) console.log(` New Stop Loss: $${dcaResult.newStopLoss?.toFixed(4)}`) console.log(` New Take Profit: $${dcaResult.newTakeProfit?.toFixed(4)}`) console.log(` New Leverage: ${dcaResult.newLeverage?.toFixed(1)}x`) console.log(` New Liquidation: $${dcaResult.newLiquidationPrice?.toFixed(4)}`) console.log() // Calculate impact const originalLoss = testParams.currentPosition.unrealizedPnl const totalPositionAfterDCA = testParams.currentPosition.size + dcaResult.dcaAmount const breakEvenMove = ((dcaResult.newAveragePrice - testParams.currentPosition.currentPrice) / testParams.currentPosition.currentPrice * 100) const potentialProfitAtTP = ((dcaResult.newTakeProfit - dcaResult.newAveragePrice) * totalPositionAfterDCA) console.log('๐Ÿ“Š Impact Analysis:') console.log('=' .repeat(20)) console.log(` Original Loss: $${originalLoss.toFixed(2)}`) console.log(` Total Position After DCA: ${totalPositionAfterDCA.toFixed(4)} SOL`) console.log(` Break-Even Price: $${dcaResult.newAveragePrice?.toFixed(4)}`) console.log(` Price Move Needed: +${breakEvenMove.toFixed(2)}% from current`) console.log(` Potential Profit at TP: $${potentialProfitAtTP.toFixed(2)}`) console.log(` Risk/Reward: ${(potentialProfitAtTP / Math.abs(originalLoss)).toFixed(1)}:1`) const liquidationBuffer = Math.abs(dcaResult.newLiquidationPrice - dcaResult.newStopLoss) / dcaResult.newStopLoss * 100 console.log(` Liquidation Buffer: ${liquidationBuffer.toFixed(1)}% safety margin`) } console.log('\n๐Ÿง  Market Context Analysis:') console.log('=' .repeat(30)) console.log(` SOL down ${Math.abs(testParams.marketData.priceChange24h)}% in 24h (oversold conditions)`) console.log(` Current price near estimated support at $${testParams.marketData.support}`) console.log(` RSI at ${testParams.marketData.rsi} indicates oversold (DCA opportunity)`) console.log(` Position is ${((testParams.currentPosition.entryPrice - testParams.currentPosition.currentPrice) / testParams.currentPosition.entryPrice * 100).toFixed(1)}% underwater`) console.log('\nโœ… DCA Analysis Complete') console.log(' This represents a sophisticated AI-driven position scaling strategy') console.log(' that could turn the current losing position into a profitable one!') } testSOLDCA().catch(console.error)