Spaces:
Running
Running
IMplement a markets grid view which groups tokens by category and then uses green or red and relative grid element size to show market strength
324d1d0
verified
| // Trading interface functionality | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Initialize tooltips | |
| const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); | |
| tooltipTriggerList.forEach(tooltipTriggerEl => { | |
| new bootstrap.Tooltip(tooltipTriggerEl); | |
| }); | |
| // Tab functionality | |
| const tabButtons = document.querySelectorAll('.flex.border-b.border-gray-700 > button, .analysis-tabs > button'); | |
| tabButtons.forEach((button, index) => { | |
| button.addEventListener('click', () => { | |
| // Remove active class from all buttons | |
| tabButtons.forEach(btn => { | |
| btn.classList.remove('text-blue-400', 'border-b-2', 'border-blue-400'); | |
| btn.classList.add('text-gray-400'); | |
| }); | |
| // Add active class to clicked button | |
| button.classList.add('text-blue-400', 'border-b-2', 'border-blue-400'); | |
| button.classList.remove('text-gray-400'); | |
| // Hide all tab contents | |
| document.querySelectorAll('[data-tab-content]').forEach(tabContent => { | |
| tabContent.classList.add('hidden'); | |
| }); | |
| // Show corresponding tab content | |
| const tabContents = ['orders', 'positions', 'history', 'bot', 'scanner', 'indicator', 'grid']; | |
| document.querySelector(`[data-tab-content="${tabContents[index]}"]`).classList.remove('hidden'); | |
| }); | |
| }); | |
| // Activate first tab by default | |
| if (tabButtons.length > 0) { | |
| tabButtons[0].click(); | |
| } | |
| // Order form validation | |
| const orderForm = document.querySelector('#order-form'); | |
| if (orderForm) { | |
| orderForm.addEventListener('submit', (e) => { | |
| e.preventDefault(); | |
| // Validate and submit order | |
| }); | |
| } | |
| }); | |
| // Trading Bot functionality | |
| let trainingInterval = null; | |
| function startTrainingBot() { | |
| const episodes = parseInt(document.getElementById('bot-episodes').value); | |
| let currentEpisode = 0; | |
| // Update UI | |
| document.getElementById('start-training').disabled = true; | |
| document.getElementById('stop-training').disabled = false; | |
| document.getElementById('training-status').textContent = 'Training...'; | |
| // Simulate training progress | |
| trainingInterval = setInterval(() => { | |
| currentEpisode++; | |
| const progress = (currentEpisode / episodes) * 100; | |
| // Update metrics | |
| document.getElementById('current-episode').textContent = `${currentEpisode}/${episodes}`; | |
| document.getElementById('avg-reward').textContent = (Math.random() * 10).toFixed(2); | |
| document.getElementById('win-rate').textContent = `${Math.min(100, Math.floor(progress * 0.8))}%`; | |
| // Complete training | |
| if (currentEpisode >= episodes) { | |
| stopTrainingBot(); | |
| document.getElementById('training-status').textContent = 'Completed'; | |
| } | |
| }, 1000); | |
| } | |
| function stopTrainingBot() { | |
| clearInterval(trainingInterval); | |
| document.getElementById('start-training').disabled = false; | |
| document.getElementById('stop-training').disabled = true; | |
| document.getElementById('training-status').textContent = 'Stopped'; | |
| } | |
| // Initialize bot controls | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const startBtn = document.getElementById('start-training'); | |
| const stopBtn = document.getElementById('stop-training'); | |
| const startTradingBtn = document.getElementById('start-trading'); | |
| const stopTradingBtn = document.getElementById('stop-trading'); | |
| const paperModeBtn = document.getElementById('paper-mode'); | |
| const liveModeBtn = document.getElementById('live-mode'); | |
| if (startBtn) { | |
| startBtn.addEventListener('click', startTrainingBot); | |
| } | |
| if (stopBtn) { | |
| stopBtn.addEventListener('click', stopTrainingBot); | |
| } | |
| // Trading buttons | |
| if (startTradingBtn) { | |
| startTradingBtn.addEventListener('click', () => { | |
| startTradingBtn.disabled = true; | |
| stopTradingBtn.disabled = false; | |
| document.getElementById('running-status').textContent = 'Yes'; | |
| document.getElementById('last-action').textContent = 'Started trading'; | |
| }); | |
| } | |
| if (stopTradingBtn) { | |
| stopTradingBtn.addEventListener('click', () => { | |
| startTradingBtn.disabled = false; | |
| stopTradingBtn.disabled = true; | |
| document.getElementById('running-status').textContent = 'No'; | |
| document.getElementById('last-action').textContent = 'Stopped trading'; | |
| }); | |
| } | |
| // Paper/Live toggle | |
| if (paperModeBtn && liveModeBtn) { | |
| paperModeBtn.addEventListener('click', () => { | |
| paperModeBtn.classList.add('bg-gray-800', 'text-white'); | |
| paperModeBtn.classList.remove('text-gray-400'); | |
| liveModeBtn.classList.remove('bg-gray-800', 'text-white'); | |
| liveModeBtn.classList.add('text-gray-400'); | |
| }); | |
| liveModeBtn.addEventListener('click', () => { | |
| liveModeBtn.classList.add('bg-gray-800', 'text-white'); | |
| liveModeBtn.classList.remove('text-gray-400'); | |
| paperModeBtn.classList.remove('bg-gray-800', 'text-white'); | |
| paperModeBtn.classList.add('text-gray-400'); | |
| }); | |
| } | |
| }); | |
| // Simulate live price updates and update footer | |
| function startLivePrices() { | |
| const pairs = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT']; | |
| setInterval(() => { | |
| pairs.forEach(pair => { | |
| const change = (Math.random() * 0.2 - 0.1).toFixed(2); | |
| const currentPrice = parseFloat(document.querySelector('.live-price')?.textContent.split(' ')[0].replace(/,/g, '') || '25432.12'); | |
| const newPrice = (currentPrice * (1 + parseFloat(change)/100)).toFixed(2); | |
| const direction = parseFloat(change) >= 0 ? 'β²' : 'βΌ'; | |
| const colorClass = parseFloat(change) >= 0 ? 'price-up' : 'price-down'; | |
| // Update main chart price | |
| const priceEl = document.querySelector('.live-price'); | |
| if (priceEl) { | |
| priceEl.textContent = `${formatPrice(newPrice)} ${direction}`; | |
| priceEl.className = `text-xs ml-1 ${parseFloat(change) >= 0 ? 'text-green-400' : 'text-red-400'}`; | |
| } | |
| // Update footer price | |
| const footerPrice = document.querySelector('custom-footer')?.shadowRoot.getElementById('current-price'); | |
| const footerChange = document.querySelector('custom-footer')?.shadowRoot.getElementById('price-change'); | |
| if (footerPrice && footerChange) { | |
| footerPrice.textContent = formatPrice(newPrice); | |
| footerChange.textContent = `${parseFloat(change) >= 0 ? '+' : ''}${change}%`; | |
| footerChange.className = `price-change ${colorClass}`; | |
| } | |
| }); | |
| }, 1000); | |
| } | |
| document.addEventListener('DOMContentLoaded', () => { | |
| startLivePrices(); | |
| // Simulate bot status changes | |
| setInterval(() => { | |
| const botStatus = document.querySelector('custom-footer')?.shadowRoot.getElementById('bot-status'); | |
| const indicator = botStatus?.querySelector('.status-indicator'); | |
| if (botStatus && indicator) { | |
| const isActive = Math.random() > 0.3; | |
| if (isActive) { | |
| botStatus.innerHTML = '<span class="status-indicator" style="background:#10b981"></span> Active'; | |
| } else { | |
| botStatus.innerHTML = '<span class="status-indicator" style="background:#ef4444"></span> Paused'; | |
| } | |
| } | |
| }, 5000); | |
| }); | |
| // Custom indicator event handling | |
| document.addEventListener('indicator-created', (e) => { | |
| const { fn, config } = e.detail; | |
| console.log('Custom indicator created:', config); | |
| // Here you would typically add the indicator to your chart | |
| // For TradingView widget you would use: | |
| // widget.chart().createStudy('Custom Study', false, false, [/* inputs */], (study) => { | |
| // study.setCallback({ | |
| // onData: (data) => { | |
| // const result = fn(data); | |
| // if (result) { | |
| // data.setValue(result.value); | |
| // if (result.color) data.setLineColor(result.color); | |
| // } | |
| // } | |
| // }); | |
| // }); | |
| }); | |
| // Utility functions | |
| function formatPrice(price) { | |
| return parseFloat(price).toLocaleString('en-US', { | |
| minimumFractionDigits: 2, | |
| maximumFractionDigits: 2 | |
| }); | |
| } | |
| function formatAmount(amount) { | |
| return parseFloat(amount).toLocaleString('en-US', { | |
| minimumFractionDigits: 4, | |
| maximumFractionDigits: 4 | |
| }); | |
| } |