Equity Research Automation Tool
Analyze companies with relative valuation using comparable company analysis (CCA).
Implied Valuation Range
Based on median multiples of comparable companies.
Valuation Summary
Football Field Valuation Chart
Target Company Financials
Comparable Company Analysis (CCA) Data
| Company Name | EV/Revenue | EV/EBITDA | P/E Ratio |
|---|
Valuation Adjustments
Apply a premium for superior growth/margins, or a discount for higher risk.
P/E Ratio implies a valuation of ${formatCurrency(valuations.impliedValPe)}.
The blended average valuation is estimated at ${formatCurrency(avgValuation)}.
`; // Update Valuation Chart (Bar) const chartCtx = document.getElementById('valuationChart').getContext('2d'); if (valuationChart) valuationChart.destroy(); valuationChart = new Chart(chartCtx, { type: 'bar', data: { labels: ['EV/Revenue', 'EV/EBITDA', 'P/E Ratio'], datasets: [{ label: 'Implied Valuation ($M)', data: [valuations.impliedValRevenue, valuations.impliedValEbitda, valuations.impliedValPe], backgroundColor: ['#34d399', '#6ee7b7', '#a7f3d0'], borderColor: '#10b981', borderWidth: 1 }] }, options: { responsive: true, plugins: { legend: { display: false } } } }); // Update Football Field Chart const footballFieldCtx = document.getElementById('footballFieldChart').getContext('2d'); if (footballFieldChart) footballFieldChart.destroy(); footballFieldChart = new Chart(footballFieldCtx, { type: 'bar', data: { labels: ['EV/Revenue', 'EV/EBITDA', 'P/E Ratio'], datasets: [{ label: 'Valuation Range ($M)', data: [ [valuations.impliedValRevenue * 0.9, valuations.impliedValRevenue * 1.1], [valuations.impliedValEbitda * 0.9, valuations.impliedValEbitda * 1.1], [valuations.impliedValPe * 0.9, valuations.impliedValPe * 1.1] ], backgroundColor: '#6ee7b7', barPercentage: 0.5, }] }, options: { indexAxis: 'y', responsive: true, plugins: { legend: { display: false } } } }); } // --- EVENT HANDLING --- document.getElementById('target-form').addEventListener('input', updateDashboard); document.getElementById('comps-table-body').addEventListener('input', (e) => { if(e.target.tagName === 'INPUT') { const { index, field } = e.target.dataset; const value = e.target.type === 'number' ? parseFloat(e.target.value) : e.target.value; researchData.comps[index][field] = value; updateDashboard(); } }); document.getElementById('comps-table-body').addEventListener('click', (e) => { if(e.target.classList.contains('remove-row-btn')) { researchData.comps.splice(e.target.dataset.index, 1); renderCompsTable(); updateDashboard(); } }); document.getElementById('add-comp-row').addEventListener('click', () => { researchData.comps.push({ name: '', evRevenue: 0, evEbitda: 0, pe: 0 }); renderCompsTable(); }); const premiumSlider = document.getElementById('valuation-premium'); premiumSlider.addEventListener('input', () => { document.getElementById('valuation-premium-val').textContent = `${premiumSlider.value}%`; updateDashboard(); }); // --- PDF GENERATION --- document.getElementById('download-pdf-btn').addEventListener('click', () => { const results = calculateValuation(); if (!results) return; const doc = new jsPDF(); const primaryColor = '#15803d'; // green-700 const secondaryColor = '#475569'; // slate-600 let cursorY = 20; // Header doc.setFontSize(22); doc.setFontStyle('bold'); doc.setTextColor(primaryColor); doc.text(`Equity Research Report: ${researchData.target.name}`, 105, cursorY, { align: 'center' }); cursorY += 8; doc.setFontSize(10); doc.setFontStyle('normal'); doc.setTextColor(secondaryColor); doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 105, cursorY, { align: 'center' }); cursorY += 15; // Summary doc.setFontSize(16); doc.setTextColor(primaryColor); doc.text('Valuation Summary', 14, cursorY); cursorY += 8; const summaryText = document.getElementById('valuation-summary').innerText; doc.setFontSize(11); doc.setTextColor(secondaryColor); doc.text(doc.splitTextToSize(summaryText, 180), 14, cursorY); cursorY += 30; // Football Field Chart doc.addImage(footballFieldChart.toBase64Image('image/png', 1.0), 'PNG', 14, cursorY, 180, 80); cursorY += 90; // Data Tables doc.autoTable({ startY: cursorY, head: [['Target Company Financials ($M)', 'Value']], body: [ ['LTM Revenue', researchData.target.revenue.toFixed(2)], ['LTM EBITDA', researchData.target.ebitda.toFixed(2)], ['LTM Net Income', researchData.target.netIncome.toFixed(2)], ], theme: 'striped', headStyles: { fillColor: secondaryColor } }); cursorY = doc.autoTable.previous.finalY + 15; doc.autoTable({ startY: cursorY, head: [['Comparable Companies', 'EV/Revenue', 'EV/EBITDA', 'P/E Ratio']], body: researchData.comps.map(c => [c.name, c.evRevenue.toFixed(1) + 'x', c.evEbitda.toFixed(1) + 'x', c.pe.toFixed(1) + 'x']), theme: 'grid', headStyles: { fillColor: primaryColor } }); cursorY = doc.autoTable.previous.finalY + 10; doc.autoTable({ startY: cursorY, head: [['Valuation Metrics', 'Implied Value ($M)']], body: [ [`Median EV/Revenue Multiple (${results.metrics.medianEvRevenue.toFixed(1)}x)`, results.valuations.impliedValRevenue.toFixed(2)], [`Median EV/EBITDA Multiple (${results.metrics.medianEvEbitda.toFixed(1)}x)`, results.valuations.impliedValEbitda.toFixed(2)], [`Median P/E Multiple (${results.metrics.medianPe.toFixed(1)}x)`, results.valuations.impliedValPe.toFixed(2)], ], theme: 'striped', headStyles: { fillColor: secondaryColor } }); doc.save(`${researchData.target.name}-Equity-Research.pdf`); }); // --- INITIALIZATION --- renderCompsTable(); updateDashboard(); setActiveTab('dashboard'); });