// Dynamic Position Calculator Component "use client" import React, { useState, useEffect } from 'react' interface PositionCalculatorProps { analysis?: any // The AI analysis results currentPrice?: number symbol?: string onPositionChange?: (position: PositionCalculation) => void } interface PositionCalculation { investmentAmount: number leverage: number positionSize: number entryPrice: number stopLoss: number takeProfit: number liquidationPrice: number maxLoss: number maxProfit: number riskRewardRatio: number marginRequired: number tradingFee: number netInvestment: number } export default function PositionCalculator({ analysis, currentPrice = 0, symbol = 'BTCUSD', onPositionChange }: PositionCalculatorProps) { const [investmentAmount, setInvestmentAmount] = useState(100) const [leverage, setLeverage] = useState(10) const [positionType, setPositionType] = useState<'long' | 'short'>('long') const [calculation, setCalculation] = useState(null) const [showAdvanced, setShowAdvanced] = useState(false) const [marketPrice, setMarketPrice] = useState(currentPrice) // Trading parameters const [tradingFee, setTradingFee] = useState(0.1) // 0.1% fee const [maintenanceMargin, setMaintenanceMargin] = useState(0.5) // 0.5% maintenance margin // Debug logging console.log('📊 PositionCalculator mounted with:', { analysis, currentPrice, symbol }) // Auto-detect position type from analysis useEffect(() => { if (analysis?.recommendation) { const rec = analysis.recommendation.toLowerCase() if (rec.includes('buy') || rec.includes('long') || rec.includes('bullish')) { setPositionType('long') } else if (rec.includes('sell') || rec.includes('short') || rec.includes('bearish')) { setPositionType('short') } } }, [analysis]) // Fetch current market price if not provided useEffect(() => { const fetchPrice = async () => { console.log('🔍 Fetching price for:', symbol, 'currentPrice:', currentPrice) if (currentPrice > 0) { console.log('✅ Using provided currentPrice:', currentPrice) setMarketPrice(currentPrice) return } try { const response = await fetch(`/api/price?symbol=${symbol}`) const data = await response.json() console.log('📊 Price API response:', data) if (data.price) { console.log('✅ Setting market price to:', data.price) setMarketPrice(data.price) } else { console.error('❌ No price in API response') setMarketPrice(symbol.includes('BTC') ? 100000 : symbol.includes('ETH') ? 4000 : 100) } } catch (error) { console.error('❌ Failed to fetch price:', error) // Fallback to a reasonable default for testing const fallbackPrice = symbol.includes('BTC') ? 100000 : symbol.includes('ETH') ? 4000 : 100 console.log('🔄 Using fallback price:', fallbackPrice) setMarketPrice(fallbackPrice) } } fetchPrice() }, [currentPrice, symbol]) // Calculate position metrics const calculatePosition = () => { let priceToUse = marketPrice || currentPrice console.log('📊 Calculating position with:', { priceToUse, marketPrice, currentPrice, investmentAmount, leverage }) // Use fallback price if no price is available if (!priceToUse || priceToUse <= 0) { priceToUse = symbol.includes('BTC') ? 117000 : symbol.includes('ETH') ? 4000 : symbol.includes('SOL') ? 200 : 100 console.log('🔄 Using fallback price:', priceToUse) } const positionSize = investmentAmount * leverage const marginRequired = investmentAmount const fee = positionSize * (tradingFee / 100) const netInvestment = investmentAmount + fee console.log('📈 Position calculation:', { positionSize, marginRequired, fee, netInvestment }) // Get AI analysis targets if available let entryPrice = priceToUse let stopLoss = 0 let takeProfit = 0 if (analysis && analysis.analysis) { console.log('🤖 Using AI analysis:', analysis.analysis) // Try to extract entry, stop loss, and take profit from AI analysis const analysisText = analysis.analysis.toLowerCase() // Look for entry price const entryMatch = analysisText.match(/entry[:\s]*[\$]?(\d+\.?\d*)/i) if (entryMatch) { entryPrice = parseFloat(entryMatch[1]) console.log('📍 Found entry price:', entryPrice) } // Look for stop loss const stopMatch = analysisText.match(/stop[:\s]*[\$]?(\d+\.?\d*)/i) if (stopMatch) { stopLoss = parseFloat(stopMatch[1]) console.log('🛑 Found stop loss:', stopLoss) } // Look for take profit const profitMatch = analysisText.match(/(?:take profit|target)[:\s]*[\$]?(\d+\.?\d*)/i) if (profitMatch) { takeProfit = parseFloat(profitMatch[1]) console.log('🎯 Found take profit:', takeProfit) } // If no specific targets found, use percentage-based defaults if (!stopLoss) { stopLoss = positionType === 'long' ? entryPrice * 0.95 // 5% stop loss for long : entryPrice * 1.05 // 5% stop loss for short console.log('🔄 Using default stop loss:', stopLoss) } if (!takeProfit) { takeProfit = positionType === 'long' ? entryPrice * 1.10 // 10% take profit for long : entryPrice * 0.90 // 10% take profit for short console.log('🔄 Using default take profit:', takeProfit) } } else { console.log('📊 No AI analysis, using defaults') // Default targets if no analysis stopLoss = positionType === 'long' ? priceToUse * 0.95 : priceToUse * 1.05 takeProfit = positionType === 'long' ? priceToUse * 1.10 : priceToUse * 0.90 } // Calculate liquidation price const liquidationPrice = positionType === 'long' ? entryPrice * (1 - (1 / leverage) + (maintenanceMargin / 100)) : entryPrice * (1 + (1 / leverage) - (maintenanceMargin / 100)) // Calculate PnL const stopLossChange = positionType === 'long' ? (stopLoss - entryPrice) / entryPrice : (entryPrice - stopLoss) / entryPrice const takeProfitChange = positionType === 'long' ? (takeProfit - entryPrice) / entryPrice : (entryPrice - takeProfit) / entryPrice const maxLoss = positionSize * Math.abs(stopLossChange) const maxProfit = positionSize * Math.abs(takeProfitChange) const riskRewardRatio = maxProfit / maxLoss const result: PositionCalculation = { investmentAmount, leverage, positionSize, entryPrice, stopLoss, takeProfit, liquidationPrice, maxLoss, maxProfit, riskRewardRatio, marginRequired, tradingFee: fee, netInvestment } console.log('✅ Position calculation result:', result) setCalculation(result) onPositionChange?.(result) return result } // Recalculate when parameters change useEffect(() => { console.log('🔄 Recalculating position...') calculatePosition() }, [investmentAmount, leverage, positionType, currentPrice, analysis, tradingFee, maintenanceMargin, marketPrice]) // Force initial calculation useEffect(() => { console.log('🚀 Position Calculator initialized, forcing calculation...') calculatePosition() }, []) const formatCurrency = (amount: number, decimals: number = 2) => { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: decimals, maximumFractionDigits: decimals }).format(amount) } const formatPrice = (price: number) => { return new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(price) } return (

📊 Position Calculator

{/* Current Price Display */}
Current Market Price
{symbol}: ${formatPrice(marketPrice || currentPrice || (symbol.includes('BTC') ? 117000 : symbol.includes('ETH') ? 4000 : symbol.includes('SOL') ? 200 : 100))} {(!marketPrice && !currentPrice) && ( (fallback) )}
{analysis?.recommendation && (
AI Recommendation: {analysis.recommendation}
)}
{/* Input Controls */}
{/* Investment Amount */}
setInvestmentAmount(Number(e.target.value))} className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500" min="1" step="1" />
{/* Position Type */}
{/* Leverage Slider */}
setLeverage(Number(e.target.value))} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer slider" style={{ background: `linear-gradient(to right, #10B981 0%, #10B981 ${leverage}%, #374151 ${leverage}%, #374151 100%)` }} />
1x 25x 50x 100x
{/* Advanced Settings */} {showAdvanced && (
setTradingFee(Number(e.target.value))} className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500" min="0" max="1" step="0.01" />
setMaintenanceMargin(Number(e.target.value))} className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500" min="0.1" max="5" step="0.1" />
)} {/* Calculation Results */} {calculation && (
{/* Position Summary */}
Position Size
{formatCurrency(calculation.positionSize)}
Entry Price
${formatPrice(calculation.entryPrice)}
Margin Required
{formatCurrency(calculation.marginRequired)}
{/* Risk Metrics */}
🚨 Risk Metrics
Stop Loss: ${formatPrice(calculation.stopLoss)}
Max Loss: {formatCurrency(calculation.maxLoss)}
Liquidation: ${formatPrice(calculation.liquidationPrice)}
💰 Profit Potential
Take Profit: ${formatPrice(calculation.takeProfit)}
Max Profit: {formatCurrency(calculation.maxProfit)}
Risk/Reward: 1:{calculation.riskRewardRatio.toFixed(2)}
{/* Fee Breakdown */}
💸 Fee Breakdown
Trading Fee: {formatCurrency(calculation.tradingFee)}
Net Investment: {formatCurrency(calculation.netInvestment)}
Leverage: {leverage}x
{/* Risk Warning */} {leverage > 50 && (
⚠️ High Leverage Warning

Using {leverage}x leverage is extremely risky. A small price movement against your position could result in liquidation.

)}
)}
) }