Credit portfolio stress tests that distinguish marginal risk from clustered defaults.
Open the online report · 中文说明 · Model and tail math · Data contract · Case study · Interview notes
Scenario assumptions are explicit. All scenarios reuse the same global, sector and obligor-level random drivers. Multiple loans to one borrower share one default event. The resulting report includes analytic expected loss, simulated mean and sampling error, discrete VaR/ES, paired scenario differences and additive sector attribution.
Python 3.11+ and Git are required. Both paths use a virtual environment directly, without activation, and install a regular package. Installation needs internet access; the generated synthetic report works offline.
Linux / macOS
git clone https://github.com/dev-belly/StressAtlas.git
cd StressAtlas
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-replay.txt
.venv/bin/python -m pip install .
.venv/bin/python -m stressatlas demo --out outputs
.venv/bin/python -m stressatlas verify --out outputsWindows (PowerShell)
git clone https://github.com/dev-belly/StressAtlas.git
cd StressAtlas
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-replay.txt
.\.venv\Scripts\python.exe -m pip install .
.\.venv\Scripts\python.exe -m stressatlas demo --out outputs
.\.venv\Scripts\python.exe -m stressatlas verify --out outputsOpen outputs/report.html in a browser. The default synthetic fixture has
160 loans, 80 obligors, 4 sectors and 20,000 paths. Successful verification
prints "verified": true, "files": 6 and "replayed_paths": 20000.
The report lets you switch between loss histograms and sector contributions.
Use a separate output directory for each trial; report commands can replace files.
Later examples use the installed stressatlas command: substitute
.venv/bin/python -m stressatlas on Linux/macOS or
.\.venv\Scripts\python.exe -m stressatlas on Windows when using this environment.
Saved-demo semantic replay requires the pinned versions and a compatible Linux numerical build. On Windows, generate a new local report and fully verify that report; version pins alone do not guarantee identical driver fingerprints across platforms. See the numerical replay boundaries.
stressatlas demo --paths 100000 --seed 42 --out outputs-large
stressatlas run --inputs demo/inputs.json --out outputs-customContributing and validation · Report a reproducible problem
Current source adds an optional streaming mode to all five commands:
stressatlas demo --paths 100000 --driver-mode stream --out outputs-stream
stressatlas verify --driver-mode stream --out outputs-stream
stressatlas precision --inputs outputs-stream/inputs.json --resamples 300 --driver-mode stream --out outputs-stream/precision
stressatlas verify-precision --driver-mode stream --out outputs-stream/precisionIt regenerates the same random streams in blocks for each scenario instead of
retaining the full path-by-obligor driver bank. The default remains memory.
On the same numerical build, both modes produce the same driver fingerprint,
loss paths and report bytes; either can verify the other's reports. Streaming
trades more random-number generation for less memory. Full loss/sector paths
and bootstrap statistics still need memory.
A fresh-process synthetic trial with 50,000 paths, 400 obligors and three scenarios reduced process peak RSS from 352.2 to 139.8 MiB, with elapsed time increasing from 4.58 to 5.44 seconds. These are local measurements, not a throughput guarantee. Reproduce the comparison and read the limits. This option is in current source; the earlier v0.1.0 release predates it.
160 loans · 80 obligors · 4 sectors · CNY 169.6m base EAD · 20,000 shared paths. All PD/LGD/EAD inputs are synthetic assumptions, not calibrated borrower estimates.
| Scenario | Analytic EL / CNY m | 99% VaR / CNY m | 99% ES / CNY m |
|---|---|---|---|
| Baseline | 3.366 | 15.140 | 18.476 |
| Recession | 8.692 | 29.289 | 33.602 |
| Severe | 19.270 | 51.326 | 57.176 |
| Independent defaults | 3.366 | 8.718 | 9.621 |
| Higher asset correlation | 3.366 | 22.085 | 27.706 |
The last two scenarios keep marginal PD, LGD and EAD fixed. Analytic expected loss is unchanged; this simulated portfolio's tail changes substantially. Correlation changes are not guaranteed to increase every individual path or every portfolio quantile.
Source: saved scenario table, sector attribution, normalized inputs, summary and driver fingerprint.
The separate precision report resamples complete paths with the same indices across all scenarios. It recomputes mean loss, VaR, exact empirical ES and their paired changes, reporting approximate percentile intervals and bootstrap SE. These diagnose sampling variation under fixed model assumptions; sparse and discrete tails can make coverage unreliable.
stressatlas precision --inputs demo/inputs.json --resamples 300 --out outputs/precision
stressatlas verify-precision --out outputs/precisionOnline precision report · Method and worked example · Interval rows · All resamples
- Borrower identity: splitting a loan does not create independent default events.
- Common random numbers: compare scenario losses path by path; report the standard error of paired differences.
- Discrete tails: ES integrates exactly the worst
N × (1−α)path-equivalents, including fractional boundary mass. Averaging every loss>= VaRcan be wrong when losses are tied. - Attribution: sectors share the portfolio-tail weights; boundary ties share weight equally. Contributions sum to portfolio ES and do not depend on tie order.
- Numerical checks: exact PD=0/1, analytic EL agreement, scenario monotonicity under fixed correlation, seed/order/chunk invariance and rehashed-report corruption regressions.
inputs.json and the saved seed regenerate all paths. loss_sample.csv contains only the first 200 paths; it is not the full tail sample. The manifest checks six artifacts; verification also reruns the model. Its hashes do not authenticate external source data.
The model has one-period Gaussian factors with deterministic scenario LGD/EAD. It does not model rating migration, contagion networks, dynamic recovery, cash flows or macro calibration. It is not an implementation of Basel regulatory capital. Mean Monte Carlo SE is not a VaR/ES confidence interval.
The default driver bank is held in memory (O(paths × obligors)). Optional
streaming removes that retained bank; it does not bound the whole report's
memory or establish production-scale throughput. MIT license.
