diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-19 00:03:32 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-19 00:03:32 -0700 |
| commit | cf3e3f5c65752b373a283141b21d38f7eb12c729 (patch) | |
| tree | d31d4379ab04a14f398d4019987b9431e73ee40a /frontend/lib/dcf.ts | |
| parent | c57b3782f61522d96b9ff21a4293ab2c938f427e (diff) | |
feat: add client-side computeDcf utility
Diffstat (limited to 'frontend/lib/dcf.ts')
| -rw-r--r-- | frontend/lib/dcf.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/frontend/lib/dcf.ts b/frontend/lib/dcf.ts new file mode 100644 index 0000000..04f1d6c --- /dev/null +++ b/frontend/lib/dcf.ts @@ -0,0 +1,52 @@ +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 }; +} |
