A deterministic DCF model produces one number: the valuation. Change any input assumption and you get a different number. Run a sensitivity table and you get a grid of numbers. But a grid is not a probability distribution, and a point estimate is not a risk assessment.
Monte Carlo simulation replaces each uncertain input — revenue growth, margin expansion, exit multiple, discount rate — with a probability distribution and samples from all of them simultaneously across 10,000 trials. The output is a distribution of valuations, not a point estimate.
Why It Matters
A deterministic model might say: "at a 10x exit multiple and 12% EBITDA margin, the valuation is $47M." A stochastic model says: "there is a 15% probability the valuation exceeds $60M, a 50% probability it exceeds $38M, and a 20% probability it falls below $22M." These are fundamentally different statements. The second is actionable for structuring debt tranches, setting earn-out thresholds, and underwriting downside scenarios.
Python Implementation Sketch
import numpy as np
def monte_carlo_valuation(n=10_000):
revenue_growth = np.random.normal(0.08, 0.04, n) # mean 8%, std 4%
ebitda_margin = np.random.normal(0.14, 0.03, n) # mean 14%, std 3%
exit_multiple = np.random.normal(9.5, 1.5, n) # mean 9.5x, std 1.5x
discount_rate = np.random.normal(0.12, 0.02, n) # mean 12%, std 2%
base_revenue = 10 # $10M
projected_ebitda = base_revenue * (1 + revenue_growth)**5 * ebitda_margin
terminal_value = projected_ebitda * exit_multiple
npv = terminal_value / (1 + discount_rate)**5
return npv
valuations = monte_carlo_valuation()
print(f"Median valuation: ${np.median(valuations):.1f}M")
print(f"5th percentile: ${np.percentile(valuations, 5):.1f}M")
print(f"95th percentile: ${np.percentile(valuations, 95):.1f}M")
Read the full article with complete model architecture and interpretation framework →
Top comments (0)