Peer-Multiple Regression
Install and import#
npm install fintech-algorithmsimport { peerMultipleRegression } from "fintech-algorithms/fundamental-analysis-and-valuation/relative-valuation/peer-multiple-regression";Signature#
peerMultipleRegression(rawInputs)Fits an ordinary least squares regression of each peer's log multiple on an intercept, expected growth, return on equity and net debt to EBITDA, then exponentiates the target's fitted value into an implied multiple and applies it to the target's valuation metric.
Parameters#
| Name | Type | Notes |
|---|---|---|
rawInputs | unknown | Declared unknown and narrowed at runtime. It must be a plain object with a target object and a peers array. Every regression row reads expected_growth_percent and return_on_equity_percent (percentage points, divided by 100 before fitting) and net_debt_to_ebitda, each a finite number of any sign. peers holds at least six objects, each also carrying a nonempty and unique string id and a positive multiple. target also carries a positive valuation_metric and an optional current_value. |
Returns#
Record<string, unknown>
model, peer_count, feature_order, coefficients keyed intercept, expected_growth_decimal, return_on_equity_decimal and net_debt_to_ebitda, r_squared_log_space measured against the log multiples rather than the levels, fitted_peers (per peer: id, observed_multiple, fitted_multiple, log_residual), target_predicted_log_multiple, implied_multiple, target_valuation_metric, implied_value (implied multiple times the metric), premium_discount_to_current measured against target.current_value and null when that is absent, smearing_correction fixed at not-applied, and state, always valuation-complete.
Errors#
- When rawInputs, target or a peer row is not a plain object, or a feature or metric is not a finite number — throws TypeError
- When peers is not an array of at least six rows, or a peer id is missing, blank or duplicated — throws RangeError
- When a peer multiple, target.valuation_metric or target.current_value is not greater than zero — throws RangeError
- When the normal-equation matrix is rank deficient, meaning Gaussian elimination finds a pivot of magnitude at or below 1e-12 — throws RangeError
Complexity: time O(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#
{
"target": {
"expected_growth_percent": 11,
"return_on_equity_percent": 15,
"net_debt_to_ebitda": 1,
"valuation_metric": 5,
"current_value": 35
},
"peers": [
{
"id": "R1",
"multiple": 3.6692966676192453,
"expected_growth_percent": 4,
"return_on_equity_percent": 8,
"net_debt_to_ebitda": 3
},
{
"id": "R2",
"multiple": 4.6043430528623635,
"expected_growth_percent": 6,
"return_on_equity_percent": 11,
"net_debt_to_ebitda": 2.4
},
{
"id": "R3",
"multiple": 5.124331102904436,
"expected_growth_percent": 8,
"return_on_equity_percent": 14,
"net_debt_to_ebitda": 1.8
}
]
}Call#
peerMultipleRegression(rawInputs)Returns#
object with 13 fields: model, peer_count, feature_order, coefficients, r_squared_log_space, fitted_peers, target_predicted_log_multiple, implied_multiple, …
{
"model": "ols-log-multiple-on-growth-roe-and-leverage",
"peer_count": 8,
"feature_order": [
"intercept",
"expected_growth_decimal",
"return_on_equity_decimal",
"net_debt_to_ebitda"
],
"coefficients": {
"intercept": 1.5364545140362829,
"expected_growth_decimal": 1.6438862781409074,
"return_on_equity_decimal": 1.6061067701607943,
"net_debt_to_ebitda": -0.13216626876457388
},
"r_squared_log_space": 0.9870676723439116,
"fitted_peers": [
{
"id": "R1",
"observed_multiple": 3.6692966676192453,
"fitted_multiple": 3.7969560280762247,
"log_residual": -0.0341997004810608
},
{
"id": "R2",
"observed_multiple": 4.6043430528623635,
"fitted_multiple": 4.457376616557734,
"log_residual": 0.032439609592552765
},
{
"id": "R3",
"observed_multiple": 5.124331102904436,
"fitted_multiple": 5.232666945553791,
"log_residual": -0.020921080333833775
}
],
"target_predicted_log_multiple": 1.8260317513913278,
"implied_multiple": 6.209198064103231,
"target_valuation_metric": 5,
"implied_value": 31.045990320516154,
"premium_discount_to_current": -0.11297170512810994,
"smearing_correction": "not-applied",
"state": "valuation-complete"
}Other exports#
This module also exports
calculate, pEComparableValuation, evEbitdaComparableValuation, priceToBookValuation, pegRatio. 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#
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.
References#
- Relative Valuation — Aswath Damodaran, New York University Stern School of Business
- Who Is My Peer? A Valuation-Based Approach to the Selection of Comparable Firms — Sanjeev Bhojraj and Charles M. C. Lee
- The Effect of the Set of Comparable Firms on the Accuracy of the Price-Earnings Valuation Method — Andrew W. Alford
- Evidence boundary