'use client' import React, { useRef, useEffect, useState } from 'react' interface Position { id: string symbol: string side: 'BUY' | 'SELL' amount: number entryPrice: number stopLoss: number takeProfit: number currentPrice: number unrealizedPnl: number leverage: number } interface SimpleChartProps { symbol?: string positions?: Position[] } interface CandleData { open: number high: number low: number close: number time: number } export default function SimpleChart({ symbol = 'SOL/USDC', positions = [] }: SimpleChartProps) { const canvasRef = useRef(null) const [candleData, setCandleData] = useState([]) const [timeframe, setTimeframe] = useState('5m') const timeframes = ['1m', '5m', '15m', '1h', '4h', '1d'] // Generate realistic candlestick data const generateCandleData = React.useCallback(() => { const data: CandleData[] = [] const basePrice = symbol === 'SOL' ? 166.5 : symbol === 'BTC' ? 42150 : 2580 let currentPrice = basePrice const now = Date.now() for (let i = 60; i >= 0; i--) { const timeOffset = i * 5 * 60 * 1000 // 5-minute intervals const time = now - timeOffset const volatility = basePrice * 0.002 // 0.2% volatility const open = currentPrice const change = (Math.random() - 0.5) * volatility * 2 const close = open + change const high = Math.max(open, close) + Math.random() * volatility const low = Math.min(open, close) - Math.random() * volatility data.push({ open, high, low, close, time }) currentPrice = close } return data }, [symbol]) useEffect(() => { setCandleData(generateCandleData()) }, [symbol, timeframe, generateCandleData]) useEffect(() => { const canvas = canvasRef.current if (!canvas || candleData.length === 0) return const ctx = canvas.getContext('2d') if (!ctx) return // Set canvas size for high DPI displays const rect = canvas.getBoundingClientRect() const dpr = window.devicePixelRatio || 1 canvas.width = rect.width * dpr canvas.height = rect.height * dpr ctx.scale(dpr, dpr) const width = rect.width const height = rect.height // Clear canvas with dark background ctx.fillStyle = '#0f0f0f' ctx.fillRect(0, 0, width, height) // Calculate price range const prices = candleData.flatMap(d => [d.high, d.low]) const maxPrice = Math.max(...prices) const minPrice = Math.min(...prices) const priceRange = maxPrice - minPrice const padding = priceRange * 0.1 // Chart dimensions const chartLeft = 60 const chartRight = width - 20 const chartTop = 40 const chartBottom = height - 60 const chartWidth = chartRight - chartLeft const chartHeight = chartBottom - chartTop // Draw grid ctx.strokeStyle = '#1a1a1a' ctx.lineWidth = 1 // Horizontal grid lines (price levels) const priceStep = (maxPrice - minPrice + padding * 2) / 8 for (let i = 0; i <= 8; i++) { const price = minPrice - padding + i * priceStep const y = chartBottom - ((price - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight ctx.beginPath() ctx.moveTo(chartLeft, y) ctx.lineTo(chartRight, y) ctx.stroke() // Price labels ctx.fillStyle = '#666' ctx.font = '11px Arial' ctx.textAlign = 'right' ctx.fillText(price.toFixed(2), chartLeft - 5, y + 4) } // Vertical grid lines (time) const timeStep = chartWidth / 12 for (let i = 0; i <= 12; i++) { const x = chartLeft + i * timeStep ctx.beginPath() ctx.moveTo(x, chartTop) ctx.lineTo(x, chartBottom) ctx.stroke() } // Draw candlesticks const candleWidth = Math.max(2, chartWidth / candleData.length - 2) candleData.forEach((candle, index) => { const x = chartLeft + (index / (candleData.length - 1)) * chartWidth const openY = chartBottom - ((candle.open - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight const closeY = chartBottom - ((candle.close - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight const highY = chartBottom - ((candle.high - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight const lowY = chartBottom - ((candle.low - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight const isGreen = candle.close > candle.open const color = isGreen ? '#26a69a' : '#ef5350' ctx.strokeStyle = color ctx.fillStyle = color ctx.lineWidth = 1 // Draw wick (high-low line) ctx.beginPath() ctx.moveTo(x, highY) ctx.lineTo(x, lowY) ctx.stroke() // Draw candle body const bodyTop = Math.min(openY, closeY) const bodyHeight = Math.abs(closeY - openY) if (isGreen) { ctx.strokeRect(x - candleWidth / 2, bodyTop, candleWidth, Math.max(bodyHeight, 1)) } else { ctx.fillRect(x - candleWidth / 2, bodyTop, candleWidth, Math.max(bodyHeight, 1)) } }) // Draw position overlays positions.forEach((position) => { if (!position.symbol.includes(symbol.replace('/USDC', ''))) return const entryY = chartBottom - ((position.entryPrice - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight const stopLossY = chartBottom - ((position.stopLoss - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight const takeProfitY = chartBottom - ((position.takeProfit - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight // Entry price line ctx.strokeStyle = position.side === 'BUY' ? '#26a69a' : '#ef5350' ctx.lineWidth = 2 ctx.setLineDash([5, 5]) ctx.beginPath() ctx.moveTo(chartLeft, entryY) ctx.lineTo(chartRight, entryY) ctx.stroke() // Stop loss line ctx.strokeStyle = '#ef5350' ctx.lineWidth = 1 ctx.setLineDash([3, 3]) ctx.beginPath() ctx.moveTo(chartLeft, stopLossY) ctx.lineTo(chartRight, stopLossY) ctx.stroke() // Take profit line ctx.strokeStyle = '#26a69a' ctx.lineWidth = 1 ctx.setLineDash([3, 3]) ctx.beginPath() ctx.moveTo(chartLeft, takeProfitY) ctx.lineTo(chartRight, takeProfitY) ctx.stroke() ctx.setLineDash([]) // Reset line dash }) // Draw current price line const currentPrice = candleData[candleData.length - 1]?.close || 0 const currentPriceY = chartBottom - ((currentPrice - (minPrice - padding)) / (maxPrice - minPrice + padding * 2)) * chartHeight ctx.strokeStyle = '#ffa726' ctx.lineWidth = 2 ctx.setLineDash([]) ctx.beginPath() ctx.moveTo(chartLeft, currentPriceY) ctx.lineTo(chartRight, currentPriceY) ctx.stroke() // Current price label ctx.fillStyle = '#ffa726' ctx.fillRect(chartRight - 60, currentPriceY - 10, 60, 20) ctx.fillStyle = '#000' ctx.font = '12px Arial' ctx.textAlign = 'center' ctx.fillText(currentPrice.toFixed(2), chartRight - 30, currentPriceY + 4) // Chart title ctx.fillStyle = '#ffffff' ctx.font = 'bold 16px Arial' ctx.textAlign = 'left' ctx.fillText(`${symbol} - ${timeframe}`, 20, 25) }, [symbol, positions, candleData, timeframe]) return (
{/* Chart Controls */}

{symbol}

{timeframes.map(tf => ( ))}
{candleData.length > 0 && ( Last: ${candleData[candleData.length - 1]?.close.toFixed(2)} • 24h Vol: ${(Math.random() * 1000000).toFixed(0)}M )}
{/* Chart Canvas */}
{/* Legend */} {positions.length > 0 && (
— Current Price
⋯ Take Profit
⋯ Stop Loss
⋯ Entry Price
)}
) }