Common-Size Statements
Install and import#
npm install fintech-algorithmsimport { commonSizeStatements } from "fintech-algorithms/fundamental-analysis-and-valuation/statement-ratios/common-size-statements";Signature#
commonSizeStatements(input)Divides every line item of each period by that period's own base line to give common-size percentages, and tracks one focus line's percentage and its change in percentage points against the previous period.
Parameters#
| Name | Type | Notes |
|---|---|---|
input | { statement_type: string; base_label: string; focus_label: string; periods: { period: string; items: { label: string; value: number }[] }[] } | A plain object. statement_type must be income or balance and governs whether a negative base is allowed. base_label names the row every value is divided by and focus_label names the row that is tracked across periods; both must exist in every period. periods is an array of at least two objects, each with a nonempty period string and an items array of at least four rows carrying a unique nonempty label and a finite value, in the same order in every period. |
Returns#
{ statement_type: string; base_label: string; focus_label: string; period_count: number; line_item_count: number; focus_percentage: number; focus_change_pp: number; periods: { period: string; base_value: number; focus_percentage: number; focus_change_pp: number | null; items: { label: string; value: number; common_size_pct: number }[] }[]; state: string; reason: string }
statement_type, base_label and focus_label echo the inputs, and period_count and line_item_count report how many periods and rows per period were normalized. periods carries one entry per input period with its trimmed period name, the base_value used as the divisor, the focus row's focus_percentage, the focus_change_pp against the previous period (null for the first), and items repeating each label and value alongside its common_size_pct. The top-level focus_percentage and focus_change_pp are the last period's. state is always calculated and reason is signed-line-items-divided-by-period-base.
Errors#
- When statement_type is neither income nor balance — throws RangeError
- When base_label or focus_label is not a nonempty string — throws RangeError
- When periods is not an array of at least two entries, an entry is not an object, its period is not a nonempty string, or its items array holds fewer than four rows — throws RangeError
- When an item is not an object, its label is empty or repeats within the period, or its value is not a finite number — throws RangeError
- When two periods do not use the same ordered labels, or a period is missing base_label or focus_label — throws RangeError
- When the base value is zero, or negative when statement_type is balance — 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#
{
"statement_type": "income",
"base_label": "Revenue",
"focus_label": "Net income",
"periods": [
{
"period": "FY2023",
"items": [
{
"label": "Revenue",
"value": 1200
},
{
"label": "Cost of goods sold",
"value": -720
},
{
"label": "Gross profit",
"value": 480
}
]
},
{
"period": "FY2024",
"items": [
{
"label": "Revenue",
"value": 1320
},
{
"label": "Cost of goods sold",
"value": -805
},
{
"label": "Gross profit",
"value": 515
}
]
},
{
"period": "FY2025",
"items": [
{
"label": "Revenue",
"value": 1450
},
{
"label": "Cost of goods sold",
"value": -899
},
{
"label": "Gross profit",
"value": 551
}
]
}
]
}Call#
commonSizeStatements(input)Returns#
object with 10 fields: statement_type, base_label, focus_label, period_count, line_item_count, focus_percentage, focus_change_pp, periods, …
{
"statement_type": "income",
"base_label": "Revenue",
"focus_label": "Net income",
"period_count": 4,
"line_item_count": 12,
"focus_percentage": 8.8125,
"focus_change_pp": 0.674568965517,
"periods": [
{
"period": "FY2023",
"base_value": 1200,
"focus_percentage": 9.416666666667,
"focus_change_pp": null,
"items": [
{
"label": "Revenue",
"value": 1200,
"common_size_pct": 100
},
{
"label": "Cost of goods sold",
"value": -720,
"common_size_pct": -60
},
{
"label": "Gross profit",
"value": 480,
"common_size_pct": 40
}
]
},
{
"period": "FY2024",
"base_value": 1320,
"focus_percentage": 8.787878787879,
"focus_change_pp": -0.628787878788,
"items": [
{
"label": "Revenue",
"value": 1320,
"common_size_pct": 100
},
{
"label": "Cost of goods sold",
"value": -805,
"common_size_pct": -60.984848484848
},
{
"label": "Gross profit",
"value": 515,
"common_size_pct": 39.015151515152
}
]
},
{
"period": "FY2025",
"base_value": 1450,
"focus_percentage": 8.137931034483,
"focus_change_pp": -0.649947753396,
"items": [
{
"label": "Revenue",
"value": 1450,
"common_size_pct": 100
},
{
"label": "Cost of goods sold",
"value": -899,
"common_size_pct": -62
},
{
"label": "Gross profit",
"value": 551,
"common_size_pct": 38
}
]
}
],
"state": "calculated",
"reason": "signed-line-items-divided-by-period-base"
}Other exports#
This module also exports
dupontDecomposition, roicCalculation, cashConversionCycle, interestCoverageRatio, netDebtToEbitda, 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
- IFRS 18 Presentation and Disclosure in Financial Statements — International Accounting Standards Board
- IFRS Accounting Taxonomy Illustrative Examples — IFRS Foundation
- EDGAR Application Programming Interfaces — U.S. Securities and Exchange Commission
- Evidence boundary