Market Cycle Analysis Tool

Market Cycle Analysis Tool

Identify market phases using technical indicators.

Price Action & Market Phases

Settings & Data

Indicator Settings

Historical Daily Data

Date Price Volume

${value}

`; function renderChart(chartData) { if (cycleChart) cycleChart.destroy(); const chartDefaults = { scales: { x: { type: 'time', time: { unit: 'month' }, grid: { color: '#374151' } }, y: { grid: { color: '#374151' } } }, plugins: { legend: { labels: { color: '#d1d5db' } } } }; Chart.defaults.color = '#d1d5db'; cycleChart = new Chart(document.getElementById('cycle-chart'), { type: 'line', data: { labels: state.historicalData.map(d => d.date), datasets: [ { label: 'Price', data: state.historicalData.map(d => d.price), borderColor: '#f3f4f6', borderWidth: 2, pointRadius: 0 }, { label: `SMA(${state.settings.shortMa})`, data: chartData.shortMa, borderColor: '#60a5fa', borderWidth: 1.5, pointRadius: 0 }, { label: `SMA(${state.settings.longMa})`, data: chartData.longMa, borderColor: '#facc15', borderWidth: 1.5, pointRadius: 0 } ] }, options: { ...chartDefaults }, plugins: [{ id: 'background', beforeDraw: (chart) => { const { ctx, chartArea, scales } = chart; const phaseColors = { 'Accumulation': 'rgba(22, 163, 74, 0.1)', 'Markup': 'rgba(59, 130, 246, 0.1)', 'Distribution': 'rgba(202, 138, 4, 0.1)', 'Markdown': 'rgba(220, 38, 38, 0.1)', 'Undefined': 'rgba(107, 114, 128, 0.1)' }; const phases = state.analysisResult?.chartData?.phases; if (!phases) return; ctx.save(); for (let i = 0; i < chart.data.labels.length - 1; i++) { if (!chart.data.labels[i+1]) continue; const xStart = scales.x.getPixelForValue(new Date(chart.data.labels[i]).getTime()); const xEnd = scales.x.getPixelForValue(new Date(chart.data.labels[i+1]).getTime()); const phase = phases[i]; const bgColor = phaseColors[phase] || 'transparent'; if (bgColor !== 'transparent') { ctx.fillStyle = bgColor; ctx.fillRect(xStart, chartArea.top, xEnd - xStart, chartArea.height); } } ctx.restore(); }}] }); } runAnalysisBtn.addEventListener('click', runAnalysis); // --- PDF GENERATION --- async function generatePdfReport() { if (!state.analysisResult) return alert("Please run an analysis first."); downloadPdfBtn.disabled = true; downloadPdfBtn.textContent = 'Generating...'; const chartImg = cycleChart.toBase64Image(); const { kpis } = state.analysisResult; const reportHtml = `

Market Cycle Analysis Report

${state.settings.ticker} | As of ${new Date().toLocaleDateString()}

Current Market Assessment

Current Identified Phase
${kpis.currentPhase}
Last Closing Price
$${kpis.price.toLocaleString()}

Market Cycle Chart

`; const pdfTemplate = document.getElementById('pdf-template'); pdfTemplate.innerHTML = reportHtml; pdfTemplate.classList.remove('invisible'); try { const { jsPDF } = window.jspdf; const canvas = await html2canvas(pdfTemplate.querySelector('.pdf-report-container'), { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); pdf.addImage(imgData, 'PNG', 0, 0, pdf.internal.pageSize.getWidth(), (canvas.height * pdf.internal.pageSize.getWidth()) / canvas.width); pdf.save(`${state.settings.ticker.replace(/\s+/g, '_')}_Cycle_Analysis.pdf`); } catch(e) { console.error('PDF Generation Error:', e); } finally { downloadPdfBtn.disabled = false; downloadPdfBtn.textContent = 'Download Analysis Report'; pdfTemplate.classList.add('invisible'); } } downloadPdfBtn.addEventListener('click', generatePdfReport); // --- INITIALIZATION --- generateSampleData(); populateSettingsUI(); renderDataTable(); attachDataListeners(); runAnalysis(); switchTab(0); });
Scroll to Top