Skip to content

Learn

Company Research and Valuation

Reverse DCF: solve the growth implied by a stock price

A reverse DCF asks which growth assumption makes a specified cash-flow model reproduce an observed share price. The useful result is a conditional statement: with these cash flows, discount rates, debt adjustments and shares fixed, this growth rate matches this price. It does not reveal every investor’s forecast. Build the forward calculation first, identify one variable, and keep a record of what the solver was allowed to change.

This guide uses a fictional company with amounts in millions of CNY and shares in millions. It solves annual free cash flow to the firm growth over three explicit years. The terminal growth rate is a separate fixed assumption. The downloadable program is an independent calculation; it neither retrieves a live quote nor establishes that CoTrading has a reverse-DCF feature.

Freeze a complete model before reversing it

Obtain the starting cash flow, forecast schedule, discount rate, terminal assumptions, net debt and share denominator from a reviewed model. Keep source references and the valuation timestamp outside the numerical search. A stock price without a currency and share class is an incomplete input. Reconcile quoted shares with the model’s denominator before interpreting a per-share result, especially after capital changes.

The original firm-valuation chapter by Aswath Damodaran explains discounting FCFF using the cost of capital. Here the supplied model already contains cash flows after its reinvestment assumptions. The tutorial does not derive free cash flow from revenue or assume that profit and cash flow grow interchangeably. A full operating model would need to make reinvestment consistent with its growth assumptions.

Our fixed inputs are starting FCFF of 100, WACC of 10%, perpetual growth of 2%, net debt of 120 and shares of 100. The target share price is 14.55 CNY. Only the three-year FCFF growth rate, h, can move. The search contract is minus 5% through plus 25%, with a price residual tolerance of 0.00000001 CNY and at most 100 iterations. These are research choices recorded before running the calculation.

Specify the forward equation and its domain

For year t, FCFF is 100 * (1+h)**t. Discount each year’s cash flow by 1.10**t. At the end of year three, calculate terminal value from year-four FCFF: FCFF3 * 1.02 / (0.10 - 0.02). Discount that terminal value by three years, add the explicit present values, subtract net debt, and divide by shares. Keep intermediate values unrounded; round only displayed summaries.

The model requires positive starting FCFF and shares, h greater than minus 100%, and WACC greater than a nonnegative terminal growth rate. Before comparing numbers, parse them as decimals and reject NaN and either infinity. Python’s Decimal documentation describes special numeric values; successful parsing alone does not establish that an input is finite. The complete example checks every numerical model field as well as the target and search endpoints.

This particular equation is continuous and strictly increasing in h within the stated domain. Each explicit cash flow increases with h, every discount denominator is fixed and positive, and the terminal-value coefficient is positive. Subtracting fixed debt and dividing by positive shares preserve that ordering. This argument belongs to this model. It does not automatically apply to a spreadsheet containing thresholds, negative starting cash flows or growth-dependent financing costs.

Bracket the price before iterating

Evaluate the share price at both endpoints. If the target falls outside that interval, return no_solution_in_domain, together with the endpoint prices. Do not enlarge the range silently. For a strictly increasing continuous model, a target between the endpoints has one solution in the domain. An endpoint that exactly matches the target is also valid. This implementation can approximate it within the residual tolerance and returns the ordinary solved status; it does not attach a separate boundary label.

The SciPy bisection reference states the continuity and bracketing requirements for its solver. Our downloadable implementation uses only the Python standard library and implements its own bounded bisection. The documentation supports the numerical method; no SciPy package is required. Numerical convergence also remains separate from whether the chosen valuation assumptions are economically defensible.

At each iteration, calculate the midpoint and its price residual, defined as calculated price minus target price. A negative residual moves the lower endpoint upward; a positive residual moves the upper endpoint downward. Save the iteration number, tested growth and residual. Stop when the price residual meets the contract. If the iteration budget runs out, report not_converged; a final midpoint should not acquire a success label merely because a loop ended.

Work the 14.55 CNY example

At h equal to 10%, the explicit cash flows are 110, 121 and 133.1. Their discounted present values are each 100, giving 300 in total. Terminal value at year three is 1697.025, and its present value is 1275. Enterprise value is therefore 1575; subtracting 120 of net debt leaves equity value of 1455. Dividing by 100 shares produces 14.55 CNY.

The solver returns growth close to 0.10 and a price residual within the specified tolerance. In this fixture the first midpoint of the chosen range happens to be 0.10. That convenience does not remove the loop or its stopping conditions: changing the target requires repeated evaluations. The program asserts both the known forward value and the recovered growth, rather than asserting an expected label without calculating it.

mid = (lo + hi) / 2
computed, terminal_share = value(mid, model)
residual = computed - target
if abs(residual) <= D("0.00000001"):
    # Return the solution together with the iteration log.
    pass

Download the complete example. It uses Python 3.12+, the standard library and synthetic data. Save the file and run python R546.py. The full implementation supplies the model, guards, loop and assertions; the excerpt only identifies the stopping calculation.

Test two different failure mechanisms

Change only the target price to 99. The valid model cannot reach it inside the approved range, so the result is a domain-specific absence of a solution. It is not proof that the stock is impossible to value. Review the price, denominator, net debt and permitted assumptions before deciding whether a separately documented search range is justified. Preserve the original unsuccessful run when making that change.

For a different mechanism, the example probes (h-0.05)**2, which falls and then rises within the same interval. It rejects this callback as nonmonotonic instead of claiming a unique implied growth. A finite grid can expose a counterexample but cannot prove that an arbitrary function is monotonic between grid points. A more complex model needs an analytical argument, a verified monotonic segment, or explicit reporting of multiple candidate roots.

Interpret the terminal dependency and hand off the result

Terminal present value is 1275 out of enterprise value 1575, approximately 80.95%. Report that proportion beside the solved growth. It shows why the answer is conditional on the fixed 2% terminal assumption and 10% discount rate. Changing either creates a different reverse-DCF question. If you investigate that sensitivity, run separate labeled models rather than allowing the solver to change several inputs until the price matches.

The review package should contain the frozen input table, equation version, search range, endpoint prices, iteration log, final residual and terminal share. Independently substitute the returned growth into the forward equation. A reviewer should be able to reproduce the quoted price without trusting the search log. Reopen the run when the price date, cash-flow model, debt adjustment or share count changes; retain the earlier result with its original assumptions.

Check the quotation and the model boundary together

Record whether the target is a last trade, closing price or another reviewed quotation. Matching a model to an indicative price does not make that quote executable. Keep the price timestamp and the model’s accounting cutoff visible even when both are supplied manually. If an implausible growth rate appears, check those definitions before interpreting the result as evidence about expectations. Also compare cash-flow units, share units and the net-debt sign. A million-to-unit mismatch or reversed debt adjustment changes the equation itself; a smaller solver tolerance cannot repair it. Correct the inputs, assign a new model version and rerun the same acceptance checks.

FAQ

Is the solved growth the market’s consensus?

No. It is the growth required by one frozen model. Different discount rates and terminal assumptions can reproduce the same price.

Can I reverse a negative-cash-flow model with this script?

The provided model rejects that extension. Redesign the forward model and establish its valid search segments before using a root solver.