Modified Jones Discretionary Accrual Model
Install and import#
npm install fintech-algorithmsimport { modifiedJonesDiscretionaryAccrualModel } from "fintech-algorithms/fundamental-analysis-and-valuation/quality-and-distress/modified-jones-discretionary-accrual-model";Signature#
modifiedJonesDiscretionaryAccrualModel(data)Fits the modified Jones accrual model on an industry-year peer group, excluding the target firm, then applies the fitted coefficients to the target to split its scaled total accruals into non-discretionary and discretionary parts.
Parameters#
| Name | Type | Notes |
|---|---|---|
data | { target_id: string; industry_year_sample: { entity_id: string; prior_total_assets: number; total_accruals: number; revenue_change: number; receivables_change: number; net_ppe: number }[] } | target_id names the firm being measured and must be a non-empty string present in the sample. industry_year_sample must be an array of at least five records with unique entity_id values. Each record supplies prior_total_assets as the scaler, total_accruals as the regressand, and revenue_change, receivables_change and net_ppe as the regressors. |
Returns#
{ state: string; method: string; target_id: string; estimation_count: number; coefficients: { inverse_assets: number; revenue_less_receivables: number; net_ppe: number }; peer_residuals: number[]; scaled_total_accruals: number; nondiscretionary_accruals: number; discretionary_accruals: number; absolute_discretionary_accruals: number; interpretation: string }
estimation_count is the number of peers used, which is the sample size less the target. coefficients holds the three fitted slopes on inverse prior assets, revenue change net of receivables change, and net PPE, all scaled by prior assets. peer_residuals are the estimation-sample residuals. scaled_total_accruals is the target's accruals over its prior assets, nondiscretionary_accruals is the fitted value and discretionary_accruals is the difference, with absolute_discretionary_accruals its magnitude. interpretation notes that the result is a signed residual with no universal cutoff. method is modified-jones-1995-peer-estimation and state is calculated.
Errors#
- When data is not a plain object — throws TypeError
- When target_id is missing, not a string, or empty — throws TypeError
- When any numeric field read is missing or not a finite number — throws TypeError
- When industry_year_sample is not an array, holds fewer than five records, or contains a non-object entry — throws RangeError
- When entity_id values are not unique, or none of them equals target_id — throws RangeError
- When prior_total_assets on any record used is zero or negative — throws RangeError
- When the peer regression has no more observations than predictors, or its design matrix is singular — throws RangeError
Complexity: time O(n),
space O(n).
Worked example#
executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.
Input#
{
"target_id": "TARGET",
"industry_year_sample": [
{
"entity_id": "TARGET",
"prior_total_assets": 900,
"total_accruals": 48,
"revenue_change": 130,
"receivables_change": 35,
"net_ppe": 390
},
{
"entity_id": "P1",
"prior_total_assets": 700,
"total_accruals": 25,
"revenue_change": 80,
"receivables_change": 12,
"net_ppe": 260
},
{
"entity_id": "P2",
"prior_total_assets": 820,
"total_accruals": 34,
"revenue_change": 110,
"receivables_change": 18,
"net_ppe": 330
}
]
}Call#
modifiedJonesDiscretionaryAccrualModel(data)Returns#
object with 11 fields: state, method, target_id, estimation_count, coefficients, peer_residuals, scaled_total_accruals, nondiscretionary_accruals, …
{
"state": "calculated",
"method": "modified-jones-1995-peer-estimation",
"target_id": "TARGET",
"estimation_count": 7,
"coefficients": {
"inverse_assets": -0.5874747557833828,
"revenue_less_receivables": 0.22667306767603043,
"net_ppe": 0.033894017127085604
},
"peer_residuals": [
0.0019446595725300733,
0.0031079596068906493,
0.002200572287491008,
-0.0015260908118726463,
-0.002277193589259173,
-0.0029399533725206935
],
"scaled_total_accruals": 0.05333333333333334,
"nondiscretionary_accruals": 0.03796125928111433,
"discretionary_accruals": 0.015372074052219006,
"absolute_discretionary_accruals": 0.015372074052219006,
"interpretation": "signed residual; no universal manipulation cutoff"
}Other exports#
This module also exports
calculate, altmanZScore, piotroskiFScore, beneishMScore, sloanAccrualMeasure, ohlsonOScore, zmijewskiXScore, springateSScore, tafflerZScore, fulmerHScore, groverGScore, dechowFScoreForMisstatementRisk, dechowDichevAccrualQuality. 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#
- Detecting Earnings Management — Patricia M. Dechow, Richard G. Sloan, and Amy P. Sweeney
- Beginners' Guide to Financial Statements — U.S. Securities and Exchange Commission
- Conceptual Framework for Financial Reporting — International Accounting Standards Board
- Evidence boundary