Private Company Valuation & IPO Pricing Simulator

Private Company Valuation & IPO Pricing Simulator

1. Assumptions

Company Financials (Current Year)

Growth Projections (for DCF)

Valuation Inputs

IPO Specifics

Please fix input errors to see valuation summary.

'; document.getElementById('ipoPricingOutput').innerHTML = '

Please fix input errors to see IPO pricing.

'; return; } // Additional validation for terminal growth rate vs WACC if (terminalGrowthRate >= (riskFreeRate + marketRiskPremium * beta)) { // Assuming WACC ~ Cost of Equity here for quick check showMessage('Terminal Growth Rate must be less than WACC for DCF calculation.', 'error'); window.valuationIPOResults = null; return; } // --- Valuation Analysis --- // Calculate Cost of Equity (CAPM) const costOfEquity = riskFreeRate + beta * marketRiskPremium; // Calculate WACC const wacc = calculateWACC(costOfEquity, costOfDebt, taxRate, equityPercentageWACC); if (wacc <= 0) { // WACC must be positive for discounting showMessage('Calculated WACC is zero or negative, cannot perform DCF. Adjust inputs.', 'error'); window.valuationIPOResults = null; return; } // DCF Projection const dcfProjections = []; let projectedRevenue = currentRevenue; let projectedEBITDA = currentEbitda; let projectedNetIncome = currentNetIncome; // Tracked for P/E multiple let previousRevenue = currentRevenue; // For NWC change calculation for (let i = 0; i < projectionYears; i++) { const year = i + 1; if (i > 0) { // Project from year 1 onwards projectedRevenue *= (1 + revenueGrowthRate); } projectedEBITDA = projectedRevenue * ebitdaMarginProjection; const ebit = projectedEBITDA; // Simplified: assuming EBITDA is close to EBIT for FCF const taxes = ebit * taxRate; const unleveredEBIT = ebit * (1 - taxRate); // EBIT(1-tax) // Simplified Depreciation & Amortization (D&A) - assume 0 for this basic model, or a fixed % of revenue/EBITDA const dAndA = 0; const capex = projectedRevenue * capexAsPctRevenue; // Simplified Change in NWC: (Current Revenue * NWC % ) - (Previous Revenue * NWC %) const changeInNWC = (projectedRevenue * nwcAsPctRevenue) - (previousRevenue * nwcAsPctRevenue); // Unlevered Free Cash Flow (UFCF) const ufcf = unleveredEBIT + dAndA - capex - changeInNWC; dcfProjections.push({ year: year, projectedRevenue: projectedRevenue, projectedEBITDA: projectedEBITDA, unleveredEBIT: unleveredEBIT, capex: capex, changeInNWC: changeInNWC, ufcf: ufcf }); previousRevenue = projectedRevenue; } // Terminal Value (last projected year's UFCF) const lastYearUFCF = dcfProjections[projectionYears - 1].ufcf; let terminalValue = 0; if (wacc > terminalGrowthRate) { terminalValue = (lastYearUFCF * (1 + terminalGrowthRate)) / (wacc - terminalGrowthRate); } else { showMessage('Terminal Growth Rate must be less than WACC for valid Terminal Value. Adjust inputs.', 'error'); window.valuationIPOResults = null; return; } // Present Value of UFCFs let pvUFCFs = 0; dcfProjections.forEach((proj, index) => { pvUFCFs += proj.ufcf / Math.pow(1 + wacc, proj.year); }); // Present Value of Terminal Value const pvTerminalValue = terminalValue / Math.pow(1 + wacc, projectionYears); // DCF Enterprise Value const dcfEnterpriseValue = pvUFCFs + pvTerminalValue; // DCF Equity Value const dcfEquityValue = dcfEnterpriseValue + currentCash - totalDebt; // Multiples Valuation const ebitdaMultipleValuation = currentEbitda * comparableEbitdaMultiple; const peMultipleValuation = currentNetIncome * comparablePEMultiple; // Blended Valuation (Pre-Discount) const blendedPreDiscountValuation = (dcfEquityValue * dcfWeight) + (ebitdaMultipleValuation * (1 - dcfWeight)); // Using EBITDA multiple for blended, P/E might be used too // Final Private Company Valuation (applying private company discount) const finalPrivateCompanyValuation = blendedPreDiscountValuation * (1 - privateCompanyDiscount); // Implied Current Share Price const impliedCurrentSharePrice = finalPrivateCompanyValuation / currentSharesOutstanding; // --- IPO Pricing Simulation --- // Pre-Money Valuation for IPO is the Final Private Company Valuation const ipoPreMoneyValuation = finalPrivateCompanyValuation; // Capital Raised from user input const ipoCapitalRaised = capitalToRaise; // Post-Money Valuation const ipoPostMoneyValuation = ipoPreMoneyValuation + ipoCapitalRaised; // IPO Offer Price Per Share (derived from Post-Money and % to sell) // If %CompanyToSell is used as a driver: const totalSharesPostIPO_derivedByPercent = currentSharesOutstanding / (1 - percentCompanyToSell); const sharesIssuedInIPO_derivedByPercent = totalSharesPostIPO_derivedByPercent - currentSharesOutstanding; let ipoOfferPricePerShare = ipoPostMoneyValuation / totalSharesPostIPO_derivedByPercent; // Fallback for IPO Offer Price Per Share if the derived shares are not practical if (ipoOfferPricePerShare <= 0 || isNaN(ipoOfferPricePerShare)) { // If a fixed capital raise is also used, we need an assumption on how many shares that capital represents. // Simplest: use calculated pre-money valuation to imply new shares if a 'target price' isn't set. // For simplicity, we'll assume the 'percentCompanyToSell' dictates new shares. ipoOfferPricePerShare = ipoCapitalRaised / sharesIssuedInIPO_derivedByPercent; // Re-calculate based on capital raised and derived shares } // Shares Issued in IPO const ipoSharesIssued = sharesIssuedInIPO_derivedByPercent; // Based on % of company to sell // Total Shares Outstanding Post-IPO const ipoTotalSharesPost = currentSharesOutstanding + ipoSharesIssued; // Existing Shareholder Dilution const ipoDilution = ipoSharesIssued / ipoTotalSharesPost; // Net Proceeds to Company from IPO const ipoNetProceeds = ipoCapitalRaised * (1 - underwritingFees); // 2. Store results for display and PDF window.valuationIPOResults = { inputs: { currentRevenue, currentEbitda, currentNetIncome, currentCash, totalDebt, currentSharesOutstanding, projectionYears, revenueGrowthRate, ebitdaMarginProjection, taxRate, capexAsPctRevenue, nwcAsPctRevenue, riskFreeRate, marketRiskPremium, beta, costOfDebt, equityPercentageWACC, terminalGrowthRate, comparableEbitdaMultiple, comparablePEMultiple, privateCompanyDiscount, dcfWeight, capitalToRaise, underwritingFees, percentCompanyToSell }, valuationAnalysis: { costOfEquity, wacc, dcfProjections, // detailed projections terminalValue, pvUFCFs, pvTerminalValue, dcfEnterpriseValue, dcfEquityValue, ebitdaMultipleValuation, peMultipleValuation, blendedPreDiscountValuation, finalPrivateCompanyValuation, impliedCurrentSharePrice }, ipoPricing: { ipoPreMoneyValuation, ipoCapitalRaised, ipoPostMoneyValuation, ipoSharesIssued, ipoTotalSharesPost, ipoOfferPricePerShare, ipoDilution, ipoNetProceeds } }; // 3. Update UI displayValuationAnalysis(window.valuationIPOResults.valuationAnalysis, window.valuationIPOResults.inputs.projectionYears); displayIPOPricing(window.valuationIPOResults.ipoPricing); // Optionally navigate to valuation tab after calculation openTab('valuation-analysis'); showMessage('Valuation & IPO Model calculated successfully!', 'success'); } /** * Displays the valuation analysis results. * @param {object} results The valuation analysis results object. */ function displayValuationAnalysis(results, projectionYears) { // Display DCF Projections table let tableHtml = `

DCF Projections

`; results.dcfProjections.forEach(row => { tableHtml += ` `; }); tableHtml += `
Year Revenue EBITDA Unlevered EBIT (1-tax) CAPEX Change in NWC UFCF
Year ${row.year} ${formatCurrency(row.projectedRevenue)} ${formatCurrency(row.projectedEBITDA)} ${formatCurrency(row.unleveredEBIT)} ${formatCurrency(row.capex)} ${formatCurrency(row.changeInNWC)} ${formatCurrency(row.ufcf)}
`; valuationProjectionsOutputDiv.innerHTML = tableHtml; // Display Valuation Summary waccOutput.textContent = formatPercentage(results.wacc); dcfEquityValueOutput.textContent = formatCurrency(results.dcfEquityValue); ebitdaMultipleValuationOutput.textContent = formatCurrency(results.ebitdaMultipleValuation); peMultipleValuationOutput.textContent = formatCurrency(results.peMultipleValuation); blendedPreDiscountValuationOutput.textContent = formatCurrency(results.blendedPreDiscountValuation); finalPrivateCompanyValuationOutput.textContent = formatCurrency(results.finalPrivateCompanyValuation); impliedCurrentSharePriceOutput.textContent = formatCurrency(results.impliedCurrentSharePrice); } /** * Displays the IPO pricing simulation results. * @param {object} results The IPO pricing results object. */ function displayIPOPricing(results) { ipoPreMoneyValuationOutput.textContent = formatCurrency(results.ipoPreMoneyValuation); ipoCapitalRaisedOutput.textContent = formatCurrency(results.ipoCapitalRaised); ipoPostMoneyValuationOutput.textContent = formatCurrency(results.ipoPostMoneyValuation); ipoSharesIssuedOutput.textContent = results.ipoSharesIssued.toFixed(0); ipoTotalSharesPostOutput.textContent = results.ipoTotalSharesPost.toFixed(0); ipoOfferPricePerShareOutput.textContent = formatCurrency(results.ipoOfferPricePerShare); ipoDilutionOutput.textContent = formatPercentage(results.ipoDilution); ipoNetProceedsOutput.textContent = formatCurrency(results.ipoNetProceeds); } /** * Resets all input fields to their default values and clears output sections. */ function resetForm() { // Reset input values currentRevenueInput.value = "50000000"; currentEbitdaInput.value = "10000000"; currentNetIncomeInput.value = "5000000"; currentCashInput.value = "2000000"; totalDebtInput.value = "15000000"; currentSharesOutstandingInput.value = "10000000"; projectionYearsInput.value = "5"; revenueGrowthRateInput.value = "10"; ebitdaMarginProjectionInput.value = "20"; taxRateInput.value = "25"; capexAsPctRevenueInput.value = "3"; nwcAsPctRevenueInput.value = "1"; riskFreeRateInput.value = "3"; marketRiskPremiumInput.value = "6"; betaInput.value = "1.2"; costOfDebtInput.value = "5"; equityPercentageWACCInput.value = "70"; terminalGrowthRateInput.value = "2.5"; comparableEbitdaMultipleInput.value = "10"; comparablePEMultipleInput.value = "20"; privateCompanyDiscountInput.value = "20"; dcfWeightInput.value = "50"; capitalToRaiseInput.value = "20000000"; underwritingFeesInput.value = "5"; percentCompanyToSellInput.value = "20"; // Clear stored results window.valuationIPOResults = null; // Clear output divs valuationProjectionsOutputDiv.innerHTML = '

Calculate the model to see DCF projections.

'; waccOutput.textContent = ''; dcfEquityValueOutput.textContent = ''; ebitdaMultipleValuationOutput.textContent = ''; peMultipleValuationOutput.textContent = ''; blendedPreDiscountValuationOutput.textContent = ''; finalPrivateCompanyValuationOutput.textContent = ''; impliedCurrentSharePriceOutput.textContent = ''; ipoPreMoneyValuationOutput.textContent = ''; ipoCapitalRaisedOutput.textContent = ''; ipoPostMoneyValuationOutput.textContent = ''; ipoSharesIssuedOutput.textContent = ''; ipoTotalSharesPostOutput.textContent = ''; ipoOfferPricePerShareOutput.textContent = ''; ipoDilutionOutput.textContent = ''; ipoNetProceedsOutput.textContent = ''; // Reset to the first tab openTab('inputs'); hideMessage(); } /** * Downloads the Private Company Valuation & IPO Pricing Simulator results as a PDF. */ function downloadPDF() { if (!window.valuationIPOResults) { showMessage('Please calculate the model first.', 'info'); return; } const { jsPDF } = window.jspdf; const pdf = new jsPDF('p', 'mm', 'a4'); // 'p' for portrait, 'mm' for millimeters, 'a4' size const BLACK_COLOR = [31, 41, 55]; // Tailwind gray-900 equivalent const BLUE_HEADER_COLOR = [29, 78, 216]; // Tailwind blue-700 equivalent const RED_COLOR = [220, 38, 38]; // Tailwind red-600 equivalent const BLUE_TEXT_COLOR = [37, 99, 235]; // Tailwind blue-600 equivalent const GREEN_TEXT_COLOR = [22, 163, 74]; // Tailwind green-600 equivalent const GRAY_TEXT_COLOR = [75, 85, 99]; // Tailwind gray-700 equivalent let y = 15; // Y-coordinate for placing content // Title pdf.setFontSize(22); pdf.setFont('helvetica', 'bold'); pdf.setTextColor(BLACK_COLOR[0], BLACK_COLOR[1], BLACK_COLOR[2]); pdf.text('Private Company Valuation & IPO Pricing Simulator Results', 105, y, { align: 'center' }); y += 15; // --- 1. Input Parameters Section --- pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('1. Input Parameters', 15, y); y += 8; const inputs = window.valuationIPOResults.inputs; const inputData = [ ['Current Revenue', formatCurrency(inputs.currentRevenue)], ['Current EBITDA', formatCurrency(inputs.currentEbitda)], ['Current Net Income', formatCurrency(inputs.currentNetIncome)], ['Current Cash & Equivalents', formatCurrency(inputs.currentCash)], ['Total Debt', formatCurrency(inputs.totalDebt)], ['Current Shares Outstanding', inputs.currentSharesOutstanding.toLocaleString()], ['Projection Years', inputs.projectionYears], ['Annual Revenue Growth Rate', `${inputs.revenueGrowthRate * 100}%`], ['Target EBITDA Margin', `${inputs.ebitdaMarginProjection * 100}%`], ['Tax Rate', `${inputs.taxRate * 100}%`], ['CAPEX as % of Revenue', `${inputs.capexAsPctRevenue * 100}%`], ['Change in NWC as % of Revenue', `${inputs.nwcAsPctRevenue * 100}%`], ['Risk-Free Rate', `${inputs.riskFreeRate * 100}%`], ['Market Risk Premium', `${inputs.marketRiskPremium * 100}%`], ['Levered Beta', inputs.beta.toFixed(2)], ['Cost of Debt', `${inputs.costOfDebt * 100}%`], ['Equity % in Capital Structure (for WACC)', `${inputs.equityPercentageWACC * 100}%`], ['Terminal Growth Rate (DCF)', `${inputs.terminalGrowthRate * 100}%`], ['Comparable EV/EBITDA Multiple', `${inputs.comparableEbitdaMultiple}x`], ['Comparable P/E Multiple', `${inputs.comparablePEMultiple}x`], ['Private Company Discount', `${inputs.privateCompanyDiscount * 100}%`], ['DCF Weight in Blended Valuation', `${inputs.dcfWeight * 100}%`], ['Capital to Raise in IPO', formatCurrency(inputs.capitalToRaise)], ['Underwriting Fees (% of Capital Raised)', `${inputs.underwritingFees * 100}%`], ['Approx. % of Company to Sell in IPO', `${inputs.percentCompanyToSell * 100}%`] ]; pdf.autoTable({ startY: y, head: [['Parameter', 'Value']], body: inputData, theme: 'grid', styles: { fontSize: 8, cellPadding: 2, overflow: 'linebreak', lineColor: 200, lineWidth: 0.1 }, headStyles: { fillColor: BLUE_HEADER_COLOR, textColor: 255, fontStyle: 'bold' }, margin: { left: 15, right: 15 }, columnStyles: { 0: { cellWidth: 80 }, 1: { cellWidth: 'auto' } } }); y = pdf.autoTable.previous.finalY + 15; // --- 2. Valuation Analysis Section --- pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('2. Valuation Analysis', 15, y); y += 8; // DCF Projections Table const dcfProjections = window.valuationIPOResults.valuationAnalysis.dcfProjections; const dcfTableBody = dcfProjections.map(row => [ `Year ${row.year}`, formatCurrency(row.projectedRevenue), formatCurrency(row.projectedEBITDA), formatCurrency(row.unleveredEBIT), formatCurrency(row.capex), formatCurrency(row.changeInNWC), formatCurrency(row.ufcf) ]); pdf.autoTable({ startY: y, head: [['Year', 'Revenue', 'EBITDA', 'Unlevered EBIT (1-tax)', 'CAPEX', 'Change in NWC', 'UFCF']], body: dcfTableBody, theme: 'grid', styles: { fontSize: 7, cellPadding: 1, overflow: 'linebreak', lineColor: 200, lineWidth: 0.1 }, headStyles: { fillColor: BLUE_HEADER_COLOR, textColor: 255, fontStyle: 'bold' }, margin: { left: 15, right: 15 }, didParseCell: function (data) { if (data.column.index >= 1) { // Align currency columns right data.cell.styles.halign = 'right'; } } }); y = pdf.autoTable.previous.finalY + 10; // Valuation Summary const valuationSummary = window.valuationIPOResults.valuationAnalysis; const summaryItems = [ { label: 'WACC:', value: formatPercentage(valuationSummary.wacc), color: GRAY_TEXT_COLOR }, { label: 'DCF Equity Value:', value: formatCurrency(valuationSummary.dcfEquityValue), color: BLUE_TEXT_COLOR }, { label: 'EV/EBITDA Multiple Valuation:', value: formatCurrency(valuationSummary.ebitdaMultipleValuation), color: BLUE_TEXT_COLOR }, { label: 'P/E Multiple Valuation:', value: formatCurrency(valuationSummary.peMultipleValuation), color: BLUE_TEXT_COLOR }, { label: 'Blended Pre-Discount Valuation:', value: formatCurrency(valuationSummary.blendedPreDiscountValuation), color: BLUE_TEXT_COLOR }, { label: 'Final Private Company Valuation:', value: formatCurrency(valuationSummary.finalPrivateCompanyValuation), color: GREEN_TEXT_COLOR }, { label: 'Implied Current Share Price:', value: formatCurrency(valuationSummary.impliedCurrentSharePrice), color: GRAY_TEXT_COLOR } ]; pdf.setFontSize(10); pdf.setFont('helvetica', 'normal'); summaryItems.forEach(item => { if (y + 7 > pdf.internal.pageSize.height - 15) { pdf.addPage(); y = 15; } pdf.setTextColor(BLACK_COLOR[0], BLACK_COLOR[1], BLACK_COLOR[2]); pdf.text(item.label, 15, y); pdf.setTextColor(item.color[0], item.color[1], item.color[2]); pdf.text(item.value, 150, y, { align: 'right' }); y += 7; }); y += 8; // Extra space before next section // --- 3. IPO Pricing Simulation Section --- pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('3. IPO Pricing Simulation', 15, y); y += 8; const ipoPricing = window.valuationIPOResults.ipoPricing; const ipoItems = [ { label: 'Pre-Money Valuation (From Valuation Analysis):', value: formatCurrency(ipoPricing.ipoPreMoneyValuation), color: GRAY_TEXT_COLOR }, { label: 'Capital Raised in IPO:', value: formatCurrency(ipoPricing.ipoCapitalRaised), color: BLUE_TEXT_COLOR }, { label: 'Post-Money Valuation:', value: formatCurrency(ipoPricing.ipoPostMoneyValuation), color: GREEN_TEXT_COLOR }, { label: 'Shares Issued in IPO:', value: ipoPricing.ipoSharesIssued.toLocaleString(), color: BLUE_TEXT_COLOR }, { label: 'Total Shares Outstanding Post-IPO:', value: ipoPricing.ipoTotalSharesPost.toLocaleString(), color: GRAY_TEXT_COLOR }, { label: 'IPO Offer Price Per Share:', value: formatCurrency(ipoPricing.ipoOfferPricePerShare), color: GREEN_TEXT_COLOR }, { label: 'Existing Shareholder Dilution:', value: formatPercentage(ipoPricing.ipoDilution), color: RED_COLOR }, { label: 'Net Proceeds to Company from IPO:', value: formatCurrency(ipoPricing.ipoNetProceeds), color: BLUE_TEXT_COLOR } ]; pdf.setFontSize(10); pdf.setFont('helvetica', 'normal'); ipoItems.forEach(item => { if (y + 7 > pdf.internal.pageSize.height - 15) { pdf.addPage(); y = 15; } pdf.setTextColor(BLACK_COLOR[0], BLACK_COLOR[1], BLACK_COLOR[2]); pdf.text(item.label, 15, y); pdf.setTextColor(item.color[0], item.color[1], item.color[2]); pdf.text(item.value, 150, y, { align: 'right' }); y += 7; }); pdf.save('Private_Company_Valuation_IPO_Simulator_Results.pdf'); } /** * Initializes DOM element references once the document is fully loaded. */ document.addEventListener('DOMContentLoaded', () => { // Input Elements currentRevenueInput = document.getElementById('currentRevenue'); currentEbitdaInput = document.getElementById('currentEbitda'); currentNetIncomeInput = document.getElementById('currentNetIncome'); currentCashInput = document.getElementById('currentCash'); totalDebtInput = document.getElementById('totalDebt'); currentSharesOutstandingInput = document.getElementById('currentSharesOutstanding'); projectionYearsInput = document.getElementById('projectionYears'); revenueGrowthRateInput = document.getElementById('revenueGrowthRate'); ebitdaMarginProjectionInput = document.getElementById('ebitdaMarginProjection'); taxRateInput = document.getElementById('taxRate'); capexAsPctRevenueInput = document.getElementById('capexAsPctRevenue'); nwcAsPctRevenueInput = document.getElementById('nwcAsPctRevenue'); riskFreeRateInput = document.getElementById('riskFreeRate'); marketRiskPremiumInput = document.getElementById('marketRiskPremium'); betaInput = document.getElementById('beta'); costOfDebtInput = document.getElementById('costOfDebt'); equityPercentageWACCInput = document.getElementById('equityPercentageWACC'); terminalGrowthRateInput = document.getElementById('terminalGrowthRate'); comparableEbitdaMultipleInput = document.getElementById('comparableEbitdaMultiple'); comparablePEMultipleInput = document.getElementById('comparablePEMultiple'); privateCompanyDiscountInput = document.getElementById('privateCompanyDiscount'); dcfWeightInput = document.getElementById('dcfWeight'); capitalToRaiseInput = document.getElementById('capitalToRaise'); underwritingFeesInput = document.getElementById('underwritingFees'); percentCompanyToSellInput = document.getElementById('percentCompanyToSell'); // Output Elements (Valuation Analysis Tab) waccOutput = document.getElementById('waccOutput'); dcfEquityValueOutput = document.getElementById('dcfEquityValueOutput'); ebitdaMultipleValuationOutput = document.getElementById('ebitdaMultipleValuationOutput'); peMultipleValuationOutput = document.getElementById('peMultipleValuationOutput'); blendedPreDiscountValuationOutput = document.getElementById('blendedPreDiscountValuationOutput'); finalPrivateCompanyValuationOutput = document.getElementById('finalPrivateCompanyValuationOutput'); impliedCurrentSharePriceOutput = document.getElementById('impliedCurrentSharePriceOutput'); // Output Elements (IPO Pricing Tab) ipoPreMoneyValuationOutput = document.getElementById('ipoPreMoneyValuationOutput'); ipoCapitalRaisedOutput = document.getElementById('ipoCapitalRaisedOutput'); ipoPostMoneyValuationOutput = document.getElementById('ipoPostMoneyValuationOutput'); ipoSharesIssuedOutput = document.getElementById('ipoSharesIssuedOutput'); ipoTotalSharesPostOutput = document.getElementById('ipoTotalSharesPostOutput'); ipoOfferPricePerShareOutput = document.getElementById('ipoOfferPricePerShareOutput'); ipoDilutionOutput = document.getElementById('ipoDilutionOutput'); ipoNetProceedsOutput = document.getElementById('ipoNetProceedsOutput'); // Other Elements valuationProjectionsOutputDiv = document.getElementById('valuationProjectionsOutput'); messageBox = document.getElementById('messageBox'); // Initialize navigation button states updateNavigationButtons(); });
Scroll to Top