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

Bank Fundamental Score

Install and import#

bash
npm install fintech-algorithms
ts
import { bankFundamentalScore } from "fintech-algorithms/fundamental-analysis-and-valuation/sector-specific-equity-scoring/bank-fundamental-score";

Signature#

bankFundamentalScore(data)

Scores a bank on eight banded prudential and profitability components, then subtracts 12.5 points for each declared minimum that the corresponding ratio falls below. Reports the pre-penalty score, the breach list and the penalty alongside the final score.

Parameters#

NameTypeNotes
dataRecordValueA plain object. framework must be the string basel-iii-teaching-v1. weights must be an object holding exactly capital, leverage, short_liquidity, stable_funding, asset_quality, coverage, margin and efficiency. The ratios read are cet1_ratio, leverage_ratio, lcr, nsfr, npl_ratio, provision_coverage_ratio and cost_income_ratio, all nonnegative, plus net_interest_margin, which may be negative. minimums must be an object supplying nonnegative cet1_ratio, leverage_ratio, lcr and nsfr floors.

Returns#

{ state: string; method: string; component_scores: Record<string, number>; weights: Record<string, number>; base_score: number; floor_breaches: string[]; penalty: number; fundamental_score: number; coverage_ratio: number; reason: string }

component_scores holds the eight band scores on a 0-100 scale and base_score is their weighted sum. floor_breaches lists the ratios below their declared minimum, penalty is 12.5 times that count, and fundamental_score is base_score less the penalty clamped to [0, 100]. state is prudential-floor-review whenever there is any breach, otherwise the band of the final score: strong-review-band at 75 or more, mixed-review-band at 50 or more, weak-review-band below that. method is bank-sector-score-v1 and coverage_ratio is 1.

Errors#

  • When data is not a plain object — throws TypeError
  • When framework is not a nonempty string, or a required ratio is not a finite number — throws TypeError
  • When minimums is missing or is not an object — throws TypeError
  • When framework is not basel-iii-teaching-v1 — throws RangeError
  • When weights does not hold exactly the eight component names, or its values do not sum to 1 within 1e-9 — throws RangeError
  • When a ratio required to be nonnegative is negative — 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
{
  "framework": "basel-iii-teaching-v1",
  "cet1_ratio": 0.12,
  "leverage_ratio": 0.05,
  "lcr": 1.25,
  "nsfr": 1.15,
  "npl_ratio": 0.025,
  "provision_coverage_ratio": 1.1,
  "net_interest_margin": 0.032,
  "cost_income_ratio": 0.48,
  "minimums": {
    "cet1_ratio": 0.045,
    "leverage_ratio": 0.03,
    "lcr": 1,
    "nsfr": 1
  },
  "weights": {
    "capital": 0.2,
    "leverage": 0.1,
    "short_liquidity": 0.1,
    "stable_funding": 0.1,
    "asset_quality": 0.15,
    "coverage": 0.1,
    "margin": 0.15,
    "efficiency": 0.1
  }
}

Call#

bankFundamentalScore(data)

Returns#

object with 10 fields: state, method, component_scores, weights, base_score, floor_breaches, penalty, fundamental_score, …

{
  "state": "mixed-review-band",
  "method": "bank-sector-score-v1",
  "component_scores": {
    "capital": 71.4285714285714,
    "leverage": 66.66666666666669,
    "short_liquidity": 62.500000000000014,
    "stable_funding": 49.999999999999964,
    "asset_quality": 91.66666666666667,
    "coverage": 83.33333333333336,
    "margin": 73.33333333333333,
    "efficiency": 73.33333333333334
  },
  "weights": {
    "capital": 0.2,
    "leverage": 0.1,
    "short_liquidity": 0.1,
    "stable_funding": 0.1,
    "asset_quality": 0.15,
    "coverage": 0.1,
    "margin": 0.15,
    "efficiency": 0.1
  },
  "base_score": 72.6190476190476,
  "floor_breaches": [],
  "penalty": 0,
  "fundamental_score": 72.6190476190476,
  "coverage_ratio": 1,
  "reason": "package-bands-with-declared-prudential-minimums"
}

Other exports#

This module also exports calculate, insuranceFundamentalScore, reitFundamentalScore, utilityFundamentalScore, earlyStageLiquidityAndRunwayScore, cyclicalAndCommodityCycleNormalization, holdingCompanyLookThroughScore, sectorSpecificWeightCalibration, unsupportedScopeAndCoverageDecision. 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#

Bank Fundamental Score — article hero
Bank Fundamental Score — component ledger
Bank Fundamental Score — decision boundary
Bank Fundamental Score — evidence clock
Bank Fundamental Score — model anatomy
Bank Fundamental Score — system map

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 Sector-Specific Equity Scoring family#