Files
trading_bot_v3/components/SimpleTradingChart.tsx
mindesbunister c1a7a28cd8 Implement working canvas-based trading chart
- Created SimpleTradingChart component using HTML5 Canvas
- Renders proper candlestick chart with sample SOL/USDC data
- Includes grid lines, price labels, and proper styling
- Replaced problematic lightweight-charts with working solution
- Updated trading page to use the new working chart component

Fixes chart loading issues by using native HTML5 Canvas instead of external library dependencies.
2025-07-16 13:06:58 +02:00

179 lines
4.8 KiB
TypeScript

'use client'
import React, { useEffect, useRef, useState } from 'react'
interface SimpleCandlestickData {
time: string
open: number
high: number
low: number
close: number
}
interface SimpleTradingChartProps {
symbol?: string
positions?: any[]
}
export default function SimpleTradingChart({ symbol = 'SOL/USDC', positions = [] }: SimpleTradingChartProps) {
const canvasRef = useRef<HTMLCanvasElement>(null)
const [data, setData] = useState<SimpleCandlestickData[]>([])
const [error, setError] = useState<string | null>(null)
// Generate sample data
useEffect(() => {
const generateData = () => {
const data: SimpleCandlestickData[] = []
const basePrice = 166.5
let currentPrice = basePrice
const today = new Date()
for (let i = 29; i >= 0; i--) {
const date = new Date(today)
date.setDate(date.getDate() - i)
const timeString = date.toISOString().split('T')[0]
const change = (Math.random() - 0.5) * 4
const open = currentPrice
const close = currentPrice + change
const high = Math.max(open, close) + Math.random() * 2
const low = Math.min(open, close) - Math.random() * 2
data.push({
time: timeString,
open: Number(open.toFixed(2)),
high: Number(high.toFixed(2)),
low: Number(low.toFixed(2)),
close: Number(close.toFixed(2)),
})
currentPrice = close
}
return data
}
setData(generateData())
}, [])
// Draw the chart on canvas
useEffect(() => {
if (!canvasRef.current || data.length === 0) return
const canvas = canvasRef.current
const ctx = canvas.getContext('2d')
if (!ctx) return
// Set canvas size
canvas.width = 800
canvas.height = 400
// Clear canvas
ctx.fillStyle = '#1a1a1a'
ctx.fillRect(0, 0, canvas.width, canvas.height)
// Calculate chart dimensions
const padding = 50
const chartWidth = canvas.width - 2 * padding
const chartHeight = canvas.height - 2 * padding
// Find price range
const prices = data.flatMap(d => [d.open, d.high, d.low, d.close])
const minPrice = Math.min(...prices)
const maxPrice = Math.max(...prices)
const priceRange = maxPrice - minPrice
// Helper functions
const getX = (index: number) => padding + (index / (data.length - 1)) * chartWidth
const getY = (price: number) => padding + ((maxPrice - price) / priceRange) * chartHeight
// Draw grid
ctx.strokeStyle = 'rgba(42, 46, 57, 0.5)'
ctx.lineWidth = 1
// Horizontal grid lines
for (let i = 0; i <= 5; i++) {
const y = padding + (i / 5) * chartHeight
ctx.beginPath()
ctx.moveTo(padding, y)
ctx.lineTo(padding + chartWidth, y)
ctx.stroke()
}
// Vertical grid lines
for (let i = 0; i <= 10; i++) {
const x = padding + (i / 10) * chartWidth
ctx.beginPath()
ctx.moveTo(x, padding)
ctx.lineTo(x, padding + chartHeight)
ctx.stroke()
}
// Draw candlesticks
const candleWidth = Math.max(2, chartWidth / data.length * 0.8)
data.forEach((candle, index) => {
const x = getX(index)
const openY = getY(candle.open)
const closeY = getY(candle.close)
const highY = getY(candle.high)
const lowY = getY(candle.low)
const isGreen = candle.close > candle.open
const color = isGreen ? '#26a69a' : '#ef5350'
// Draw wick
ctx.strokeStyle = color
ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(x, highY)
ctx.lineTo(x, lowY)
ctx.stroke()
// Draw body
ctx.fillStyle = color
const bodyTop = Math.min(openY, closeY)
const bodyHeight = Math.abs(closeY - openY)
ctx.fillRect(x - candleWidth / 2, bodyTop, candleWidth, Math.max(bodyHeight, 1))
})
// Draw price labels
ctx.fillStyle = '#ffffff'
ctx.font = '12px Arial'
ctx.textAlign = 'right'
for (let i = 0; i <= 5; i++) {
const price = maxPrice - (i / 5) * priceRange
const y = padding + (i / 5) * chartHeight
ctx.fillText(price.toFixed(2), padding - 10, y + 4)
}
// Draw title
ctx.fillStyle = '#ffffff'
ctx.font = 'bold 16px Arial'
ctx.textAlign = 'left'
ctx.fillText(symbol, padding, 30)
}, [data, symbol])
if (error) {
return (
<div className="bg-gray-900 rounded-lg p-6 h-[600px] flex items-center justify-center">
<div className="text-red-400">Chart Error: {error}</div>
</div>
)
}
return (
<div className="bg-gray-900 rounded-lg p-6">
<canvas
ref={canvasRef}
className="border border-gray-700 rounded"
style={{ width: '100%', maxWidth: '800px', height: '400px' }}
/>
<div className="mt-4 text-sm text-gray-400">
Simple canvas-based candlestick chart {data.length} data points
</div>
</div>
)
}