fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

EV/EBITDA Comparable Valuation

Install and import#

bash
npm install fintech-algorithms
ts
import { evEbitdaComparableValuation } from "fintech-algorithms/fundamental-analysis-and-valuation/relative-valuation/ev-ebitda-comparable-valuation";

Signature#

evEbitdaComparableValuation(rawInputs)

Takes the median of the peer group's enterprise-value-to-EBITDA multiples, applies it to the target's EBITDA, then walks the resulting enterprise value down to an equity value and a per-share price through a net-debt bridge.

Parameters#

NameTypeNotes
rawInputsunknownDeclared unknown and narrowed at runtime. It must be a plain object with a target object and a peers array. target supplies a positive ebitda and shares_outstanding, an optional net_debt (any finite sign, defaulting to 0), optional nonnegative preferred_equity, noncontrolling_interest and nonoperating_assets (each defaulting to 0), and an optional current_price. peers holds at least three objects, each with a nonempty and unique string id, a positive enterprise_value and a positive ebitda.

Returns#

Record<string, unknown>

model, peer_count, peer_multiples (per peer: id, enterprise_value, ebitda, ev_ebitda), multiple_summary with minimum, median, maximum and range, selected_multiple which is that median, target_ebitda, implied_enterprise_value, equity_bridge echoing net_debt, preferred_equity, noncontrolling_interest and nonoperating_assets, implied_equity_value (enterprise value less net debt, preferred and minority interest, plus nonoperating assets), shares_outstanding, implied_price which is null when the equity value is not positive, premium_discount_to_current, and state, either valuation-complete or nonpositive-equity-bridge.

Errors#

  • When rawInputs, target or a peer row is not a plain object, or a numeric field is not a finite number — throws TypeError
  • When peers is not an array of at least three rows, or a peer id is missing, blank or duplicated — throws RangeError
  • When target.ebitda, target.shares_outstanding, a peer enterprise_value, a peer ebitda or target.current_price is not greater than zero — throws RangeError
  • When preferred_equity, noncontrolling_interest or nonoperating_assets is negative — throws RangeError

Complexity: time O(n log n), space O(n).

Worked example#

verified This is the worked example published in the article, replayed by the test suite on every run. The output cannot drift.

Input#

rawInputs
{
  "target": {
    "ebitda": 150,
    "net_debt": 300,
    "preferred_equity": 20,
    "noncontrolling_interest": 30,
    "nonoperating_assets": 50,
    "shares_outstanding": 100,
    "current_price": 9.5
  },
  "peers": [
    {
      "id": "E1",
      "enterprise_value": 600,
      "ebitda": 100
    },
    {
      "id": "E2",
      "enterprise_value": 700,
      "ebitda": 100
    },
    {
      "id": "E3",
      "enterprise_value": 800,
      "ebitda": 100
    }
  ]
}

Call#

evEbitdaComparableValuation(rawInputs)

Returns#

object with 13 fields: model, peer_count, peer_multiples, multiple_summary, selected_multiple, target_ebitda, implied_enterprise_value, equity_bridge, …

{
  "model": "median-positive-ebitda-peer-ev-ebitda",
  "peer_count": 5,
  "peer_multiples": [
    {
      "id": "E1",
      "enterprise_value": 600,
      "ebitda": 100,
      "ev_ebitda": 6
    },
    {
      "id": "E2",
      "enterprise_value": 700,
      "ebitda": 100,
      "ev_ebitda": 7
    },
    {
      "id": "E3",
      "enterprise_value": 800,
      "ebitda": 100,
      "ev_ebitda": 8
    }
  ],
  "multiple_summary": {
    "minimum": 6,
    "median": 8,
    "maximum": 10,
    "range": 4
  },
  "selected_multiple": 8,
  "target_ebitda": 150,
  "implied_enterprise_value": 1200,
  "equity_bridge": {
    "net_debt": 300,
    "preferred_equity": 20,
    "noncontrolling_interest": 30,
    "nonoperating_assets": 50
  },
  "implied_equity_value": 900,
  "shares_outstanding": 100,
  "implied_price": 9,
  "premium_discount_to_current": -0.052631578947368474,
  "state": "valuation-complete"
}

Other exports#

This module also exports calculate, pEComparableValuation, priceToBookValuation, pegRatio, peerMultipleRegression. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams#

EV/EBITDA Comparable Valuation — article hero
EV/EBITDA Comparable Valuation — decision boundaries
EV/EBITDA Comparable Valuation — method selection
EV/EBITDA Comparable Valuation — system map

How it works#

This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.

Read the article →

References#

The rest of the Relative Valuation family#