Estimate asset correlation from historical default data under the Vasicek credit-portfolio model.
Project description
pyAssetCorr
Estimate asset correlation from historical default data under the Vasicek credit-portfolio model.
A clean-room Python implementation of the most-used functionality of the R
package AssetCorr: method-of-moments
and maximum-likelihood estimators for intra- and inter-cohort asset correlation,
with standard errors, information criteria, likelihood-ratio tests, and tools
for overlapping multi-year cohorts.
See docs/USER_GUIDE.md for the full guide.
Why asset correlation?
In the Vasicek single-factor model an obligor's latent asset return is
A = sqrt(rho) * X + sqrt(1 - rho) * eps
with a systematic factor X shared across obligors and idiosyncratic eps.
The obligor defaults when A falls below Phi^{-1}(PD). The asset
correlation rho controls how strongly defaults cluster: it drives the tail
of the portfolio loss distribution and hence economic and regulatory capital.
pyAssetCorr estimates rho (and, for several cohorts, the inter-cohort
coupling) from observed default-count time series.
Installation
pip install pyAssetCorr # numpy + scipy only
From a checkout:
pip install -e ".[dev]" # editable install with pytest
Requires Python >= 3.9. All computation is vectorized NumPy/SciPy — no
compiled extensions or JIT needed. (An [accel] extra installs numba for an
internal alternative kernel, but the built-in estimators run pure NumPy and do
not use it, so it changes neither results nor speed.)
Quickstart
Data are two equal-length arrays: d = defaults per period, n = obligors per
period.
import numpy as np
from pyassetcorr import intra_fmm, intra_mle, simulate_default_series
# Simulate a 10-year history with rho = 0.15, PD = 3%, 2000 obligors/year.
d, n = simulate_default_series(rho=0.15, pd=0.03, n=2000, T=10, seed=0)
# Method of moments (finite-sample corrected) with a confidence interval.
mom = intra_fmm(d, n, ci=True)
print(mom) # MomentResult(method='fmm', rho=..., se=..., ...)
print(mom.rho, mom.ci)
# Maximum likelihood, jointly estimating PD, with AIC/BIC and SE.
mle = intra_mle(d, n, pd="joint", ci=True)
print(mle.params["rho"], mle.params["pd"])
print(mle.aic, mle.bic, mle.se["rho"])
# The MLE integral is adaptive; pass `nodes` to check quadrature convergence,
# e.g. intra_mle(d, n, nodes=64). See the User Guide, "Checking quadrature
# convergence".
Several cohorts at once
from pyassetcorr import multi_cohort_mle, lr_test, multi_cohort_single_factor
# d, n are now (T x K): T periods, K cohorts.
fit = multi_cohort_mle(d_mat, n_mat) # per-cohort rho + free gamma
print(fit.params["rho"], fit.params["gamma"])
print(fit.inter_corr) # inter-cohort asset-corr matrix
# Is a single common factor (gamma = 1) enough?
restricted = multi_cohort_single_factor(d_mat, n_mat)
print(lr_test(fit, restricted)) # likelihood-ratio test
The multi-cohort model nests cohorts under a single global factor Z plus
per-cohort factors w_k, controlled by one coupling parameter gamma:
intra-cohort correlation stays rho_k, inter-cohort correlation is
gamma * sqrt(rho_i * rho_j). gamma = 1 is a single common factor,
gamma = 0 independent cohorts.
Overlapping multi-year cohorts
Annual cohorts measured over an h-year horizon share calendar shocks, so the
default series is autocorrelated and naive standard errors are too small. Use a
HAC lag or non-overlapping subsample averaging:
from pyassetcorr import intra_fmm, group_average
intra_fmm(d, n, lag=h - 1) # autocorrelation-robust (Frei-Wunsch) SE
group_average(d, n, horizon=h) # average over non-overlapping subsamples
Estimators
| Function | Kind | Description |
|---|---|---|
intra_amm |
MoM | Asymptotic method of moments (Gordy 2000) |
intra_fmm |
MoM | Finite-sample corrected method of moments |
intra_jdp1 |
MoM | Unbiased joint-default-probability matching (Lucas 1995) |
intra_jdp2 |
MoM | Biased JDP matching (literature parity) |
intra_mle |
MLE | Single-cohort Vasicek-Binomial MLE |
multi_cohort_mle |
MLE | Generalized multi-cohort MLE (nested two-level factor) |
AssetCorr-style aliases (intraAMM, intraFMM, intraJDP1, intraJDP2,
intraMLE) are provided for discoverability.
License
MIT. This is a clean-room implementation written from the published equations (see references below), not a translation of the GPL-3 R source, so it is free to use in both academic and commercial/financial settings.
References
- Vasicek, O. (2002). The Distribution of Loan Portfolio Value. Risk.
- Gordy, M. (2000). A comparative anatomy of credit risk models. J. Banking & Finance.
- Lucas, D. (1995). Default correlation and credit analysis. J. Fixed Income.
- Gordy, M. & Heitfield, E. (2010). Small-sample estimation of models of portfolio credit risk.
- Duellmann, K. & Gehde-Trapp, M. (2004). Probability of default estimation.
- Bluhm, C. & Overbeck, L. (2003). Systematic risk in homogeneous credit portfolios.
- Frei, C. & Wunsch, M. (2018). Moment Estimators for Autocorrelated Time Series and Default Correlations. J. Credit Risk.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyassetcorr-0.1.3.tar.gz.
File metadata
- Download URL: pyassetcorr-0.1.3.tar.gz
- Upload date:
- Size: 79.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac03aa29aa7fd13b0c18baefccfa88f8f11855fdedcff38b94130d1b83f260d4
|
|
| MD5 |
8ed9bb171e825c138b93f8afcd42c689
|
|
| BLAKE2b-256 |
fb60af164bedc2a877cf56e7d36925cbf466a6d151847b30f21ed30a8cd32599
|
File details
Details for the file pyassetcorr-0.1.3-py3-none-any.whl.
File metadata
- Download URL: pyassetcorr-0.1.3-py3-none-any.whl
- Upload date:
- Size: 27.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
876f725bb634be693f1ad744df38a1c58666068adaabc9130161c24c5400e0e7
|
|
| MD5 |
7f760fb1469560a1c2e9287cea9f41cc
|
|
| BLAKE2b-256 |
854c78ae5faf3c52f2cd3f934b3889b8ff706a8d6d777e1ab31370679eb35ed9
|