document.addEventListener('DOMContentLoaded', function () { const POLLING_INTERVAL = 3000; // 3 seconds const liveTickers = [ { symbol: 'BTCUSDT', elementId: 'live-crypto-row-btc', lastPrice: 0 }, { symbol: 'ETHUSDT', elementId: 'live-crypto-row-eth', lastPrice: 0 } ]; async function fetchAndupdate(ticker, rowElement) { try { const response = await fetch(`api/ticker.php?symbol=${ticker.symbol}`); if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); const data = await response.json(); if (data.error) throw new Error(`API Error: ${data.error}`); updateRow(data, ticker, rowElement); } catch (error) { console.error(`Failed to fetch live price for ${ticker.symbol}:`, error); const priceCell = rowElement.querySelector('.price'); if (priceCell) priceCell.textContent = 'Error'; } } function updateRow(data, ticker, rowElement) { const priceCell = rowElement.querySelector('.price'); const symbolCell = rowElement.querySelector('.symbol'); const exchangeCell = rowElement.querySelector('.exchange'); if (!priceCell || !symbolCell || !exchangeCell) { console.error(`One or more required elements not found in row for ${ticker.symbol}`); return; } const currentPrice = parseFloat(data.price); priceCell.textContent = `${currentPrice.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; symbolCell.textContent = data.symbol.replace('_SPBL', ''); exchangeCell.textContent = data.exchange; if (ticker.lastPrice !== 0 && currentPrice !== ticker.lastPrice) { const flashClass = currentPrice > ticker.lastPrice ? 'flash-success' : 'flash-danger'; priceCell.classList.add(flashClass); setTimeout(() => priceCell.classList.remove(flashClass), 750); } ticker.lastPrice = currentPrice; } async function fetchAnalysis(ticker, rowElement) { try { const response = await fetch(`api/analysis.php?symbol=${ticker.symbol}&period=20`); if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); const data = await response.json(); if (data.error) throw new Error(`API Error: ${data.error}`); updateAnalysis(data, rowElement, ticker.lastPrice); } catch (error) { console.error(`Failed to fetch analysis for ${ticker.symbol}:`, error); const smaCell = rowElement.querySelector('.sma'); if (smaCell) smaCell.textContent = 'Error'; } } function updateAnalysis(data, rowElement, currentPrice) { const smaCell = rowElement.querySelector('.sma'); const signalCell = rowElement.querySelector('.signal'); if (!smaCell || !signalCell) return; const sma = parseFloat(data.sma); smaCell.textContent = sma.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); if (currentPrice > sma) { signalCell.innerHTML = 'Above SMA'; } else if (currentPrice < sma) { signalCell.innerHTML = 'Below SMA'; } else { signalCell.innerHTML = 'At SMA'; } } async function fetchAlert(ticker, rowElement) { try { const response = await fetch(`api/alerts.php?symbol=${ticker.symbol}`); if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); const data = await response.json(); updateAlertStatus(data.status, rowElement); } catch (error) { console.error(`Failed to fetch alert for ${ticker.symbol}:`, error); } } function updateAlertStatus(status, rowElement) { const statusCell = rowElement.querySelector('.status'); if (!statusCell) return; rowElement.classList.remove('flash-alert'); statusCell.innerHTML = '-'; if (status === 'Crash Alert') { statusCell.innerHTML = 'Crash Alert'; rowElement.classList.add('flash-alert'); } else if (status === 'Pump Alert') { statusCell.innerHTML = 'Pump Alert'; rowElement.classList.add('flash-alert'); } } function initializeLiveTickers() { liveTickers.forEach(ticker => { const rowElement = document.getElementById(ticker.elementId); if (!rowElement) { console.error(`Element with ID #${ticker.elementId} not found for symbol ${ticker.symbol}.`); return; } const fetchAll = () => { fetchAndupdate(ticker, rowElement).then(() => { fetchAnalysis(ticker, rowElement); }); fetchAlert(ticker, rowElement); }; fetchAll(); setInterval(fetchAll, POLLING_INTERVAL); }); } initializeLiveTickers(); });