'use client'
import React, { useState, useEffect } from 'react'
export default function TradeExecutionPanel({ analysis, symbol = 'SOL' }) {
const [tradeType, setTradeType] = useState('BUY')
const [amount, setAmount] = useState('')
const [customPrice, setCustomPrice] = useState('')
const [useRecommendedPrice, setUseRecommendedPrice] = useState(true)
const [isExecuting, setIsExecuting] = useState(false)
const [executionResult, setExecutionResult] = useState(null)
const [balance, setBalance] = useState(null)
// Trading mode and pair selection
const [tradingMode, setTradingMode] = useState('SPOT') // 'SPOT' or 'PERP'
const [tradingPair, setTradingPair] = useState('SOL/USDC') // SOL/USDC or USDC/SOL
// TP/SL functionality
const [enableStopLoss, setEnableStopLoss] = useState(false)
const [stopLoss, setStopLoss] = useState('')
const [enableTakeProfit, setEnableTakeProfit] = useState(false)
const [takeProfit, setTakeProfit] = useState('')
const [useRealDEX, setUseRealDEX] = useState(false)
// Perp trading settings
const [leverage, setLeverage] = useState(1)
const [perpSize, setPerpSize] = useState('')
// USDC stablecoin features
const [quickSwapMode, setQuickSwapMode] = useState(false)
const [usdcSwapAmount, setUsdcSwapAmount] = useState('')
// Auto-fill TP/SL from AI analysis
useEffect(() => {
if (analysis) {
if (analysis.stopLoss?.price) {
setStopLoss(analysis.stopLoss.price.toString())
setEnableStopLoss(true)
}
if (analysis.takeProfits?.tp1?.price) {
setTakeProfit(analysis.takeProfits.tp1.price.toString())
setEnableTakeProfit(true)
}
}
}, [analysis])
// Get recommended price from analysis
const getRecommendedPrice = () => {
if (!analysis) return null
if (analysis.recommendation === 'BUY' && analysis.entry?.price) {
return analysis.entry.price
} else if (analysis.recommendation === 'SELL' && analysis.entry?.price) {
return analysis.entry.price
}
return null
}
const recommendedPrice = getRecommendedPrice()
// Fetch balance on component mount
useEffect(() => {
fetchBalance()
}, [])
const fetchBalance = async () => {
try {
const response = await fetch('/api/trading/balance')
const data = await response.json()
if (data.success) {
setBalance(data.balance)
}
} catch (error) {
console.error('Failed to fetch balance:', error)
}
}
const executeQuickUSDCSwap = async () => {
if (!usdcSwapAmount || parseFloat(usdcSwapAmount) <= 0) {
alert('Please enter a valid USDC swap amount')
return
}
setIsExecuting(true)
setExecutionResult(null)
try {
const swapData = {
symbol: 'SOL',
side: 'SELL', // Sell SOL for USDC
amount: parseFloat(usdcSwapAmount),
tradingPair: 'SOL/USDC',
tradingMode: 'SPOT',
useRealDEX: true,
quickSwap: true
}
const response = await fetch('/api/trading/execute-dex', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(swapData)
})
const result = await response.json()
if (result.success) {
setExecutionResult({
success: true,
trade: result.trade,
message: `✅ Quick swapped ${usdcSwapAmount} SOL to USDC`
})
await fetchBalance()
setUsdcSwapAmount('')
} else {
setExecutionResult({
success: false,
error: result.error,
message: result.message
})
}
} catch (error) {
setExecutionResult({
success: false,
error: 'Network error',
message: 'Failed to execute USDC swap. Please try again.'
})
} finally {
setIsExecuting(false)
}
}
const executeTrade = async () => {
if (!amount || parseFloat(amount) <= 0) {
alert('Please enter a valid amount')
return
}
setIsExecuting(true)
setExecutionResult(null)
try {
const tradePrice = useRecommendedPrice && recommendedPrice
? recommendedPrice
: customPrice ? parseFloat(customPrice) : undefined
// Prepare trade data based on trading mode
let tradeData = {
symbol,
side: tradeType,
amount: parseFloat(amount),
price: tradePrice,
orderType: tradePrice ? 'limit' : 'market',
useRealDEX: useRealDEX,
tradingMode: tradingMode,
tradingPair: tradingPair
}
// Add TP/SL if enabled
if (enableStopLoss && stopLoss) {
tradeData.stopLoss = parseFloat(stopLoss)
}
if (enableTakeProfit && takeProfit) {
tradeData.takeProfit = parseFloat(takeProfit)
}
// Add perpetuals specific data
if (tradingMode === 'PERP') {
tradeData.leverage = leverage
tradeData.perpSize = perpSize ? parseFloat(perpSize) : parseFloat(amount)
}
// Determine API endpoint based on trading mode
let apiEndpoint = '/api/trading/execute'
if (tradingMode === 'PERP') {
apiEndpoint = '/api/trading/execute-perp'
} else if (useRealDEX || quickSwapMode) {
apiEndpoint = '/api/trading/execute-dex'
}
const response = await fetch(apiEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(tradeData)
})
const result = await response.json()
if (result.success) {
setExecutionResult({
success: true,
trade: result.trade,
message: result.message
})
// Refresh balance after successful trade
await fetchBalance()
} else {
setExecutionResult({
success: false,
error: result.error,
message: result.message
})
}
} catch (error) {
setExecutionResult({
success: false,
error: 'Network error',
message: 'Failed to execute trade. Please try again.'
})
} finally {
setIsExecuting(false)
}
}
const getTradeButtonColor = () => {
if (tradeType === 'BUY') return 'bg-green-600 hover:bg-green-700'
return 'bg-red-600 hover:bg-red-700'
}
const getRecommendationColor = () => {
if (!analysis) return 'text-gray-400'
switch (analysis.recommendation) {
case 'BUY': return 'text-green-400'
case 'SELL': return 'text-red-400'
default: return 'text-yellow-400'
}
}
return (
Execute Trade
{symbol} Trading
{/* Balance Display */}
{balance && (
Portfolio Balance
${balance.totalValue?.toFixed(2)}
Available: ${balance.availableBalance?.toFixed(2)}
)}
{/* AI Recommendation Display */}
{analysis && (
AI Recommendation
{analysis.recommendation}
{analysis.confidence}% confidence
{recommendedPrice && (
Entry: ${recommendedPrice.toFixed(4)}
{analysis.entry?.buffer && (
({analysis.entry.buffer})
)}
)}
{analysis.stopLoss && (
Stop Loss: ${analysis.stopLoss.price.toFixed(4)}
)}
{analysis.takeProfits?.tp1 && (
TP1: ${analysis.takeProfits.tp1.price.toFixed(4)}
)}
{analysis.reasoning}
)}
{/* Trading Mode Selection */}
{/* Trading Pair Selection (for Spot) */}
{tradingMode === 'SPOT' && (
{tradingPair === 'SOL/USDC' ? 'Swap SOL for USDC stablecoin' : 'Buy SOL with USDC'}
)}
{/* Leverage Selection (for Perps) */}
{tradingMode === 'PERP' && (
{[1, 2, 5, 10].map(lev => (
))}
⚠️ Higher leverage = Higher risk. Max 10x for safety.
)}
{/* Trade Type Selection */}
{/* Amount Input */}
setAmount(e.target.value)}
placeholder="0.00"
step="0.001"
min="0"
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
{/* Price Selection */}
{recommendedPrice && (
)}
{!useRecommendedPrice && (
setCustomPrice(e.target.value)}
placeholder="Enter price (leave empty for market)"
step="0.0001"
min="0"
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
)}
{/* Stop Loss & Take Profit */}
Risk Management
{/* Stop Loss */}
{/* Take Profit */}
{/* DEX Selection */}
Execution Method
{useRealDEX
? '⚠️ Real DEX trading uses your actual SOL/USDC and costs gas fees'
: '🎮 Simulation mode for testing strategies without real trades'
}
{/* Quick USDC Swap - Spot mode only */}
{tradingMode === 'SPOT' && (
💱 Quick USDC Swap
STABLE
Instantly convert SOL to USDC stablecoin to lock in profits or avoid volatility
setUsdcSwapAmount(e.target.value)}
placeholder="SOL amount"
step="0.01"
min="0"
className="flex-1 px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-green-500"
/>
Real-time swap via Jupiter DEX • Low slippage • Instant execution
)}
{/* Jupiter Perpetuals Integration - Perp mode only */}
{tradingMode === 'PERP' && (
⚡ Jupiter Perpetuals
LEVERAGE
Trade with leverage on Jupiter's perpetual DEX • Long or Short any asset
Liquidation Risk:
{leverage <= 2 ? 'Low' : leverage <= 5 ? 'Medium' : 'High'}
🚧 Jupiter Perpetuals integration in development. Currently using simulation mode.
)}
{/* Execute Button */}
{/* Execution Result */}
{executionResult && (
{executionResult.success ? '✅ Trade Executed' : '❌ Trade Failed'}
{executionResult.message}
{executionResult.trade && (
TX ID: {executionResult.trade.txId}
)}
)}
{/* Risk Warning */}
⚠️ Trading involves significant risk. This is a simulated trading environment using Bitquery data.
)
}