summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-19 00:03:32 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-19 00:03:32 -0700
commitcf3e3f5c65752b373a283141b21d38f7eb12c729 (patch)
treed31d4379ab04a14f398d4019987b9431e73ee40a
parentc57b3782f61522d96b9ff21a4293ab2c938f427e (diff)
feat: add client-side computeDcf utility
-rw-r--r--frontend/lib/dcf.ts52
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 };
+}