fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

Ohlson O-Score

Install and import#

bash
npm install fintech-algorithms
ts
import { ohlsonOScore } from "fintech-algorithms/fundamental-analysis-and-valuation/quality-and-distress/ohlson-o-score";

Signature#

ohlsonOScore(data)

Computes Ohlson's 1980 Model 1 O-Score from nine accounting variables, including the two indicator terms for negative equity and two consecutive loss years, and maps the linear index through a logistic function to a bankruptcy probability.

Parameters#

NameTypeNotes
data{ total_assets: number; price_level_index: number; total_liabilities: number; current_assets: number; current_liabilities: number; working_capital: number; net_income: number; prior_net_income: number; funds_from_operations: number }One accounting record plus the deflator. total_assets is divided by price_level_index before the logarithm that forms the SIZE term; total_liabilities, current_assets, current_liabilities, working_capital, net_income, prior_net_income and funds_from_operations supply the remaining eight variables.

Returns#

{ state: string; method: string; variables: { size: number; tlta: number; wcta: number; clca: number; oeneg: number; nita: number; futl: number; intwo: number; chin: number }; o_score: number; logistic_probability: number; screen: string; cutoff_probability: number }

variables holds the nine terms, with oeneg set to 1 when total liabilities exceed total assets and intwo set to 1 when both current and prior net income are negative. o_score applies the intercept -1.32 and coefficients -0.407 SIZE, 6.03 TLTA, -1.43 WCTA, 0.0757 CLCA, -1.72 OENEG, -2.37 NITA, -1.83 FUTL, 0.285 INTWO and -0.521 CHIN. logistic_probability is the logistic transform of that index, cutoff_probability is 0.038 and screen is above-original-cutoff when the probability exceeds it and below-original-cutoff otherwise. method is ohlson-1980-model-1 and state is calculated.

Errors#

  • When data is not a plain object — throws TypeError
  • When any field read is missing or not a finite number — throws TypeError
  • When total_assets, price_level_index, total_liabilities or current_assets is zero or negative — throws RangeError
  • When current_liabilities is negative — throws RangeError
  • When net_income and prior_net_income are both zero, leaving the CHIN denominator at zero — throws RangeError

Complexity: time O(1), space O(1).

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#

data
{
  "total_assets": 1000,
  "price_level_index": 1,
  "total_liabilities": 550,
  "current_assets": 450,
  "current_liabilities": 250,
  "working_capital": 200,
  "net_income": 80,
  "prior_net_income": 50,
  "funds_from_operations": 110
}

Call#

ohlsonOScore(data)

Returns#

object with 7 fields: state, method, variables, o_score, logistic_probability, screen, cutoff_probability

{
  "state": "calculated",
  "method": "ohlson-1980-model-1",
  "variables": {
    "size": 6.907755278982137,
    "tlta": 0.55,
    "wcta": 0.2,
    "clca": 0.5555555555555556,
    "oeneg": 0,
    "nita": 0.08,
    "futl": 0.2,
    "intwo": 0,
    "chin": 0.23076923076923078
  },
  "o_score": -1.734731612220943,
  "logistic_probability": 0.14998335476443922,
  "screen": "above-original-cutoff",
  "cutoff_probability": 0.038
}

Other exports#

This module also exports calculate, altmanZScore, piotroskiFScore, beneishMScore, sloanAccrualMeasure, zmijewskiXScore, springateSScore, tafflerZScore, fulmerHScore, groverGScore, dechowFScoreForMisstatementRisk, dechowDichevAccrualQuality, modifiedJonesDiscretionaryAccrualModel. 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#

Ohlson O-Score — evidence clock
Ohlson O-Score — model anatomy
Ohlson O-Score — system map
Ohlson O-Score — threshold and interpretation
Ohlson O-Score — variant boundaries

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.

Read the article →

References#

The rest of the Quality and Distress family#