Skip to content

pparack/clo-tranche-loss-model

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CLO Cashflow & Tranche Loss Model (v2)

A Monte Carlo engine that simulates losses across the capital structure of a Collateralized Loan Obligation (CLO) — from a synthetic leveraged-loan pool, through a quarterly cashflow waterfall with reinvestment and amortization periods, to correlated-default simulation under both Gaussian and t-copulas, and finally to tranche expected loss and implied ratings.

This reproduces, end-to-end, the core analytical workflow a rating agency (Fitch / Moody's / S&P) performs when it rates a CLO — and adds the two pieces that most distinguish a toy model from a realistic one: the time structure of a real deal and model risk from the choice of copula.

v1 → v2. v1 was an annual, single-copula reference implementation. v2 adds (1) quarterly cashflows with explicit reinvestment/amortization phases and OC turbo, and (2) a Gaussian-vs-t-copula comparison to quantify tail dependence.


What it does

Synthetic pool ─► Quarterly waterfall ─► Correlated MC ─────────► EL → Rating
  (200 loans)      reinvest → amortize    Gaussian / t-copula      (idealized EL)
                   + OC/IC turbo          (tail dependence)
  1. Loan pool — 200 synthetic leveraged loans calibrated to public market statistics (single-B concentration, SOFR+300–375 bps, ~35 industries, top-10 ~65%).
  2. Quarterly waterfall — 28 quarters (7y). During the reinvestment period (3y) recoveries are reinvested (no senior paydown); in the amortization period principal sequentially delevers the notes. OC/IC tests divert cash to turbo the seniors on breach.
  3. Correlated defaults — two-factor (systematic + industry) latent variables, quarterly default barriers, beta-distributed recoveries. Switchable Gaussian or t-copula (shared chi-square mixing → tail dependence).
  4. Rating — tranche expected loss mapped to an implied rating via a Moody's-style idealized-EL framework.

Key results

Senior tranches stay safe — even with longer exposure

Tranche Base EL 2020-like (×2) 2008-like (×3)
AAA 0.00% 0.00% 0.01%
AA 0.00% 0.49% 7.90%
A 0.06% 9.70% 47.29%
BBB 1.24% 37.13% 83.48%
BB 8.90% 72.12% 96.96%
Equity 68.31% 97.13% 99.93%

AAA expected loss is ~0 across scenarios (0.01% at a 2008-magnitude stress, with zero loss in 99%+ of paths). 36% subordination absorbs crisis-level losses even over a 7-year, reinvesting deal.

Scenario EL

Reinvestment → amortization: how the senior cushion evolves

During reinvestment the AAA notes are not paid down (flat); only in amortization do they delever. Under stress the collateral erodes faster, thinning the senior cushion from ~34% to ~13% — but it stays positive, so AAA is protected.

CE timeline

Copula choice is model risk — it lives in the tail

Gaussian and t-copula give similar means but the t-copula puts more mass in the joint-default tail. At a 2008-like stress the AA tranche's 99th-percentile loss rises from 86% (Gaussian) to 97% (t-copula, ν=5).

Gaussian vs t

AA tail distribution

Correlation drives tail risk

With independent defaults the AA tranche's 99th-percentile loss is ~24%; with realistic correlation it is ~86%. Senior tranches are long correlation — only impaired when defaults cluster, the same structural exposure found in worst-of basket products.

Correlation effect


Project structure

clo_v2/
├── config.py          # Parameters: pool, quarterly/reinvest structure, copula, tests
├── loan_pool.py       # Synthetic leveraged-loan pool generator
├── waterfall.py       # Quarterly waterfall + reinvestment/amortization + OC/IC turbo
├── simulation.py      # Gaussian / t-copula Monte Carlo simulator
├── rating_engine.py   # Expected loss → implied rating (idealized EL)
├── visualize.py       # 7 charts (reads saved results)
├── main.py            # End-to-end run; saves results_v2.json, timeline_v2.json
└── figures/           # Generated charts

Run

pip install numpy pandas scipy matplotlib
python main.py          # runs all scenarios/variants (~130s), saves JSON results
python visualize.py     # builds the 7 figures from saved results

Tech: Python · NumPy · SciPy · pandas · matplotlib


Methodology notes

  • Why synthetic data? Deal-level CLO data (loan-by-loan composition, tranche trades) is proprietary (Trepp, LSEG, Intex). This project calibrates a synthetic pool to public aggregate statistics — standard for methodology demonstration.
  • Reinvestment recycles recoveries into new risk; the reinvested sleeve defaults at a path-conditional (Vasicek) rate tied to the macro factor, so it co-moves with the original pool.
  • t-copula uses a shared chi-square mixing variable (ν=5) to induce tail dependence absent from the Gaussian copula.

Limitations & extensions

Documented honestly, because knowing the gap is half the skill:

  • Recovery is independent of default (real LGD is procyclical) → add correlated recovery.
  • Reinvestment sleeve is modeled at the aggregate (not loan-by-loan) level.
  • No explicit reinvestment-eligibility covenants (WARF, diversity, WAS).
  • Idealized-EL table is a public approximation; swap in official tables for production.
  • Possible extensions: t-copula degrees-of-freedom sensitivity, Clayton copula, equity call/refinancing optionality.

About

Quarterly CLO cashflow & tranche loss model — reinvestment/amortization, OC/IC turbo, Gaussian vs t-copula, EL→rating (Python)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages