// Global variables let trades = []; let currentMarketPrice = 0; let marketData = []; // Initialize the application document.addEventListener('DOMContentLoaded', function() { // Set default date to today const today = new Date().toISOString().split('T')[0]; document.getElementById('marketDate').value = today; // Add first trade addTrade(); // Set up event listeners document.getElementById('fetchDataBtn').addEventListener('click', fetchMarketData); document.getElementById('addTradeBtn').addEventListener('click', addTrade); // Price slider and input synchronization const priceSlider = document.getElementById('priceSlider'); const priceInput = document.getElementById('priceInput'); priceSlider.addEventListener('input', function() { currentMarketPrice = parseFloat(this.value); priceInput.value = currentMarketPrice.toFixed(2); updateAllCalculations(); }); priceInput.addEventListener('input', function() { currentMarketPrice = parseFloat(this.value) || 0; priceSlider.value = currentMarketPrice; updateAllCalculations(); }); }); // Fetch market data from API async function fetchMarketData() { const symbol = document.getElementById('stockSymbol').value.trim().toUpperCase() || 'RELIANCE'; const date = document.getElementById('marketDate').value; if (!date) { alert('Please select a date'); return; } // Show loading state const btn = document.getElementById('fetchDataBtn'); const originalText = btn.innerHTML; btn.innerHTML = ' Loading...'; btn.disabled = true; try { // Convert date to timestamps const startDate = new Date(date + 'T00:01:00'); const endDate = new Date(date + 'T23:58:00'); const startTime = startDate.getTime(); const endTime = endDate.getTime(); // Construct API URL const url = `http://localhost:5000/chart?ticker=${symbol}&date=${date}`; const response = await fetch(url); const data = await response.json(); if (data && data.length > 0) { marketData = data; // Process data - we'll use the times as-is (assuming they're in proper format) const processedData = marketData.map(item => ({ price: item.price, time: item.time })); // Update UI updateMarketInfo(processedData); document.getElementById('marketInfo').classList.remove('hidden'); // Set initial price if (processedData.length > 0) { currentMarketPrice = processedData[processedData.length - 1].price; document.getElementById('priceSlider').value = currentMarketPrice; document.getElementById('priceInput').value = currentMarketPrice.toFixed(2); updateAllCalculations(); } } else { alert('No data available for the selected date'); } } catch (error) { console.error('Error fetching market data:', error); alert('Failed to fetch market data. Please try again.'); } finally { // Reset button state btn.innerHTML = originalText; btn.disabled = false; feather.replace(); } } // Update market info display function updateMarketInfo(data) { const currentPrice = data[data.length - 1].price; const lastUpdated = data[data.length - 1].time; document.getElementById('currentPrice').textContent = `₹${currentPrice.toFixed(2)}`; document.getElementById('lastUpdated').textContent = lastUpdated; // Update slider range based on data const prices = data.map(d => d.price); const minPrice = Math.min(...prices) * 0.9; const maxPrice = Math.max(...prices) * 1.1; const slider = document.getElementById('priceSlider'); slider.min = minPrice; slider.max = maxPrice; } // Add a new trade function addTrade() { const tradeId = 'trade_' + Date.now(); const trade = { id: tradeId, type: 'BUY', quantity: 0, price: 0 }; trades.push(trade); renderTrade(trade); } // Render trade UI function renderTrade(trade) { const container = document.getElementById('tradesContainer'); const tradeElement = document.createElement('div'); tradeElement.id = trade.id; tradeElement.className = 'bg-gray-700 rounded-lg p-4 border border-gray-600'; tradeElement.innerHTML = `
₹0.00
`; container.appendChild(tradeElement); // Set up event listeners tradeElement.querySelector('.trade-type-btn[data-type="BUY"]').addEventListener('click', function() { updateTradeType(trade.id, 'BUY'); }); tradeElement.querySelector('.trade-type-btn[data-type="SELL"]').addEventListener('click', function() { updateTradeType(trade.id, 'SELL'); }); tradeElement.querySelector('.trade-quantity').addEventListener('input', function() { updateTradeQuantity(trade.id, parseFloat(this.value) || 0); }); tradeElement.querySelector('.trade-price').addEventListener('input', function() { updateTradePrice(trade.id, parseFloat(this.value) || 0); }); tradeElement.querySelector('.remove-trade-btn').addEventListener('click', function() { removeTrade(trade.id); }); feather.replace(); } // Update trade type function updateTradeType(tradeId, type) { const trade = trades.find(t => t.id === tradeId); if (trade) { trade.type = type; // Update UI const tradeElement = document.getElementById(tradeId); const buyBtn = tradeElement.querySelector('.trade-type-btn[data-type="BUY"]'); const sellBtn = tradeElement.querySelector('.trade-type-btn[data-type="SELL"]'); if (type === 'BUY') { buyBtn.className = 'trade-type-btn flex-1 py-2 px-3 rounded-md text-sm font-medium transition-colors bg-blue-600 text-white'; sellBtn.className = 'trade-type-btn flex-1 py-2 px-3 rounded-md text-sm font-medium transition-colors text-gray-300'; } else { buyBtn.className = 'trade-type-btn flex-1 py-2 px-3 rounded-md text-sm font-medium transition-colors text-gray-300'; sellBtn.className = 'trade-type-btn flex-1 py-2 px-3 rounded-md text-sm font-medium transition-colors bg-purple-600 text-white'; } updateCalculations(tradeId); } } // Update trade quantity function updateTradeQuantity(tradeId, quantity) { const trade = trades.find(t => t.id === tradeId); if (trade) { trade.quantity = quantity; updateCalculations(tradeId); } } // Update trade price function updateTradePrice(tradeId, price) { const trade = trades.find(t => t.id === tradeId); if (trade) { trade.price = price; updateCalculations(tradeId); } } // Remove trade function removeTrade(tradeId) { trades = trades.filter(t => t.id !== tradeId); const tradeElement = document.getElementById(tradeId); tradeElement.remove(); updateTotalPL(); } // Update calculations for a specific trade function updateCalculations(tradeId) { const trade = trades.find(t => t.id === tradeId); if (!trade) return; const pl = calculatePL(trade); const tradeElement = document.getElementById(tradeId); const plElement = tradeElement.querySelector('.trade-pl'); plElement.textContent = `₹${pl.toFixed(2)}`; // Apply color based on profit/loss plElement.classList.remove('text-green-400', 'text-red-400', 'profit-pulse', 'loss-pulse'); if (pl > 0) { plElement.classList.add('text-green-400', 'profit-pulse'); } else if (pl < 0) { plElement.classList.add('text-red-400', 'loss-pulse'); } updateTotalPL(); } // Calculate P&L for a single trade function calculatePL(trade) { if (trade.quantity === 0) return 0; let pl; if (trade.type === 'BUY') { pl = (currentMarketPrice - trade.price) * trade.quantity; } else { pl = (trade.price - currentMarketPrice) * trade.quantity; } return pl; } // Update total P&L function updateTotalPL() { const totalPL = trades.reduce((sum, trade) => sum + calculatePL(trade), 0); const totalPLElement = document.getElementById('totalPLValue'); totalPLElement.textContent = `₹${totalPL.toFixed(2)}`; totalPLElement.classList.remove('text-green-400', 'text-red-400'); if (totalPL > 0) { totalPLElement.classList.add('text-green-400'); } else if (totalPL < 0) { totalPLElement.classList.add('text-red-400'); } } // Update all calculations function updateAllCalculations() { trades.forEach(trade => updateCalculations(trade.id)); }