Real-Time Market Fear & Greed Index
Current Market Sentiment
--
Calculating...
Extreme Fear (0)
Neutral (50)
Extreme Greed (100)
The Fear & Greed Index is a tool to gauge current investor sentiment in the market.
Historical Index View
Loading historical data...
No historical data to display.
`; return; } data.forEach(item => { const bar = document.createElement('div'); bar.className = 'chart-bar'; const barHeight = (item.value / 100) * (historicalChartContainer.clientHeight - 20); // -20 for padding bar.style.height = `${Math.max(barHeight, 5)}px`; // Min height 5px bar.style.backgroundColor = getIndexSentiment(item.value).color; const valueLabel = document.createElement('span'); valueLabel.className = 'chart-bar-value'; valueLabel.textContent = item.value; bar.appendChild(valueLabel); historicalChartContainer.appendChild(bar); }); }; // --- "Real-Time" Simulation --- const simulateRealTimeUpdate = () => { let change = Math.floor(Math.random() * 7) - 3; // -3 to +3 currentIndexValue += change; if (currentIndexValue < 0) currentIndexValue = 0; if (currentIndexValue > 100) currentIndexValue = 100; updateIndexDisplay(currentIndexValue); }; // --- PDF Download Functionality --- const downloadPDF = () => { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { showMessage('PDF generation library (jsPDF) is not loaded.', 'error'); console.error("jsPDF main library (window.jspdf.jsPDF) is not loaded."); return; } const { jsPDF: JSPDF } = window.jspdf; const doc = new JSPDF(); // Check for autoTable, though not strictly needed for this PDF layout if (typeof doc.autoTable !== 'function') { console.warn("jsPDF autoTable plugin is not available, but not critical for this PDF."); } const today = new Date().toLocaleDateString('en-US'); const appTitle = "Market Fear & Greed Index"; const sentiment = getIndexSentiment(currentIndexValue); doc.setFontSize(18); doc.text(appTitle, 14, 22); doc.setFontSize(11); doc.setTextColor(100); doc.text(`Report Generated: ${today}`, 14, 30); doc.setFontSize(14); doc.text("Current Market Sentiment:", 14, 45); doc.setFontSize(22); doc.setTextColor(sentiment.color.startsWith('#') ? sentiment.color : '#000000'); // Use sentiment color doc.text(`${currentIndexValue} - ${sentiment.text}`, 14, 55); doc.setTextColor(0); // Reset color to black doc.setFontSize(10); const interpretationLines = doc.splitTextToSize(getInterpretation(currentIndexValue, sentiment.text), 180); doc.text(interpretationLines, 14, 65); let yPos = 65 + (interpretationLines.length * 5) + 10; // Start historical data below interpretation // Add historical data (simplified for PDF) doc.setFontSize(12); doc.text("Historical Data Snapshot:", 14, yPos); yPos += 7; const selectedPeriod = timeframeSelector ? timeframeSelector.options[timeframeSelector.selectedIndex].text : "Last 30 Days"; doc.setFontSize(10); doc.text(`Period: ${selectedPeriod}`, 14, yPos); yPos += 7; const historicalForPdf = generateHistoricalData(timeframeSelector ? parseInt(timeframeSelector.value.replace('d','')) : 30).slice(-7); // Last 7 points of selected period if (historicalForPdf.length > 0) { let tableData = historicalForPdf.map((item, index) => [`Day ${index + 1}`, item.value, getIndexSentiment(item.value).text]); if (typeof doc.autoTable === 'function') { doc.autoTable({ head: [['Time Point', 'Index Value', 'Sentiment']], body: tableData, startY: yPos, theme: 'grid', headStyles: { fillColor: [75, 85, 99] }, // gray-600 styles: { fontSize: 8 } }); } else { // Fallback if autoTable is not there doc.text("Historical data (last 7 points from selected period):", 14, yPos); yPos +=5; historicalForPdf.forEach((item, index) => { doc.text(`- Day ${index+1}: ${item.value} (${getIndexSentiment(item.value).text})`, 14, yPos); yPos+=5; if (yPos > 280) { doc.addPage(); yPos = 20;} }); } } else { doc.text("No historical data to display for PDF.", 14, yPos); } doc.save(`${appTitle} - ${today}.pdf`); showMessage('PDF downloaded successfully!', 'success'); }; // --- Event Listeners --- if (timeframeSelector) { timeframeSelector.addEventListener('change', renderHistoricalChart); } if (downloadPdfButton) { downloadPdfButton.addEventListener('click', downloadPDF); } // --- Initialization --- const initializeApp = () => { if (currentYearSpan) { currentYearSpan.textContent = new Date().getFullYear(); } updateIndexDisplay(currentIndexValue); // Initial display renderHistoricalChart(); // Initial historical chart setInterval(simulateRealTimeUpdate, 5000); // Update every 5 seconds showMessage('Fear & Greed Index initialized.', 'success', 1500); }; initializeApp(); });