export type DcfInputs = { baseFcf: number; /** enterprise_value - equity_value; holds net_debt + preferred + minority interest */ equityBridge: number; sharesOutstanding: number; }; export type DcfParams = { wacc: number; terminalGrowth: number; projectionYears: number; growthRate: number; }; export type DcfComputed = { intrinsicValuePerShare: number; enterpriseValue: number; equityValue: number; fcfPvSum: number; terminalValuePv: number; }; export function computeDcf( inputs: DcfInputs, params: DcfParams ): DcfComputed | { error: string } { const { baseFcf, equityBridge, sharesOutstanding } = inputs; const { wacc, terminalGrowth, projectionYears, growthRate } = params; if (wacc <= 0) return { error: "WACC must be greater than 0%." }; if (terminalGrowth >= wacc) return { error: "Terminal growth must be lower than WACC." }; if (baseFcf <= 0) return { error: "DCF not meaningful with zero or negative base FCF." }; const projected = Array.from( { length: projectionYears }, (_, i) => baseFcf * (1 + growthRate) ** (i + 1) ); const fcfPvSum = projected.reduce( (sum, fcf, i) => sum + fcf / (1 + wacc) ** (i + 1), 0 ); const terminalFcf = projected[projected.length - 1] * (1 + terminalGrowth); const terminalValue = terminalFcf / (wacc - terminalGrowth); const terminalValuePv = terminalValue / (1 + wacc) ** projectionYears; const enterpriseValue = fcfPvSum + terminalValuePv; const equityValue = enterpriseValue - equityBridge; const intrinsicValuePerShare = equityValue / sharesOutstanding; return { intrinsicValuePerShare, enterpriseValue, equityValue, fcfPvSum, terminalValuePv }; }