const SIGNAL_DATA = [ { type: 'BUY', price: '2034.50', tp: '2042.00', sl: '2029.00', confidence: 89, time: '2m ago' }, { type: 'SELL', price: '2045.10', tp: '2038.50', sl: '2048.00', confidence: 92, time: '15m ago' }, { type: 'BUY', price: '2022.80', tp: '2030.00', sl: '2018.50', confidence: 76, time: '42m ago' }, { type: 'SELL', price: '2051.00', tp: '2044.20', sl: '2055.00', confidence: 84, time: '1h ago' }, { type: 'BUY', price: '2036.20', tp: '2041.50', sl: '2033.00', confidence: 65, time: '1h ago' }, { type: 'SELL', price: '2048.90', tp: '2040.00', sl: '2052.00', confidence: 95, time: '2h ago' }, ]; const HISTORY_DATA = [ { asset: 'XAUUSD', type: 'BUY', entry: '2,024.50', exit: '2,031.20', yield: '+670 pts', color: 'text-emerald-400', time: '2h ago' }, { asset: 'XAUUSD', type: 'SELL', entry: '2,038.10', exit: '2,034.40', yield: '+370 pts', color: 'text-emerald-400', time: '4h ago' }, { asset: 'XAUUSD', type: 'BUY', entry: '2,018.00', exit: '2,015.50', yield: '-250 pts', color: 'text-rose-400', time: '6h ago' }, { asset: 'XAUUSD', type: 'BUY', entry: '2,012.20', exit: '2,020.80', yield: '+860 pts', color: 'text-emerald-400', time: '10h ago' }, ]; class Particle { constructor(sphereRadius) { const theta = Math.random() * 2 * Math.PI; const phi = Math.acos(2 * Math.random() - 1); this.sphereRadius = sphereRadius; this.x = sphereRadius * Math.sin(phi) * Math.cos(theta); this.y = sphereRadius * Math.sin(phi) * Math.sin(theta); this.z = sphereRadius * Math.cos(phi); this.size = Math.random() * 1.8 + 0.6; this.baseOpacity = Math.random() * 0.6 + 0.3; } rotate(angleX, angleY) { let cosY = Math.cos(angleY), sinY = Math.sin(angleY); let x = this.x * cosY - this.z * sinY; let z = this.z * cosY + this.x * sinY; this.x = x; this.z = z; let cosX = Math.cos(angleX), sinX = Math.sin(angleX); let y = this.y * cosX - this.z * sinX; z = this.z * cosX + this.y * sinX; this.y = y; this.z = z; } draw(ctx, centerX, centerY) { const scale = 300 / (300 + this.z); const x2d = this.x * scale + centerX; const y2d = this.y * scale + centerY; const opacity = Math.max(0, this.baseOpacity + (this.z / this.sphereRadius) * 0.4); ctx.beginPath(); ctx.arc(x2d, y2d, this.size * scale, 0, Math.PI * 2); if (this.x > 40) ctx.fillStyle = `rgba(34, 211, 238, ${opacity})`; else if (this.x < -40) ctx.fillStyle = `rgba(167, 139, 250, ${opacity})`; else ctx.fillStyle = `rgba(248, 250, 252, ${opacity})`; ctx.fill(); } } function initParticleSphere() { const canvas = document.getElementById('particle-canvas'); const ctx = canvas.getContext('2d', { alpha: true }); const sphereRadius = 105; const particleCount = 400; const rotationSpeed = 0.003; let particles = []; let width, height; function resize() { const dpr = window.devicePixelRatio || 1; const rect = canvas.parentElement.getBoundingClientRect(); canvas.width = rect.width * dpr; canvas.height = rect.height * dpr; canvas.style.width = `${rect.width}px`; canvas.style.height = `${rect.height}px`; ctx.scale(dpr, dpr); width = rect.width; height = rect.height; } function animate() { ctx.clearRect(0, 0, width, height); const centerX = width / 2; const centerY = height / 2; particles.sort((a, b) => b.z - a.z); particles.forEach(p => { p.rotate(rotationSpeed, rotationSpeed * 0.6); p.draw(ctx, centerX, centerY); }); requestAnimationFrame(animate); } for (let i = 0; i < particleCount; i++) particles.push(new Particle(sphereRadius)); window.addEventListener('resize', resize); resize(); animate(); } function renderSignals() { const grid = document.getElementById('signals-grid'); grid.innerHTML = SIGNAL_DATA.map(s => `