Skip to main content

riskvalidation

CI License: MIT

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)

Source distribution for riskvalidation 0.8.1
File Size Uploaded Provenance
riskvalidation-0.8.1.tar.gz 504.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for riskvalidation 0.8.1
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page