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

Time Value of Money & Free Cash Flow

Master the mathematics of discounting, compute FCFF and FCFE from your integrated model, and understand why a rupee today is worth more than a rupee tomorrow.

Learning Objectives

12.1 The Time Value of Money: The First Principle of Finance

The time value of money (TVM) is the foundation on which all of DCF valuation rests. The principle is simple: a rupee received today is worth more than a rupee received tomorrow, because today's rupee can be invested and earn a return. TVM provides the mathematics that converts future cash flows — which we spent Chapters 7–9 forecasting — into a single present value.

12.1.1 Present Value and Future Value

FV = PV × (1 + r)n
PV = FV / (1 + r)n

Where r is the discount rate (our WACC from Chapter 11) and n is the number of periods. The discount factor 1/(1+r)n converts a future cash flow into today's rupees. As n increases, the discount factor shrinks — distant cash flows contribute less to present value.

Year (n)Discount Factor (r=10%)PV of Rs. 100 received in year n
10.909Rs. 90.91
30.751Rs. 75.13
50.621Rs. 62.09
100.386Rs. 38.55
200.149Rs. 14.86

A rupee received 20 years from now is worth only 15 paise today at a 10% discount rate. This is why the terminal value (Chapter 13) — which captures cash flows beyond the explicit forecast — matters so much, and why the perpetual growth rate assumption in the terminal value formula has such enormous leverage on the final valuation.

12.1.2 Net Present Value (NPV)

The NPV is the sum of the present values of all future cash flows, minus the initial investment. In a DCF valuation, the enterprise value is the NPV of all future FCFFs.

NPV = ∑ CFt / (1 + r)t − Initial Investment
import numpy as np
import numpy_financial as npf

def compute_npv(cash_flows, discount_rate):
    """
    Compute NPV of a series of cash flows.

    Parameters
    ----------
    cash_flows : list or array — CF[0] is Year 0 (investment, usually negative),
                  CF[1] is Year 1, CF[2] is Year 2, etc.
    discount_rate : float — annual discount rate (WACC)

    Returns
    -------
    float — Net Present Value
    """
    # Manual computation (for transparency)
    npv = 0
    for t, cf in enumerate(cash_flows):
        npv += cf / (1 + discount_rate) ** t
    return npv

# Example: Investment of Rs. 1000, returns of Rs. 200/year for 7 years
cf = [-1000, 200, 200, 200, 200, 200, 200, 200]
npv_10 = compute_npv(cf, 0.10)
print(f"NPV at 10%: Rs. {npv_10:.2f}")
print(f"NPV at 8%:  Rs. {compute_npv(cf, 0.08):.2f}")
print(f"NPV at 12%: Rs. {compute_npv(cf, 0.12):.2f}")

# When NPV > 0, the investment creates value.
# When NPV < 0, it destroys value.

12.1.3 Internal Rate of Return (IRR)

The IRR is the discount rate that makes the NPV equal to zero. It represents the compounded annual return of the investment. If IRR > WACC, the investment creates value.

def compute_irr(cash_flows, guess=0.10, tolerance=1e-8, max_iter=1000):
    """
    Compute IRR using Newton-Raphson iteration.

    IRR is the rate r such that Σ CF_t / (1+r)^t = 0.
    """
    def npv_at_rate(r):
        return sum(cf / (1 + r) ** t for t, cf in enumerate(cash_flows))

    def npv_derivative(r):
        return sum(-t * cf / (1 + r) ** (t + 1) for t, cf in enumerate(cash_flows))

    r = guess
    for _ in range(max_iter):
        npv_val = npv_at_rate(r)
        if abs(npv_val) < tolerance:
            return r
        deriv = npv_derivative(r)
        if abs(deriv) < 1e-12:
            break
        r = r - npv_val / deriv
        if r <= -1:  # IRR cannot be below -100%
            return None

    return r

irr = compute_irr(cf)
print(f"\nIRR: {irr*100:.2f}%")
print(f"WACC = 10%: {'ACCEPT (IRR > WACC)' if irr > 0.10 else 'REJECT'}")
📝
Note: In DCF valuation, we do not compute IRR for the company as a whole — we compute NPV (the enterprise value). IRR is used for project evaluation and for calculating the implied return of an investment at a given purchase price. The numpy_financial library provides npf.npv() and npf.irr() as optimized implementations.

12.2 Free Cash Flow to Firm (FCFF): The Engine of Enterprise Valuation

FCFF is the cash available to all providers of capital — both debt and equity holders — after the company has made all the investments necessary to sustain and grow the business. It is the numerator in an enterprise-level DCF, discounted at WACC.

12.2.1 The FCFF Formula — Two Equivalent Approaches

Approach 1: From EBIT (preferred)

FCFF = EBIT × (1 − T) + D&A − Capex − Δ Working Capital

Start from operating profit, add back non-cash charges, subtract reinvestment. This is the most common approach and the one our integrated model uses.

Approach 2: From CFO

FCFF = CFO + Interest × (1 − T) − Capex

Start from operating cash flow, add back after-tax interest (since FCFF is pre-interest), subtract capex. Useful as a cross-check.

12.2.2 FCFF from the Integrated Model

def compute_fcff(ebit, tax_rate, depreciation, capex, delta_wc):
    """
    Compute Free Cash Flow to Firm.

    Parameters
    ----------
    ebit : float or array — Earnings Before Interest and Taxes
    tax_rate : float — effective tax rate
    depreciation : float or array — depreciation & amortization
    capex : float or array — capital expenditure (positive value)
    delta_wc : float or array — change in working capital
              (positive = increase = cash outflow)

    Returns
    -------
    float or array — FCFF
    """
    nopat = ebit * (1 - tax_rate)
    fcff = nopat + depreciation - capex - delta_wc
    return fcff


# --- Example using Chapter 9 integrated model output ---
# Simulate a 5-year forecast (would come from IntegratedFinancialModel)
import pandas as pd

forecast_data = {
    'Year':       [1,     2,     3,     4,     5],
    'Revenue':    [40500, 45800, 51300, 56900, 62600],
    'EBIT':       [8100,  9160, 10260, 11380, 12520],
    'Depreciation': [1215, 1374, 1539, 1707, 1878],
    'Capex':      [2228, 2519, 2822, 3130, 3443],
    'Delta_WC':   [450,   410,   380,   350,   310],
}

df = pd.DataFrame(forecast_data).set_index('Year')

tax_rate = 0.25
df['NOPAT'] = df['EBIT'] * (1 - tax_rate)
df['FCFF'] = compute_fcff(
    df['EBIT'], tax_rate, df['Depreciation'], df['Capex'], df['Delta_WC']
)

print("=== FCFF COMPUTATION (Rs. Crore) ===")
print(df.round(0))

print(f"\nFCFF as % of Revenue:")
for yr in df.index:
    print(f"  Year {yr}: {df.loc[yr, 'FCFF']/df.loc[yr, 'Revenue']*100:.1f}%")

total_fcff = df['FCFF'].sum()
print(f"\nTotal 5-Year FCFF: Rs. {total_fcff:.0f} Cr")

12.2.3 The Reinvestment Rate: Linking Growth to Cash Flow

The reinvestment rate is the proportion of NOPAT that must be reinvested to achieve a given growth rate. It is a crucial consistency check:

Reinvestment Rate = (Capex − Depreciation + Δ WC) / NOPAT
Expected Growth = Reinvestment Rate × ROIC
df['Reinvestment'] = df['Capex'] - df['Depreciation'] + df['Delta_WC']
df['Reinvestment_Rate'] = (df['Reinvestment'] / df['NOPAT']) * 100
df['Implied_Growth'] = df['Reinvestment_Rate'] / 100 * 0.30  # Assume ROIC = 30%

print("\n=== REINVESTMENT ANALYSIS ===")
print(f"{'Year':<6} {'Reinv Rate':<13} {'Implied Growth':<16}")
for yr in df.index:
    rr = df.loc[yr, 'Reinvestment_Rate']
    ig = df.loc[yr, 'Implied_Growth']
    print(f"  {yr:<4} {rr:.1f}%{'':<8} {ig*100:.1f}%")

# If implied growth from reinvestment rate ≠ your forecast growth,
# either ROIC must adjust or your capex/WC assumptions are inconsistent.
Consistency Check: A forecast with 18% revenue growth, 6% reinvestment rate, and 30% ROIC is mathematically impossible. The implied growth from reinvestment (6% × 30% = 1.8%) is far below the forecast. Either capex/working capital must increase (raising the reinvestment rate), or ROIC must be higher, or the growth forecast must come down. The reinvestment equation is the ultimate bullshit-detector in financial models.

12.3 Free Cash Flow to Equity (FCFE): The Equity Investor's Perspective

FCFE is the cash available to equity holders after all debt obligations have been met. It is the cash that can potentially be paid out as dividends or used for share buybacks. FCFE is discounted at the cost of equity (Ke) to derive equity value directly — an alternative to the FCFF → Enterprise Value → Equity Value route.

FCFE = FCFF − Interest × (1 − T) + Net Borrowing
FCFE = Net Income + D&A − Capex − Δ WC + Net Borrowing

Where Net Borrowing = New debt issued − Debt repaid. If the company increases its debt, more cash is available to equity holders. If it pays down debt, less is available.

def compute_fcfe(net_income, depreciation, capex, delta_wc, net_borrowing):
    """
    Compute Free Cash Flow to Equity from net income.

    Parameters
    ----------
    net_income : float or array
    depreciation : float or array
    capex : float or array
    delta_wc : float or array — change in working capital
    net_borrowing : float or array — new debt issued minus debt repaid

    Returns
    -------
    float or array — FCFE
    """
    return net_income + depreciation - capex - delta_wc + net_borrowing


def fcff_to_fcfe(fcff, interest_expense, tax_rate, net_borrowing):
    """Convert FCFF to FCFE."""
    return fcff - interest_expense * (1 - tax_rate) + net_borrowing


# --- Example: Derive FCFE from FCFF ---
interest = np.array([160, 150, 140, 130, 120])
net_borrowing = np.array([0, 0, 0, 0, 0])  # No change in debt

df['Interest'] = interest
df['Net_Borrowing'] = net_borrowing
df['FCFE'] = fcff_to_fcfe(df['FCFF'], df['Interest'], tax_rate, df['Net_Borrowing'])

print("\n=== FCFF vs FCFE (Rs. Crore) ===")
print(f"{'Year':<6} {'FCFF':<10} {'Interest(1-T)':<15} {'FCFE':<10}")
for yr in df.index:
    fcff = df.loc[yr, 'FCFF']
    int_after_tax = df.loc[yr, 'Interest'] * (1 - tax_rate)
    fcfe = df.loc[yr, 'FCFE']
    print(f"  {yr:<4} {fcff:<10.0f} {int_after_tax:<15.0f} {fcfe:<10.0f}")

print(f"\nNote: FCFE < FCFF because after-tax interest is subtracted.")
print(f"Total 5-Year FCFE: Rs. {df['FCFE'].sum():.0f} Cr")

12.3.1 FCFF vs FCFE: When to Use Which

CriterionUse FCFF (Enterprise DCF)Use FCFE (Equity DCF)
Capital structureStable or predictable D/E ratioVolatile D/E — net borrowing is erratic
LeverageLow to moderateHigh leverage — FCFE can be very volatile or negative
Financial firmsNot appropriate (debt is operating, not financing)Use Equity DCF or Dividend Discount Model
Ease of computationFewer components — no need to forecast net borrowingRequires explicit debt schedule and net borrowing forecast
OutputEnterprise Value → subtract net debt → Equity ValueEquity Value directly
Standard in practiceMost common for corporate valuationUsed for financial institutions, highly leveraged companies
💡
Pro Tip: For 90% of non-financial corporate valuations, use the FCFF approach. It is simpler (fewer components to forecast), more robust (less sensitive to capital structure assumptions), and directly produces enterprise value. The FCFE approach is best reserved for financial institutions (banks, NBFCs) where debt is an operating item, not a financing choice. This course focuses on the FCFF approach for the capstone DCF.

12.4 Discounting Mechanics: Converting FCFF to Present Value

With FCFF computed and WACC estimated, the remaining task is to discount each year's FCFF back to today. The discounting mechanics must be correct — a small error in the timing convention compounds across all years.

12.4.1 Year-End vs Mid-Year Discounting

The standard DCF formula assumes cash flows arrive at the end of each year. But in reality, cash flows are generated throughout the year. The mid-year convention assumes cash flows arrive in the middle of each year, which increases their present value (they are received earlier).

Year-End: PV = FCFFt / (1 + WACC)t
Mid-Year: PV = FCFFt / (1 + WACC)(t − 0.5)
def discount_fcff(fcff_array, wacc, mid_year=True):
    """
    Discount a series of FCFFs to present value.

    Parameters
    ----------
    fcff_array : list or array — FCFF for years 1, 2, ..., n
    wacc : float — weighted average cost of capital
    mid_year : bool — use mid-year convention if True

    Returns
    -------
    pv_fcff : array of present values for each year
    total_pv : sum of all present values
    """
    pv_fcff = []
    for t, fcff in enumerate(fcff_array, start=1):
        exponent = t - 0.5 if mid_year else t
        pv = fcff / (1 + wacc) ** exponent
        pv_fcff.append(pv)

    total_pv = sum(pv_fcff)
    return np.array(pv_fcff), total_pv


# --- Discount the forecast FCFF ---
wacc = 0.108  # From Chapter 11

fcff_values = df['FCFF'].values
pv_year_end, total_ye = discount_fcff(fcff_values, wacc, mid_year=False)
pv_mid_year, total_my = discount_fcff(fcff_values, wacc, mid_year=True)

print(f"\n=== DISCOUNTED FCFF (WACC = {wacc*100:.1f}%) ===")
print(f"{'Year':<6} {'FCFF':<10} {'PV (Yr-End)':<14} {'PV (Mid-Yr)':<14}")
for yr in df.index:
    idx = yr - 1
    print(f"  {yr:<4} {fcff_values[idx]:<10.0f} {pv_year_end[idx]:<14.0f} {pv_mid_year[idx]:<14.0f}")

print(f"\n  Total PV (Year-End): Rs. {total_ye:.0f} Cr")
print(f"  Total PV (Mid-Year): Rs. {total_my:.0f} Cr")
print(f"  Mid-Year Premium:    Rs. {total_my - total_ye:.0f} Cr ({(total_my/total_ye - 1)*100:.1f}%)")

# Show discount factors
print(f"\n  Discount Factors (WACC = {wacc*100:.0f}%):")
for t in range(1, 6):
    df_ye = 1 / (1 + wacc) ** t
    df_my = 1 / (1 + wacc) ** (t - 0.5)
    print(f"    Year {t}: Year-End = {df_ye:.4f}, Mid-Year = {df_my:.4f}")
📝
Which Convention to Use: The mid-year convention is standard in investment banking and equity research because it more accurately reflects the timing of cash flows. The difference is typically 2–5% of the total PV. For this course, use the mid-year convention as the default. The year-end convention is more conservative (lower PV) and is sometimes used for regulatory or debt-covenant valuations where conservatism is preferred.

12.5 Building the DCF Engine: The Present Value of Explicit Forecasts

Let us build the core DCF function that takes FCFF and WACC and returns the present value of the explicit forecast period. This is the first of two components of enterprise value (the second being terminal value, covered in Chapter 13).

def pv_of_explicit_forecast(fcff_forecast, wacc, mid_year=True):
    """
    Compute the present value of explicit forecast period FCFFs.

    This is Component 1 of a DCF valuation.
    Component 2 (Terminal Value PV) is covered in Chapter 13.

    Parameters
    ----------
    fcff_forecast : list or array — FCFF for forecast years 1 through n
    wacc : float
    mid_year : bool

    Returns
    -------
    dict with year-by-year PV, total PV, and discount factors.
    """
    n = len(fcff_forecast)

    pv_details = []
    for t, fcff in enumerate(fcff_forecast, start=1):
        exponent = t - 0.5 if mid_year else t
        discount_factor = 1 / (1 + wacc) ** exponent
        pv = fcff * discount_factor
        pv_details.append({
            'Year': t,
            'FCFF': fcff,
            'Discount Factor': round(discount_factor, 4),
            'PV of FCFF': round(pv, 1)
        })

    pv_df = pd.DataFrame(pv_details).set_index('Year')
    total_pv = pv_df['PV of FCFF'].sum()

    # Percentage of total from each year
    pv_df['% of Total'] = (pv_df['PV of FCFF'] / total_pv * 100).round(1)

    print(f"Present Value of {n}-Year Explicit Forecast:")
    print(f"  WACC: {wacc*100:.2f}% | Convention: {'Mid-Year' if mid_year else 'Year-End'}")
    print(f"\n{pv_df.to_string()}")
    print(f"\n  TOTAL PV (Explicit Forecast): Rs. {total_pv:,.0f} Cr")

    return {
        'pv_details': pv_df,
        'total_pv': total_pv,
        'wacc': wacc,
        'mid_year': mid_year
    }


# --- Run ---
explicit_pv = pv_of_explicit_forecast(fcff_values, wacc, mid_year=True)

# Sensitivity: Total PV at different WACCs
print(f"\n  Sensitivity — Total PV at Different WACC:")
for w in [0.08, 0.09, 0.10, 0.11, 0.12, 0.13]:
    _, total = discount_fcff(fcff_values, w, mid_year=True)
    print(f"    WACC = {w*100:.0f}% → PV = Rs. {total:,.0f} Cr")

12.6 The Complete FCFF Pipeline: From Model to Present Value

Now we connect Chapter 9 (integrated model) → Chapter 11 (WACC) → Chapter 12 (FCFF + discounting) into a single pipeline:

def dcf_preparation_pipeline(ticker_symbol, forecast_years=5):
    """
    Prepare all inputs for a DCF valuation.

    1. Fetch historical data
    2. Build integrated forecast (Chapter 9)
    3. Compute WACC (Chapter 11)
    4. Extract and discount FCFF (Chapter 12)

    Returns everything needed for the DCF in Chapters 13–14.
    """
    import yfinance as yf
    from scipy import stats

    # --- Fetch data ---
    ticker = yf.Ticker(ticker_symbol)
    info = ticker.info

    # --- WACC computation (simplified inline) ---
    rf = 0.0675
    us_erp, india_crp = 0.05, 0.0225
    india_erp = us_erp + india_crp
    tax_rate = 0.25

    # Beta
    stock_p = yf.download(ticker_symbol, period='5y', progress=False)['Adj Close']
    mkt_p = yf.download('^NSEI', period='5y', progress=False)['Adj Close']
    stock_r = stock_p.resample('ME').last().pct_change().dropna()
    mkt_r = mkt_p.resample('ME').last().pct_change().dropna()
    common = stock_r.index.intersection(mkt_r.index)
    rf_m = (1 + rf)**(1/12) - 1
    raw_beta, _, _, _, _ = stats.linregress(
        mkt_r[common] - rf_m, stock_r[common] - rf_m)
    adj_beta = (2/3) * raw_beta + (1/3)

    ke = rf + adj_beta * india_erp

    # Cost of debt and WACC (simplified — use compute_wacc in production)
    is_df = ticker.financials
    bs_df = ticker.balance_sheet

    def safe_get(df, candidates):
        for c in ([candidates] if isinstance(candidates, str) else candidates):
            if c in df.index:
                return df.loc[c]
        return None

    ebit_val = safe_get(is_df, ['Operating Income', 'EBIT'])
    interest_val = safe_get(is_df, ['Interest Expense'])
    ebit_y0 = ebit_val.iloc[0] / 1e7 if ebit_val is not None else 5000
    interest_y0 = interest_val.iloc[0] / 1e7 if interest_val is not None else 200
    icr = ebit_y0 / interest_y0 if interest_y0 > 0 else 10

    # Synthetic rating
    icr_map = [(8.5, 0.0065), (6.5, 0.01), (4.5, 0.018), (3.0, 0.03),
               (2.0, 0.045), (1.5, 0.06), (0, 0.10)]
    spread = next(s for icr_min, s in icr_map if icr >= icr_min)
    kd = rf + spread

    # Capital structure
    mkt_cap = info.get('marketCap', 1e12) / 1e7
    debt = safe_get(bs_df, ['Total Debt', 'Long Term Debt'])
    debt = debt.iloc[0] / 1e7 if debt is not None else 0
    cash = safe_get(bs_df, ['Cash And Cash Equivalents'])
    cash = cash.iloc[0] / 1e7 if cash is not None else 0
    net_debt = debt - cash

    ev = mkt_cap + max(net_debt, 0)
    e_weight = mkt_cap / ev
    d_weight = max(net_debt, 0) / ev

    wacc = e_weight * ke + d_weight * kd * (1 - tax_rate)

    # --- Build simplified forecast ---
    rev = safe_get(is_df, ['Total Revenue', 'Revenue']).iloc[0] / 1e7
    growth_rates = [0.14, 0.13, 0.12, 0.11, 0.10]
    op_margin = (ebit_y0 / rev) if rev > 0 else 0.20
    depr_rate = 0.03
    capex_pct = 0.06
    wc_pct = 0.02

    fcff_forecast = []
    prev_rev = rev
    for g in growth_rates:
        rev_next = prev_rev * (1 + g)
        ebit_next = rev_next * op_margin
        nopat = ebit_next * (1 - tax_rate)
        depr = rev_next * depr_rate
        capex_val = rev_next * capex_pct
        delta_wc = (rev_next - prev_rev) * wc_pct
        fcff = nopat + depr - capex_val - delta_wc
        fcff_forecast.append(fcff)
        prev_rev = rev_next

    # --- Discount FCFF ---
    _, pv_explicit = discount_fcff(fcff_forecast, wacc, mid_year=True)

    # --- Display Summary ---
    print(f"\n{'='*60}")
    print(f"  DCF PREPARATION: {info.get('longName', ticker_symbol)}")
    print(f"{'='*60}")
    print(f"\n  WACC:               {wacc*100:.2f}%")
    print(f"  Cost of Equity:     {ke*100:.2f}%")
    print(f"  After-Tax Kd:       {kd*(1-tax_rate)*100:.2f}%")
    print(f"  D/E:                {net_debt/mkt_cap:.2f}")
    print(f"\n  FCFF Forecast (Rs. Cr):")
    for i, fcff in enumerate(fcff_forecast, 1):
        print(f"    Year {i}: Rs. {fcff:,.0f} Cr")
    print(f"\n  PV of Explicit Forecast: Rs. {pv_explicit:,.0f} Cr")

    return {
        'ticker': ticker_symbol,
        'company': info.get('longName', ticker_symbol),
        'wacc': wacc,
        'ke': ke,
        'fcff_forecast': fcff_forecast,
        'pv_explicit': pv_explicit,
        'market_cap': mkt_cap,
        'net_debt': net_debt,
        'shares_outstanding': info.get('sharesOutstanding', None),
    }


# --- Run for a sample company ---
dcf_inputs = dcf_preparation_pipeline("ASIANPAINT.NS")

This pipeline produces everything needed for the complete DCF in Chapter 14. The pv_explicit value will be combined with the terminal value PV (Chapter 13) to derive enterprise value, then equity value, then the per-share intrinsic value.

Hands-On Project: Compute FCFF and Present Value for Your Capstone Company

Take the integrated model output from Chapter 9 and the WACC from Chapter 11. Compute FCFF for all 5 forecast years, discount them to present value using the mid-year convention, and verify the reinvestment rate consistency. This is the explicit forecast period component of your capstone DCF.

Steps

  1. Extract or recompute FCFF from your Chapter 9 integrated model. Verify each component: NOPAT, depreciation, capex, and Δ working capital.
  2. Compute the reinvestment rate for each forecast year. Check that the implied growth (Reinvestment Rate × ROIC) is approximately consistent with your revenue growth forecast. If not, identify which assumption is misaligned.
  3. Derive FCFE from FCFF using your interest and net borrowing forecast. Compare the FCFE profile to FCFF — is FCFE more or less volatile?
  4. Discount FCFF to present value using your WACC from Chapter 11. Use the mid-year convention. Compute the year-by-year PV and the total explicit-period PV.
  5. Build a sensitivity table: Total PV of explicit forecasts at WACC ranging from 8% to 14% in 1% increments. What is the PV at your base WACC, and how much does it change per 1% change in WACC?
  6. Write a 150-word note: What percentage of total FCFF comes from Year 4–5 vs Year 1–3? Why does this matter for terminal value (Chapter 13)?
View Solution / Walkthrough

Complete FCFF + Discounting Walkthrough

# ================================================================
# FCFF AND DISCOUNTING — Complete Analysis
# ================================================================

wacc = 0.1064  # From Chapter 11 pipeline

# FCFF from integrated model (Rs. Cr)
fcff_forecast = np.array([5100, 5750, 6380, 7010, 7680])

# --- 1. Reinvestment Rate Check ---
nopat_forecast = np.array([6075, 6870, 7695, 8535, 9390])
reinvestment = nopat_forecast - fcff_forecast  # What's reinvested
reinv_rate = reinvestment / nopat_forecast * 100

print("Reinvestment Rate Check:")
for i in range(5):
    implied_g = reinv_rate[i] / 100 * 0.30  # Assuming 30% ROIC
    print(f"  Year {i+1}: Reinvestment = {reinv_rate[i]:.1f}%, "
          f"Implied Growth = {implied_g*100:.1f}%")
    # Growth should roughly match your revenue growth forecast

# --- 2. FCFE Derivation ---
interest = np.array([350, 330, 310, 290, 270])
net_borrowing = np.array([0, 0, 0, 0, 0])  # Assume no net borrowing
fcfe = fcff_to_fcfe(fcff_forecast, interest, 0.25, net_borrowing)

print(f"\nFCFF vs FCFE Comparison:")
for i in range(5):
    print(f"  Year {i+1}: FCFF = {fcff_forecast[i]:,.0f}, "
          f"FCFE = {fcfe[i]:,.0f}, "
          f"Diff = {fcff_forecast[i] - fcfe[i]:,.0f}")

# --- 3. Discount FCFF ---
_, pv_explicit = discount_fcff(fcff_forecast, wacc, mid_year=True)

print(f"\nPV of Explicit FCFF = Rs. {pv_explicit:,.0f} Cr")

# Year-by-year contribution
print(f"\nYear-by-Year PV Contribution:")
cumulative = 0
for i in range(5):
    exponent = i + 1 - 0.5
    pv = fcff_forecast[i] / (1 + wacc) ** exponent
    cumulative += pv
    print(f"  Year {i+1}: PV = Rs. {pv:,.0f} Cr ({pv/pv_explicit*100:.1f}%), "
          f"Cumulative: {cumulative/pv_explicit*100:.1f}%")

# --- 4. WACC Sensitivity ---
print(f"\nPV Sensitivity to WACC:")
for w in np.arange(0.08, 0.15, 0.01):
    _, pv = discount_fcff(fcff_forecast, w, mid_year=True)
    delta = pv - pv_explicit
    print(f"  WACC = {w*100:.0f}%: PV = Rs. {pv:,.0f} Cr ({delta:+,.0f} vs base)")

# --- 5. Note ---
print(f"""
=== ANALYSIS NOTE ===

Years 4–5 contribute approximately {((pv_explicit - sum(fcff_forecast[:3] / (1+wacc)**(np.arange(1,4)-0.5))) / pv_explicit * 100):.0f}%
of the total explicit-period PV. This means the majority of value
comes from the TERMINAL VALUE (Chapter 13), not the explicit forecast.
This is typical — in most DCFs, the terminal value represents 60–80%
of total enterprise value. The explicit forecast establishes the base
from which the terminal value grows, making the Year 5 FCFF and the
terminal growth rate the two most critical assumptions in the model.
""")

Key Takeaways

1

A rupee today > a rupee tomorrow. The discount factor 1/(1+r)n converts future cash flows to present value. At a 10% WACC, a cash flow 10 years out is worth only 39% of its face value.

2

FCFF = NOPAT + D&A − Capex − ΔWC. It is the cash available to all capital providers. FCFF is discounted at WACC to derive enterprise value — the standard approach for corporate valuation.

3

The reinvestment rate links growth to cash flow. Growth = Reinvestment Rate × ROIC. If your forecast growth exceeds the implied growth from reinvestment, your assumptions are inconsistent.

4

Use the mid-year discounting convention. It assumes cash flows arrive throughout the year, not just at year-end, and is the standard in investment banking and equity research.

5

The explicit forecast PV is only Component 1 of enterprise value. Component 2 — the terminal value — typically contributes 60–80% of the total. We compute it in Chapter 13.

Test Your Understanding

1. A company has EBIT of Rs. 1,000 Cr, a tax rate of 25%, depreciation of Rs. 200 Cr, capex of Rs. 350 Cr, and an increase in working capital of Rs. 100 Cr. What is its FCFF?

2. Why is the mid-year convention used in DCF discounting?

3. A company has NOPAT of Rs. 500 Cr, a reinvestment rate of 40%, and an ROIC of 20%. What is its implied growth rate?

4. When should the FCFE approach be used instead of the FCFF approach for DCF valuation?

5. You forecast 15% annual revenue growth but your model shows a reinvestment rate of only 15%. With an ROIC of 25%, what does this imply?