Terminal Value & Enterprise Value
Value the business beyond the forecast horizon — the terminal value that typically represents 60–80% of a DCF — and derive enterprise value, equity value, and the per-share intrinsic value.
Learning Objectives
- Compute terminal value using both the perpetuity growth method and the exit multiple method
- Choose defensible terminal growth rates and exit multiples grounded in economics
- Discount the terminal value to present value and combine it with the explicit forecast PV
- Derive enterprise value, equity value, and per-share intrinsic value from the DCF
- Apply sanity checks to ensure the terminal value is reasonable and not dominating the valuation
13.1 Why Terminal Value Matters So Much
In Chapter 12, we discounted 5 years of explicit FCFF forecasts. For most companies, those 5 years represent only 20–40% of the total enterprise value. The remaining 60–80% comes from the terminal value — the value of all cash flows beyond the explicit forecast period.
This is not a flaw in DCF methodology. It is a reflection of economic reality: companies are going concerns with indefinite lives. A 5-year forecast captures the near-term trajectory; the terminal value captures the long-run steady state. The fact that terminal value dominates the result is precisely why the assumptions that go into it — particularly the terminal growth rate — must be chosen with extreme care and defended rigorously.
13.2 The Perpetuity Growth Method (Gordon Growth Model)
The perpetuity growth method assumes the company grows at a constant rate forever after the explicit forecast period. It is theoretically the correct approach — companies are going concerns, and their cash flows do not stop after Year 5. The formula derives from the Gordon Growth Model:
= FCFFn × (1 + g) / (WACC − g)
Where:
- FCFFn = Free cash flow in the final year of the explicit forecast (Year 5 in our model)
- g = Perpetual growth rate — the rate at which FCFF grows forever
- WACC = Weighted average cost of capital
13.2.1 Choosing the Terminal Growth Rate (g)
The terminal growth rate is the most consequential single assumption in a DCF. These principles govern its selection:
| Principle | Explanation |
|---|---|
| 1. g cannot exceed the long-run nominal GDP growth rate | No company can grow faster than the economy forever. If it did, it would eventually become larger than the economy — a mathematical impossibility. For India, long-run nominal GDP growth is ~8–10% (real 6–7% + inflation 3–4%). So g for an Indian company cannot exceed ~8% and is typically much lower. |
| 2. g should reflect the company's competitive position at maturity | A company with a durable moat (Asian Paints, TCS) might sustain 3–5% terminal growth — slightly above long-run inflation. A commodity company with no moat might sustain 1–2% — essentially matching inflation. A company in structural decline might have zero or negative terminal growth. |
| 3. g must be consistent with the terminal year's reinvestment | If g = 4% and the terminal ROIC is 20%, the required reinvestment rate = g / ROIC = 4% / 20% = 20%. If your Year 5 reinvestment rate is 60%, the model is inconsistent — either g must be higher, ROIC lower, or the Year 5 reinvestment rate must decline toward the steady-state level. |
| 4. When in doubt, use 3–4% for Indian companies | This approximates long-run nominal GDP growth for a mature economy (India's long-run steady state). It is the most common choice among practitioners for quality Indian companies. |
13.2.2 Terminal Value in Python
import numpy as np
import pandas as pd
def terminal_value_perpetuity(fcff_terminal_year, wacc, terminal_growth):
"""
Compute terminal value using the perpetuity growth method.
Parameters
----------
fcff_terminal_year : float — FCFF in the final explicit forecast year (Year n)
wacc : float — weighted average cost of capital
terminal_growth : float — perpetual growth rate (g)
Returns
-------
dict with terminal value, PV of terminal value, and implied metrics.
"""
# FCFF in Year n+1 = FCFF_n × (1 + g)
fcff_next = fcff_terminal_year * (1 + terminal_growth)
# Terminal Value at Year n
tv = fcff_next / (wacc - terminal_growth)
# Present value of terminal value (discount back to today, mid-year convention)
# Assuming n=5 forecast years, discount from Year 5
n = 5
pv_tv = tv / (1 + wacc) ** n # Year-end convention for terminal value
# Implied perpetuity assumptions
implied_exit_multiple = tv / fcff_terminal_year
print(f"Terminal Value — Perpetuity Growth Method:")
print(f" FCFF (Year 5): Rs. {fcff_terminal_year:,.0f} Cr")
print(f" FCFF (Year 6): Rs. {fcff_next:,.0f} Cr")
print(f" Terminal Growth (g): {terminal_growth*100:.1f}%")
print(f" WACC: {wacc*100:.1f}%")
print(f" WACC − g: {(wacc - terminal_growth)*100:.1f}%")
print(f" Terminal Value (Y5): Rs. {tv:,.0f} Cr")
print(f" PV of Terminal Value: Rs. {pv_tv:,.0f} Cr")
print(f" Implied TV/FCFF mult: {implied_exit_multiple:.1f}x")
return {
'fcff_year_n': fcff_terminal_year,
'fcff_year_n1': fcff_next,
'terminal_growth': terminal_growth,
'terminal_value': tv,
'pv_terminal_value': pv_tv,
'implied_multiple': implied_exit_multiple,
'wacc': wacc
}
# --- Example ---
# Year 5 FCFF from Chapter 12
fcff_y5 = 7680 # Rs. Crore
wacc = 0.1064 # From Chapter 11
g = 0.035 # 3.5% perpetual growth
tv_result = terminal_value_perpetuity(fcff_y5, wacc, g)
# --- Sensitivity: TV at different growth rates ---
print(f"\n Terminal Value Sensitivity to g:")
for g_test in [0.02, 0.025, 0.03, 0.035, 0.04, 0.045]:
fcff_next = fcff_y5 * (1 + g_test)
tv = fcff_next / (wacc - g_test)
pv_tv = tv / (1 + wacc) ** 5
tv_pct = pv_tv / (pv_tv + 25000) * 100 # Approx total EV
print(f" g = {g_test*100:.1f}%: TV = Rs. {tv:,.0f} Cr, "
f"PV = Rs. {pv_tv:,.0f} Cr, TV% = {tv_pct:.0f}%")
13.3 The Exit Multiple Method
The exit multiple method values the company at the end of the forecast period by applying a valuation multiple (typically EV/EBITDA or EV/EBIT) to the final year's metric. It is the standard cross-check against the perpetuity growth method.
The exit multiple method is widely used in practice — particularly in investment banking and private equity — because it is concrete and comparable. "We value the company at 12x Year 5 EBITDA" is more intuitive to many practitioners than "We assume 3.5% perpetual growth."
13.3.1 Choosing the Exit Multiple
- Current peer multiples: Look at the EV/EBITDA of comparable companies today. Apply a discount to reflect that the company will be 5 years older (and likely growing more slowly) at exit.
- Historical averages: What has the sector's median EV/EBITDA been over the past 5–10 years? Sector multiples mean-revert.
- Implied multiple from perpetuity growth: The perpetuity growth rate IMPLIES an exit multiple. Always compare the two methods — if they produce wildly different terminal values, one of your assumptions is wrong.
13.3.2 Bridging Perpetuity Growth and Exit Multiples
There is a mathematical relationship between the two methods:
If the perpetuity growth method gives a TV of Rs. 1,20,000 Cr and Year 5 EBITDA is Rs. 14,000 Cr, the implied EV/EBITDA is 8.6x. If comparable companies today trade at 15x, your implied exit multiple suggests significant multiple compression — which may be entirely appropriate for a maturing company.
def terminal_value_exit_multiple(ebitda_terminal_year, exit_multiple,
fcff_terminal_year=None, wacc=None):
"""
Compute terminal value using the exit multiple method.
Also computes the implied perpetual growth rate if FCFF and WACC are provided.
"""
tv = ebitda_terminal_year * exit_multiple
print(f"Terminal Value — Exit Multiple Method:")
print(f" Year 5 EBITDA: Rs. {ebitda_terminal_year:,.0f} Cr")
print(f" Exit EV/EBITDA: {exit_multiple:.1f}x")
print(f" Terminal Value (Y5): Rs. {tv:,.0f} Cr")
result = {
'ebitda_y5': ebitda_terminal_year,
'exit_multiple': exit_multiple,
'terminal_value': tv,
'pv_terminal_value': tv / (1 + wacc) ** 5 if wacc else None
}
# Implied perpetual growth rate
if fcff_terminal_year is not None and wacc is not None:
# TV = FCFF × (1+g) / (WACC − g)
# Solve: g = (TV × WACC − FCFF) / (TV + FCFF)
implied_g = (tv * wacc - fcff_terminal_year) / (tv + fcff_terminal_year)
result['implied_g'] = implied_g
print(f" Implied Perpetual g: {implied_g*100:.2f}%")
if implied_g > 0.06:
print(f" ⚠ WARNING: Implied g ({implied_g*100:.1f}%) seems high — "
f"verify exit multiple is reasonable")
elif implied_g < 0.01:
print(f" ⚠ WARNING: Implied g ({implied_g*100:.1f}%) is very low — "
f"exit multiple may be too conservative")
return result
# --- Example: Exit Multiple Method ---
ebitda_y5 = 14400 # Year 5 EBITDA (Rs. Cr)
exit_ev_ebitda = 12.0 # 12x EV/EBITDA — at a discount to current sector multiples
tv_exit = terminal_value_exit_multiple(ebitda_y5, exit_ev_ebitda,
fcff_y5, wacc)
# --- Compare Both Methods ---
print(f"\n=== METHOD COMPARISON ===")
print(f" Perpetuity Growth (g={g*100:.1f}%):")
print(f" TV = Rs. {tv_result['terminal_value']:,.0f} Cr")
print(f" Implied EV/EBITDA = {tv_result['terminal_value']/ebitda_y5:.1f}x")
print(f"\n Exit Multiple ({exit_ev_ebitda:.0f}x EV/EBITDA):")
print(f" TV = Rs. {tv_exit['terminal_value']:,.0f} Cr")
print(f" Implied g = {tv_exit['implied_g']*100:.2f}%")
difference_pct = (tv_exit['terminal_value'] - tv_result['terminal_value']) / tv_result['terminal_value'] * 100
print(f"\n Difference: {difference_pct:+.1f}%")
print(f" {'Methods are broadly consistent' if abs(difference_pct) < 20 else 'Large divergence — investigate assumptions'}")
13.4 From Enterprise Value to Equity Value
Enterprise value is the total value of the firm's operations. To arrive at equity value — the value belonging to common shareholders — we must adjust for all other claims on the firm:
This is the same EV-to-Equity bridge we introduced in Chapter 1. Now we apply it with real numbers from our DCF.
def derive_equity_value(enterprise_value, net_debt, minority_interest=0,
preferred_stock=0, non_op_assets=0,
shares_outstanding=None):
"""
Bridge from Enterprise Value to Equity Value and per-share value.
Parameters
----------
enterprise_value : float — from DCF (PV of explicit + PV of terminal)
net_debt : float — Total Debt − Cash
minority_interest : float — non-controlling interest on balance sheet
preferred_stock : float — preference share capital
non_op_assets : float — non-operating assets (investments, surplus land)
shares_outstanding : float — diluted shares in crores
Returns
-------
dict with EV, equity value, and per-share intrinsic value.
"""
equity_value = (enterprise_value
- net_debt
- minority_interest
- preferred_stock
+ non_op_assets)
result = {
'enterprise_value': enterprise_value,
'less_net_debt': -net_debt,
'less_minority_interest': -minority_interest,
'less_preferred_stock': -preferred_stock,
'plus_non_op_assets': non_op_assets,
'equity_value': equity_value,
}
print(f"Enterprise Value → Equity Value Bridge:")
print(f" Enterprise Value: Rs. {enterprise_value:,.0f} Cr")
print(f" (−) Net Debt: Rs. {net_debt:,.0f} Cr")
if minority_interest:
print(f" (−) Minority Interest: Rs. {minority_interest:,.0f} Cr")
if preferred_stock:
print(f" (−) Preferred Stock: Rs. {preferred_stock:,.0f} Cr")
if non_op_assets:
print(f" (+) Non-Op Assets: Rs. {non_op_assets:,.0f} Cr")
print(f" ═══════════════════════════════")
print(f" EQUITY VALUE: Rs. {equity_value:,.0f} Cr")
if shares_outstanding:
per_share = equity_value / shares_outstanding
result['per_share_value'] = per_share
print(f"\n Shares Outstanding: {shares_outstanding:.0f} Cr")
print(f" INTRINSIC VALUE/SHARE: Rs. {per_share:,.0f}")
return result
# --- Example: Derive Equity Value ---
pv_explicit = 23750 # PV of 5-year FCFF (from Ch12, Rs. Cr)
pv_terminal = 72500 # PV of Terminal Value (Rs. Cr)
enterprise_value = pv_explicit + pv_terminal
net_debt = 2700 # Rs. Cr (Debt 4800 − Cash 2100)
shares = 92.5 # Crore shares (diluted)
equity_result = derive_equity_value(
enterprise_value, net_debt,
minority_interest=150,
shares_outstanding=shares
)
# Compare to market price
market_price = 3240 # Current market price (Rs.)
if 'per_share_value' in equity_result:
iv = equity_result['per_share_value']
premium = (iv / market_price - 1) * 100
print(f"\n Market Price: Rs. {market_price:,.0f}")
print(f" Premium/(Discount): {premium:+.1f}%")
if iv > market_price:
print(f" → Stock appears UNDERVALUED by {premium:.0f}%")
else:
print(f" → Stock appears OVERVALUED by {abs(premium):.0f}%")
13.5 Sanity Checks: Is Your Terminal Value Reasonable?
Before presenting your DCF result, apply these sanity checks. If your model fails any of them, investigate the assumptions — do not ignore the warning signs.
| # | Sanity Check | How to Test | Red Flag If |
|---|---|---|---|
| 1 | TV % of Total EV | PV(TV) / (PV(Explicit) + PV(TV)) | TV > 85% of EV (unless very early-stage company) |
| 2 | Implied ROIC at maturity | g / Reinvestment Rate at terminal year | Implied ROIC far from industry norms or historical levels |
| 3 | Implied exit multiple | TV / EBITDAn | Exit EV/EBITDA > 20x for a mature industrial company or < 3x (fire-sale pricing) |
| 4 | WACC − g spread | WACC − g | Spread < 3% — terminal value is hyper-sensitive to small assumption changes |
| 5 | Reinvestment consistency | Year 5 reinvestment rate vs steady-state reinvestment rate (g / ROIC) | Year 5 reinvestment rate is 2× or more the steady-state rate without explanation |
| 6 | Per-share value reasonableness | IV per share vs current market price | IV differs from market price by >100% (possible, but demands rock-solid assumptions) |
def dcf_sanity_checks(pv_explicit, pv_terminal, terminal_value,
ebitda_y5, fcff_y5, wacc, terminal_g, roic_terminal=None):
"""Run all DCF sanity checks and flag any concerns."""
enterprise_value = pv_explicit + pv_terminal
checks = []
# 1. TV % of EV
tv_pct = pv_terminal / enterprise_value * 100
status = 'WARN' if tv_pct > 85 else ('OK' if tv_pct < 70 else 'MONITOR')
checks.append((f'TV % of EV', f'{tv_pct:.0f}%', status,
'> 85% is concerning' if tv_pct > 85 else 'Reasonable'))
# 2. Implied exit multiple
implied_ebitda_mult = terminal_value / ebitda_y5
status = 'WARN' if implied_ebitda_mult > 20 else ('WARN' if implied_ebitda_mult < 3 else 'OK')
checks.append(('Implied EV/EBITDA', f'{implied_ebitda_mult:.1f}x', status,
f'Check against sector norms'))
# 3. WACC − g spread
spread = (wacc - terminal_g) * 100
status = 'WARN' if spread < 3 else 'OK'
checks.append(('WACC − g Spread', f'{spread:.1f}%', status,
'< 3% is dangerously narrow' if spread < 3 else 'Adequate cushion'))
# 4. Implied ROIC check
if roic_terminal:
implied_reinv = terminal_g / roic_terminal
checks.append(('Steady-State Reinv Rate', f'{implied_reinv*100:.1f}%',
'OK', f'Required to sustain {terminal_g*100:.1f}% growth at {roic_terminal*100:.0f}% ROIC'))
# 5. Explicit vs Terminal contribution
checks.append(('Explicit PV', f'{pv_explicit/enterprise_value*100:.0f}% of EV',
'OK' if pv_explicit/enterprise_value > 0.15 else 'MONITOR',
'Explicit period should contribute ≥ 15%'))
# Display
print(f"{'='*60}")
print(f" DCF SANITY CHECKS")
print(f"{'='*60}")
all_ok = True
for name, value, status, note in checks:
symbol = '✓' if status == 'OK' else ('⚠' if status == 'MONITOR' else '✗')
print(f" {symbol} {name:<25s}: {value:<12s} [{status}] {note}")
if status == 'WARN':
all_ok = False
if all_ok:
print(f"\n ✓ All checks passed — DCF is internally consistent.")
else:
print(f"\n ⚠ Some checks flagged warnings — review assumptions before finalizing.")
return all_ok
# --- Run sanity checks ---
dcf_sanity_checks(
pv_explicit=23750,
pv_terminal=72500,
terminal_value=tv_result['terminal_value'],
ebitda_y5=14400,
fcff_y5=7680,
wacc=0.1064,
terminal_g=0.035,
roic_terminal=0.22
)
13.6 The Complete Enterprise Value Pipeline
Now we assemble the complete DCF value derivation — explicit period PV + terminal value PV = enterprise value → equity value → per-share intrinsic value:
def complete_dcf_valuation(fcff_forecast, ebitda_forecast, wacc,
terminal_g=0.035, exit_multiple=None,
net_debt=0, minority_interest=0,
preferred_stock=0, non_op_assets=0,
shares_outstanding=None,
market_price=None):
"""
Complete DCF valuation: from FCFF to per-share intrinsic value.
Parameters
----------
fcff_forecast : list — FCFF for years 1 through n
ebitda_forecast : list — EBITDA for years 1 through n
wacc : float
terminal_g : float — perpetual growth rate
exit_multiple : float — if provided, also compute exit multiple TV as cross-check
net_debt, minority_interest, preferred_stock, non_op_assets : float
shares_outstanding : float — diluted shares in crores
market_price : float — current stock price for comparison
Returns
-------
dict with complete DCF breakdown.
"""
n = len(fcff_forecast)
fcff_n = fcff_forecast[-1]
ebitda_n = ebitda_forecast[-1]
# --- 1. PV of Explicit Forecast ---
pv_explicit = sum(fcff / (1 + wacc) ** (t + 1 - 0.5)
for t, fcff in enumerate(fcff_forecast))
# --- 2. Terminal Value (Perpetuity Growth) ---
tv_perpetuity = terminal_value_perpetuity(fcff_n, wacc, terminal_g)
pv_terminal = tv_perpetuity['pv_terminal_value']
# --- 3. Enterprise Value ---
enterprise_value = pv_explicit + pv_terminal
# --- 4. Cross-Check with Exit Multiple ---
tv_exit = None
if exit_multiple:
tv_exit = terminal_value_exit_multiple(ebitda_n, exit_multiple,
fcff_n, wacc)
pv_tv_exit = tv_exit['pv_terminal_value']
ev_exit = pv_explicit + pv_tv_exit
print(f"\n Exit Multiple EV: Rs. {ev_exit:,.0f} Cr "
f"({(ev_exit/enterprise_value - 1)*100:+.1f}% vs perpetuity)")
# --- 5. Equity Value Bridge ---
equity = derive_equity_value(enterprise_value, net_debt,
minority_interest, preferred_stock,
non_op_assets, shares_outstanding)
# --- 6. Final Summary ---
print(f"\n{'='*60}")
print(f" DCF VALUATION SUMMARY")
print(f"{'='*60}")
print(f" PV of Explicit FCFF: Rs. {pv_explicit:,.0f} Cr "
f"({pv_explicit/enterprise_value*100:.0f}%)")
print(f" PV of Terminal Value: Rs. {pv_terminal:,.0f} Cr "
f"({pv_terminal/enterprise_value*100:.0f}%)")
print(f" ═══════════════════════════════")
print(f" ENTERPRISE VALUE: Rs. {enterprise_value:,.0f} Cr")
print(f" (−) Net Debt: Rs. {net_debt:,.0f} Cr")
print(f" ═══════════════════════════════")
print(f" EQUITY VALUE: Rs. {equity['equity_value']:,.0f} Cr")
if shares_outstanding:
iv_per_share = equity['per_share_value']
print(f"\n INTRINSIC VALUE/SHARE: Rs. {iv_per_share:,.0f}")
if market_price:
upside = (iv_per_share / market_price - 1) * 100
recommendation = 'BUY' if upside > 15 else ('HOLD' if upside > -10 else 'SELL')
print(f" Market Price: Rs. {market_price:,.0f}")
print(f" Upside/(Downside): {upside:+.1f}%")
print(f" RECOMMENDATION: {recommendation}")
return {
'pv_explicit': pv_explicit,
'pv_terminal': pv_terminal,
'enterprise_value': enterprise_value,
'equity_value': equity['equity_value'],
'per_share_value': equity.get('per_share_value'),
'tv_perpetuity': tv_perpetuity,
'tv_exit': tv_exit,
}
# --- Run Complete DCF ---
fcff_forecast = [5100, 5750, 6380, 7010, 7680]
ebitda_forecast = [9600, 10800, 12060, 13380, 14400]
dcf_result = complete_dcf_valuation(
fcff_forecast=fcff_forecast,
ebitda_forecast=ebitda_forecast,
wacc=0.1064,
terminal_g=0.035,
exit_multiple=12.0, # Cross-check
net_debt=2700,
minority_interest=150,
shares_outstanding=92.5,
market_price=3240
)
13.7 Common Terminal Value Mistakes
Hands-On Project: Terminal Value and Equity Value for Your Capstone Company
Compute the terminal value using both methods, derive enterprise value and equity value, and produce a per-share intrinsic value for your capstone company. Compare it to the current market price and formulate a preliminary investment recommendation.
Steps
- Compute terminal value using the perpetuity growth method. Justify your choice of g with reference to India's long-run nominal GDP growth, the company's competitive position, and the implied reinvestment rate.
- Compute terminal value using the exit multiple method as a cross-check. Use an exit multiple 10–20% below the current sector median to reflect maturation.
- Derive enterprise value = PV(Explicit FCFF) + PV(Terminal Value). Run the 6 sanity checks from Section 13.5.
- Bridge to equity value: subtract net debt, minority interest, and add non-operating assets. Use the latest balance sheet data.
- Compute per-share intrinsic value using fully diluted shares outstanding (include ESOPs, convertibles).
- Compare to market price. Calculate the premium/discount. Does your DCF suggest the stock is undervalued, fairly valued, or overvalued?
- Build a terminal value sensitivity grid: Per-share value for g from 2% to 5% and WACC from 9% to 13%. This is the single most important exhibit for your investment committee presentation.
View Solution / Walkthrough
Complete Terminal Value & Equity Value Analysis
# ================================================================
# TERMINAL VALUE & EQUITY VALUE — Complete Analysis
# ================================================================
# Inputs from previous chapters
fcff_forecast = [5100, 5750, 6380, 7010, 7680]
ebitda_forecast = [9600, 10800, 12060, 13380, 14400]
wacc = 0.1064
terminal_g_base = 0.035
shares = 92.5
market_price = 3240
net_debt = 2700
minority = 150
# --- Run Complete DCF ---
dcf = complete_dcf_valuation(
fcff_forecast, ebitda_forecast, wacc,
terminal_g=terminal_g_base,
exit_multiple=12.0,
net_debt=net_debt,
minority_interest=minority,
shares_outstanding=shares,
market_price=market_price
)
# --- Sanity Checks ---
dcf_sanity_checks(
dcf['pv_explicit'], dcf['pv_terminal'],
dcf['tv_perpetuity']['terminal_value'],
ebitda_forecast[-1], fcff_forecast[-1],
wacc, terminal_g_base, roic_terminal=0.22
)
# --- TERMINAL VALUE SENSITIVITY GRID ---
print(f"\n{'='*60}")
print(f" PER-SHARE VALUE SENSITIVITY")
print(f"{'='*60}")
g_range = np.arange(0.02, 0.055, 0.005)
wacc_range = np.arange(0.09, 0.135, 0.005)
sensitivity_grid = np.zeros((len(g_range), len(wacc_range)))
for i, g in enumerate(g_range):
for j, w in enumerate(wacc_range):
# Recompute PV of explicit
pv_exp = sum(fcff / (1 + w) ** (t + 0.5)
for t, fcff in enumerate(fcff_forecast))
# Terminal value
tv = fcff_forecast[-1] * (1 + g) / (w - g)
pv_tv = tv / (1 + w) ** 5
ev = pv_exp + pv_tv
eq = ev - net_debt - minority
sensitivity_grid[i, j] = eq / shares
# Display grid
print(f"\n{'g \\ WACC':<10}", end="")
for w in wacc_range:
print(f"{w*100:.1f}%".rjust(10), end="")
print()
for i, g in enumerate(g_range):
print(f"{g*100:.1f}%".ljust(10), end="")
for j, w in enumerate(wacc_range):
val = sensitivity_grid[i, j]
marker = ' ***' if abs(g - terminal_g_base) < 0.001 and abs(w - wacc) < 0.001 else ''
print(f"{val:,.0f}{marker}".rjust(10), end="")
print()
# Highlight base case
print(f"\n *** = Base Case (g={terminal_g_base*100:.1f}%, WACC={wacc*100:.1f}%)")
# Find cells where stock is undervalued vs market price
undervalued_cells = (sensitivity_grid > market_price).sum()
total_cells = sensitivity_grid.size
print(f"\n Stock is undervalued in {undervalued_cells}/{total_cells} "
f"({undervalued_cells/total_cells*100:.0f}%) of sensitivity scenarios")
# --- Investment Recommendation ---
iv_base = dcf['per_share_value']
upside = (iv_base / market_price - 1) * 100
print(f"\n{'='*60}")
print(f" PRELIMINARY INVESTMENT RECOMMENDATION")
print(f"{'='*60}")
print(f"""
Intrinsic Value: Rs. {iv_base:,.0f}
Market Price: Rs. {market_price:,.0f}
Upside: {upside:+.1f}%
Recommendation: {'BUY' if upside > 15 else ('HOLD' if upside > -10 else 'SELL')}
KEY ASSUMPTIONS TO DEFEND:
1. Terminal growth rate of {terminal_g_base*100:.1f}% (long-run nominal GDP proxy)
2. WACC of {wacc*100:.1f}% (from Chapter 11)
3. Year 5 FCFF of Rs. {fcff_forecast[-1]:,.0f} Cr must be sustainable
4. Net debt of Rs. {net_debt:,.0f} Cr from latest balance sheet
The stock appears {'undervalued' if upside > 0 else 'overvalued'} by {abs(upside):.0f}%.
This view is supported in {undervalued_cells}/{total_cells} sensitivity scenarios.
The primary risk to this valuation is [insert your company-specific risk].
""")
Key Takeaways
Terminal value dominates the DCF. It typically represents 60–80% of enterprise value. The terminal growth rate (g) is the single most consequential assumption — a 0.5% change can swing value by 10–15%.
Use BOTH perpetuity growth and exit multiple methods. Compute the implied g from your exit multiple and the implied multiple from your g. If they are inconsistent, one of your assumptions is wrong.
g must be less than the long-run nominal GDP growth rate. For India, this caps g at ~8%, and most mature companies should use 2–4%. A g above 5% demands exceptional justification.
The EV-to-Equity bridge transforms enterprise value into shareholder value. Subtract net debt, minority interest, and preferred stock. Add non-operating assets. Divide by diluted shares for the per-share intrinsic value.
Run the 6 sanity checks before presenting your DCF. TV% of EV, implied exit multiple, WACC−g spread, reinvestment consistency, and reasonableness of per-share value. A DCF that fails sanity checks is not defensible.
Test Your Understanding
1. Year 5 FCFF is Rs. 1,000 Cr, WACC is 10%, and the terminal growth rate is 3.5%. What is the terminal value using the perpetuity growth method?
2. Why must the terminal growth rate (g) not exceed the long-run nominal GDP growth rate?
3. The perpetuity growth method gives a terminal value of Rs. 50,000 Cr and the exit multiple method gives Rs. 65,000 Cr. What should you do?
4. Enterprise Value is Rs. 1,00,000 Cr. Net Debt is Rs. 5,000 Cr. Minority Interest is Rs. 2,000 Cr. There are 200 Cr shares outstanding. What is the per-share intrinsic value?
5. Your DCF shows the terminal value represents 92% of total enterprise value. What is the most appropriate response?