Ohlson O-Score
Calculates the Ohlson O-Score, a financial metric used to predict the likelihood of a company going bankrupt. Unlike the Altman Z-Score, which is built with multiple discriminant analysis, the O-Score’s coefficients come from a fitted logistic regression (logit) model. This is why the two models are usually reported side by side rather than one being treated as a replacement for the other: the Z-Score is only meaningful compared against Altman’s empirically derived threshold bands, while the O-Score is directly interpretable as a probability of bankruptcy once passed through the logistic transform.
The formula is as follows:
\[\text{SIZE} = \ln(\text{Total Assets})\] \[\text{TLTA} = \text{Total Liabilities} / \text{Total Assets}\] \[\text{WCTA} = \text{Working Capital} / \text{Total Assets}\] \[\text{CLCA} = \text{Current Liabilities} / \text{Current Assets}\] \[\text{OENEG} = 1 \text{if Total Liabilities} > \text{Total Assets else} 0\] \[\text{NITA} = \text{Net Income} / \text{Total Assets}\] \[\text{FUTL} = \text{Operating Cash Flow} / \text{Total Liabilities}\] \[\text{INTWO} = 1 \text{if Net Income was negative for the last two years else} 0\] \[\text{CHIN} = (\text{Net Income} (t) - \text{Net Income} (t-1)) / (| \text{Net Income} (t) | + | \text{Net Income} (t-1) |)\] \[\text{O-Score} = - 1.32 - 0.407 \cdot \text{SIZE} + 6.03 \cdot \text{TLTA} - 1.43 \cdot \text{WCTA} + 0.0757 \cdot \text{CLCA}\] \[1.72 \cdot \text{OENEG} - 2.37 \cdot \text{NITA} - 1.83 \cdot \text{FUTL} + 0.285 \cdot \text{INTWO} - 0.521 \cdot \text{CHIN}\] \[\text{Bankruptcy Probability} = 1 / (1 + e ^{- \text{O-Score}})\]The Ohlson O-Score can be interpreted as follows:
- Ohlson’s (1980) original cutoff is a bankruptcy probability of 0.038 (3.8%), the threshold that minimized the sum of Type I and Type II misclassification errors on his sample. It is deliberately far below the naive 0.50 midpoint because bankruptcy is a rare event. Equivalently, in raw O-Score terms the cutoff sits at ln(0.038 / 0.962), i.e. approximately -3.23.
- A higher probability indicates a higher likelihood of bankruptcy.
Also known as: Ohlson O-Score, bankruptcy prediction, financial distress score.
Ohlson O-Score in Python
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_ohlson_o_score as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "MSFT"], api_key="FINANCIAL_MODELING_PREP_KEY")
ohlson_o_score = toolkit.models.get_ohlson_o_score()
ohlson_o_score.loc["AAPL"]
Which returns:
| 2020 | 2021 | 2022 | 2023 | |
|---|---|---|---|---|
| Log of Total Assets | 26.5037 | 26.5841 | 26.589 | 26.5886 |
| Total Liabilities to Total Assets | 0.7983 | 0.8203 | 0.8564 | 0.8237 |
| Working Capital to Total Assets | 0.1183 | 0.0267 | -0.0527 | -0.0049 |
| Current Liabilities to Current Assets | 0.7334 | 0.9306 | 1.1372 | 1.0121 |
| Negative Equity Indicator | 0 | 0 | 0 | 0 |
| Net Income to Total Assets | 0.1773 | 0.2697 | 0.2829 | 0.2751 |
| Funds from Operations to Total Liabilities | 0.312 | 0.3614 | 0.4044 | 0.3806 |
| Negative Income Indicator | 0 | 0 | 0 | 0 |
| Change in Net Income | nan | 0.245 | 0.0263 | -0.0143 |
| Ohlson O-Score | nan | -8.5895 | -8.2408 | -8.4318 |
| Ohlson Bankruptcy Probability | nan | 0.0002 | 0.0003 | 0.0002 |
Note that the first period is NaN because the Change in Net Income and Negative Income Indicator components require a prior period to compare against.
Parameters
The function accepts the following parameters:
- rounding (int, optional): The number of decimals to round the results to. Defaults to None.
- growth (bool, optional): Whether to calculate the growth of the values. Defaults to False.
- lag (int | list[int], optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
- trailing (int | None, optional): The trailing period to use for the calculation. Defaults to None.
- show_columns (list[str] | None, optional): List of columns to show in the results. If None, all columns will be shown. Defaults to None.