DuPont Decomposition
Install and import#
npm install fintech-algorithmsimport { dupontDecomposition } from "fintech-algorithms/fundamental-analysis-and-valuation/statement-ratios/dupont-decomposition";Signature#
dupontDecomposition(input)Splits return on equity into net profit margin, asset turnover and equity multiplier, using period-average assets and equity as the denominators, and reports the gap between the three-factor product and return on equity taken directly as net_income / average_equity.
Parameters#
| Name | Type | Notes |
|---|---|---|
input | { net_income: number; revenue: number; beginning_assets: number; ending_assets: number; beginning_equity: number; ending_equity: number } | A plain object. Six keys are read and each must be a finite number: net_income and revenue form the margin, beginning_assets and ending_assets are averaged into the turnover denominator, and beginning_equity and ending_equity are averaged into the equity base. |
Returns#
{ net_profit_margin: number | null; asset_turnover: number | null; equity_multiplier: number | null; dupont_roe: number | null; direct_roe: number | null; identity_gap: number | null; average_assets: number; average_equity: number; state: string; reason: string }
net_profit_margin, asset_turnover and equity_multiplier multiply to dupont_roe; direct_roe divides net income by average equity and identity_gap is the difference between the two. average_assets and average_equity are always emitted. state is calculated, or loss when net income is negative, or not-meaningful when revenue is zero or either average is not positive — in that case the six ratio keys are null and reason joins the offending conditions with +, otherwise reason is three-factor-identity-reconciles.
Errors#
- When any of the six inputs is not a finite number — throws RangeError
Complexity: time O(1),
space O(1).
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#
{
"net_income": 96,
"revenue": 1200,
"beginning_assets": 900,
"ending_assets": 1100,
"beginning_equity": 380,
"ending_equity": 420
}Call#
dupontDecomposition(input)Returns#
object with 10 fields: net_profit_margin, asset_turnover, equity_multiplier, dupont_roe, direct_roe, identity_gap, average_assets, average_equity, …
{
"net_profit_margin": 0.08,
"asset_turnover": 1.2,
"equity_multiplier": 2.5,
"dupont_roe": 0.24,
"direct_roe": 0.24,
"identity_gap": 0,
"average_assets": 1000,
"average_equity": 400,
"state": "calculated",
"reason": "three-factor-identity-reconciles"
}Other exports#
This module also exports
roicCalculation, cashConversionCycle, interestCoverageRatio, netDebtToEbitda, commonSizeStatements, calculate. 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#
- Beginners' Guide to Financial Statements — U.S. Securities and Exchange Commission
- EDGAR Application Programming Interfaces — U.S. Securities and Exchange Commission
- IFRS 18 Presentation and Disclosure in Financial Statements — International Accounting Standards Board
- Evidence boundary