Session 13 of 26 Part V: DCF Valuation — Chapter 13 of 18
Part V: DCF Valuation Chapter 13 of 18 Session 13 Python

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

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.

The Terminal Value Trap: A 0.5% change in the perpetual growth rate can swing the terminal value by 10–15%. An analyst who wants a higher valuation can simply nudge the terminal growth rate up — and no one can prove them wrong, because the terminal value is inherently unobservable. This is why investment committees scrutinize terminal value assumptions more than any other part of a DCF. Your terminal growth rate must be defensible with economic logic, not just selected to hit a target price.

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:

Terminal Valuen = FCFFn+1 / (WACC − g)
= FCFFn × (1 + g) / (WACC − g)

Where:

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:

PrincipleExplanation
1. g cannot exceed the long-run nominal GDP growth rateNo 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 maturityA 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 reinvestmentIf 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 companiesThis 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.
🌎
Real World: Damodaran's research shows that analysts routinely overestimate terminal growth. A survey of sell-side DCF models found that the median terminal growth rate was 3.5%, yet the median actual long-run growth rate of the companies valued was below 2%. The gap — 1.5 percentage points — translates to a systematic overvaluation of 20–30% across the entire universe of DCF-based equity research. Do not be that analyst.

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}%")
Critical Constraint: If terminal growth (g) approaches or exceeds WACC, the denominator (WACC − g) approaches zero, and the terminal value explodes to infinity. This is not a feature — it is a mathematical artifact that signals your assumptions are wrong. For a company with WACC of 10%, a terminal growth rate above 9% should trigger immediate skepticism. The gap between WACC and g must be economically meaningful — at least 3–4 percentage points.

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.

Terminal Valuen = EBITDAn × Exit Multiple (EV/EBITDA)

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

13.3.2 Bridging Perpetuity Growth and Exit Multiples

There is a mathematical relationship between the two methods:

Implied EV/EBITDA = (1 + g) / (WACC − g) × (FCFF / EBITDA)

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:

Equity Value = Enterprise Value − Debt + Cash − Minority Interest − Preferred Stock + Other Non-Operating Assets

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 CheckHow to TestRed Flag If
1TV % of Total EVPV(TV) / (PV(Explicit) + PV(TV))TV > 85% of EV (unless very early-stage company)
2Implied ROIC at maturityg / Reinvestment Rate at terminal yearImplied ROIC far from industry norms or historical levels
3Implied exit multipleTV / EBITDAnExit EV/EBITDA > 20x for a mature industrial company or < 3x (fire-sale pricing)
4WACC − g spreadWACC − gSpread < 3% — terminal value is hyper-sensitive to small assumption changes
5Reinvestment consistencyYear 5 reinvestment rate vs steady-state reinvestment rate (g / ROIC)Year 5 reinvestment rate is 2× or more the steady-state rate without explanation
6Per-share value reasonablenessIV per share vs current market priceIV 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

Mistake 1: Double-counting growth. The terminal growth rate applies to FCFF, not revenue. If you forecast 12% revenue growth in Year 5 and set terminal growth to 8%, you are claiming the company will grow at near-GDP rates forever — which may be defensible, but only if the competitive advantage period is extremely long. For most companies, growth decelerates in the terminal period.
Mistake 2: Using the exit multiple as the primary method without checking the implied perpetuity growth. An exit multiple of 15x EBITDA might seem reasonable because "the sector trades at 15x." But at a 10% WACC, a 15x multiple on Year 5 FCFF implies a terminal growth rate of ~8% — which may be indefensible. Always compute the implied g and ask: can this company really grow at this rate forever?
Mistake 3: Not normalizing the terminal year. The terminal year FCFF and EBITDA must represent a steady-state — normal capex (not an investment spike), normal margins (not a cyclical peak), normal working capital. If Year 5 happens to be an investment-heavy year with depressed FCFF, your terminal value will be artificially low. If it is a capex-light year with inflated FCFF, your terminal value will be artificially high. Check that Year 5 is representative.
Mistake 4: Discounting the terminal value incorrectly. The terminal value computed by the perpetuity formula is as of Year n (the end of the forecast). It must be discounted back to today using the same discount rate and timing convention. A common error is to apply mid-year discounting to the terminal value — the terminal value already represents a single lump sum at Year n; it should be discounted using the year-end convention (exponent = n, not n − 0.5). Some practitioners use mid-year for the terminal value as well; the difference is small but worth being deliberate about.

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

  1. 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.
  2. 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.
  3. Derive enterprise value = PV(Explicit FCFF) + PV(Terminal Value). Run the 6 sanity checks from Section 13.5.
  4. Bridge to equity value: subtract net debt, minority interest, and add non-operating assets. Use the latest balance sheet data.
  5. Compute per-share intrinsic value using fully diluted shares outstanding (include ESOPs, convertibles).
  6. Compare to market price. Calculate the premium/discount. Does your DCF suggest the stock is undervalued, fairly valued, or overvalued?
  7. 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

1

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%.

2

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.

3

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.

4

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.

5

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?