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

Merton Distance-to-Default

Install and import#

bash
npm install fintech-algorithms
ts
import { mertonDistanceToDefault } from "fintech-algorithms/credit-risk-and-default/probability-of-default/merton-distance-to-default";

Signature#

mertonDistanceToDefault(equity_value, equity_volatility, debt_face_value, risk_free_rate, asset_drift, horizon_years, tolerance, max_iterations)

Solves the two-equation Merton system iteratively for the unobserved asset value and asset volatility implied by observed equity, then reports the distance to default and the default probabilities that follow from it.

Parameters#

NameTypeNotes
equity_valuenumberObserved market value of equity, in the same currency unit as the debt.
exclusive_min: 0
equity_volatilitynumberObserved volatility of equity, as an annualised decimal.
exclusive_min: 0
debt_face_valuenumberFace value of debt acting as the default barrier at the horizon.
exclusive_min: 0
risk_free_ratenumberContinuously compounded risk-free rate used to discount the barrier and to drift assets under the risk-neutral measure.
asset_driftnumberExpected asset return under the physical measure, used only for the distance to default and the physical default probability.
horizon_yearsnumberTime to the default barrier, in years.
exclusive_min: 0
tolerancenumberConvergence tolerance. The loop stops once the larger of the relative asset-value change and the absolute asset-volatility change falls to or below this value.
exclusive_min: 0
max_iterationsnumberCap on solver iterations. Must be a whole number and no more than 10000.
integer: true · exclusive_min: 0 · max: 10000

Returns#

{ asset_value: number | null; asset_volatility: number | null; distance_to_default: number | null; physical_default_probability: number | null; risk_neutral_default_probability: number | null; iterations: number; residual: number | null; state: string; reason: string }

On convergence, asset_value and asset_volatility are the solved quantities, distance_to_default uses asset_drift, physical_default_probability is the normal tail beyond it, risk_neutral_default_probability is the same tail under the risk-free drift, iterations and residual describe the solve, and state is converged. If the loop exhausts max_iterations the five numeric results come back null with state set to not-converged rather than an error being thrown.

Errors#

  • When any argument is not a finite number — throws Error
  • When equity_value, equity_volatility, debt_face_value, horizon_years, tolerance, or max_iterations is not positive — throws Error
  • When max_iterations is not a whole number or exceeds 10000 — throws Error

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

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#

equity_value
120
equity_volatility
0.35
debt_face_value
80
risk_free_rate
0.03
asset_drift
0.06
horizon_years
1
tolerance
1e-10
max_iterations
200

Call#

mertonDistanceToDefault(equity_value, equity_volatility, debt_face_value, risk_free_rate, asset_drift, horizon_years, tolerance, max_iterations)

Returns#

object with 9 fields: asset_value, asset_volatility, distance_to_default, physical_default_probability, risk_neutral_default_probability, iterations, residual, state, …

{
  "asset_value": 197.635612721046,
  "asset_volatility": 0.212513018382,
  "distance_to_default": 4.431810702245,
  "physical_default_probability": 0.000004672252,
  "risk_neutral_default_probability": 0.000008907831,
  "iterations": 2,
  "residual": 5.5e-11,
  "state": "converged",
  "reason": "merton-equity-system-solved"
}

Other exports#

This module also exports logisticPdModel, probitPdModel, throughTheCyclePd, pointInTimePd, campbellHilscherSzilagyiDistressProbability, bharathShumwayNaiveDistanceToDefault, 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#

Merton Distance-to-Default — article hero
Merton Distance-to-Default — evidence clock
Merton Distance-to-Default — formula anatomy
Merton Distance-to-Default — method comparison
Merton Distance-to-Default — system map
Merton Distance-to-Default — validation layers

Calculation flow#

Merton Distance-to-Default calculation flow
flowchart LR
    S1["Validate contemporaneous market inputs debt convention"]
    S2["Initialize asset value and volatility"]
    S3["Iterate the equityvalue and equityvolatility equations"]
    S4["If convergence fails return null structural outputs an"]
    S5["Calculate physical DD and probability with asset drift"]
    S1 --> S2
    S2 --> S3
    S3 --> S4
    S4 --> S5
    S5 --> D{"nonconvergence returns null outputs physical and riskneutr"}
    D --> O["distance_to_default + diagnostics"]
    O --> A["Audit: a converged output reproduces the equity value and volatil"]

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 Probability of Default family#