riskvalidation
Validation tests, regulatory calculators and reference engines for financial risk models: the toolkit of an independent model validator.
Every test returns one TestResult that carries the statistic, the null hypothesis, the primary source that
defines the test, the policy that classified it and a fingerprint of the inputs. Thresholds live in versioned
policy files and are presented as policy, never as regulation. The core depends only on NumPy and SciPy, so the
same wheel runs in a Python pipeline and in the browser under Pyodide.
Status
Version 0.08.001: the fairness metric rows carry null alphas, their cut points in extras; 0.08.000: liquidity (run-off, deposits, the counterbalancing capacity, the maturity ladder and reverse liquidity stress), aggregation (simple sum and variance-covariance, copulas, bounds and the dependence band, aggregation model risk), stress testing (satellites, scenario models, path transposition, the capital path, reverse stress), the regulatory calculators (the standardised approach, IRB, the output floor, SA-CCR, BA-CVA, the FRTB sensitivities-based method and liquidity-horizon cascade, LCR and NSFR), counterparty credit risk (Hull-White one-factor exposure, swaps, collateral, CVA), machine-learning model validation and fair lending, each with its validation tests; 0.07.000: portfolio credit capital (copula Monte Carlo, CreditRisk+, the granularity adjustment, importance sampling, Euler contributions, the Vasicek fit), market risk (VaR and ES estimators, scoring, the model confidence set, the FRTB back-tests and PLA), interest rate risk in the banking book (SRP31 and RAN 21-13 Annex 1 EVE and NII, behavioural models, EaR and EVaR) and operational risk (LDA by Monte Carlo, Panjer and FFT, the SMA), each with its validation tests; 0.06.000: loss given default and exposure at default (workout LGD, the LGD rungs, downturn LGD, CCF and EAD, the IRB floors, and their validation tests); 0.05.000: provisions (the IFRS 9 expected credit loss engine with its validation battery, and the CMF B-1 and BdE Annex 9 statutory provisions); before it, the core contracts (result record, policy, registry, suite runner); 27 validation tests for PD calibration, discrimination, rating-system stability, population stability and rating transitions; the IRB risk-weight functions under four regimes; three reference engines (the one-factor model with its large homogeneous portfolio, most prudent estimation for low-default portfolios, PD curve calibration after Tasche 2013); rating transitions (cohort, duration, Aalen-Johansen and EM estimators, the embedding problem, intervals for PDs by grade, mobility, the through-the-cycle portfolio a migration matrix implies); and known-truth generators, among them rating paths with planted momentum, regimes and withdrawals, with a size and power harness that measures how often each test rejects a right model and catches a wrong one, with the Monte Carlo error of every rate. Each reproduces its primary source's own tables, worked examples or published simulations. Further calculators and engines arrive unit by unit; the CHANGELOG lists exactly what each release contains. Not yet published on PyPI.
Install (from source, until the first PyPI release)
git clone https://github.com/fsantibanezleal/CAOS_RiskValidation.git
cd CAOS_RiskValidation
python -m venv .venv
.venv/bin/pip install -e ".[dev]" # Windows: .venv\Scripts\pip install -e ".[dev]"
.venv/bin/pytest -q
Use
examples/quickstart.py, run by the test suite:
import numpy as np
from riskvalidation import default_policy, run_suite
from riskvalidation.validation import (
bin_counts,
disc_auc_vs_initial,
pd_jeffreys_grades,
quantile_edges,
stability_psi,
)
rng = np.random.default_rng(2026)
# Jeffreys test per grade and for the portfolio (ECB 2019, section 2.5.3.1)
for r in pd_jeffreys_grades(n=[400, 900, 300], d=[2, 14, 19], pd=[0.004, 0.012, 0.05], grades=["A", "B", "C"]):
print(f"{r.segment:>9} p = {r.p_value:.4f} {r.light.value}")
# a scored sample: PDs and observed defaults, plus a development-period score sample
pd_scores = rng.beta(1.2, 40.0, 5000)
defaults = (rng.uniform(size=5000) < pd_scores).astype(int)
development = rng.beta(1.2, 45.0, 8000)
edges = quantile_edges(development, 10)
# a battery under one policy; a failing test is recorded and the rest still run
run = run_suite(
[
(disc_auc_vs_initial, {"auc_initial": 0.78, "risk": pd_scores, "defaults": defaults}),
(stability_psi, {"expected_counts": bin_counts(development, edges),
"actual_counts": bin_counts(pd_scores, edges)}),
],
policy=default_policy(),
model_id="retail-pd-v3",
)
for r in run.results:
print(f"{r.test_id:>22} statistic = {r.statistic:.4f} p = {r.p_value:.4f} {r.light.value}")
print("lights:", run.counts(), "worst:", run.worst().value)
Documentation
The docs/ wiki: the software design document, the architecture (result contract, policies
and lights, suites and reproducibility), one page per test family with its formula, null hypothesis, decision rule
and primary source, the regulatory calculators, the reference engines,
rating transitions and the generators and the size and power harness. examples/size_power.py
measures the size and power of a few tests in seconds.
examples/credit_math.py runs the credit mathematics end to end: IRB capital under two
regimes, the large homogeneous portfolio behind it, most prudent PDs, and a PD curve calibrated to a new year and
tested for fit. examples/rating_transitions.py estimates, embeds, tests, bounds
and projects a migration matrix on a known generator, then plants rating momentum and shows which tests see it.
What this is not
A compliance verdict on any model, a training framework for heavy learners, or a data service. A green light means a statistic fell inside a policy band.
License
MIT, see LICENSE. Developed by Felipe Santibáñez-Leal.
Metadata
Release files for riskvalidation 0.8.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| riskvalidation-0.8.1.tar.gz | 504.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| riskvalidation-0.8.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.0 MB
Release files / riskvalidation-0.8.1.tar.gz
| Download URL | riskvalidation-0.8.1.tar.gz |
|---|---|
| Size | 504.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8531ac88af69ee2dc84aaa128af3301dbee04bc585741d6c1f353ae34fbff425
|
|
BLAKE2b-256 checksum How to use checksums |
09e364efb599f9d29f3b9c62085562dbef469b96e652ebf8bad0024f66972c10
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / riskvalidation-0.8.1-py3-none-any.whl
| Download URL | riskvalidation-0.8.1-py3-none-any.whl |
|---|---|
| Size | 539.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2a546c29b7db49e70648da345fbb772c482c3227c25cb997feda64d67f31ade9
|
|
BLAKE2b-256 checksum How to use checksums |
1a58ba213d02ac3365f38245c410419eaedbba13ea860e478b7d5e8c044d6308
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for riskvalidation 0.8.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for riskvalidation-0.8.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.