Skip to main content

CDFI portfolio stress testing engine — Monte Carlo simulation with correlated NOI, rate, and property-value shocks

Project description

cdfi-stress-tester

PyPI version Python 3.9+ License: MIT

Professional CDFI portfolio stress testing engine for Python.

Monte Carlo simulation with correlated shocks to NOI, interest rates, and property values. Compute VaR, CVaR, and capital adequacy across 2008-style recession, COVID, rate-spike, and regional CRE crash scenarios — all from pure numpy/pandas, no simulation libraries required.


Why cdfi-stress-tester?

CDFI Fund regulations and investor due diligence increasingly require stress-tested capital adequacy projections. Building Monte Carlo models in Excel is brittle and hard to audit. cdfi-stress-tester provides a reproducible, testable Python engine tuned to community development finance portfolio characteristics.

Installation

pip install cdfi-stress-tester

Requires: numpy, pandas (Python 3.9+).

Quickstart

from cdfistress import (
    generate_sample_portfolio,
    from_standard,
    MonteCarloEngine,
    generate_stress_report,
    scenario_comparison_table,
    value_at_risk, conditional_var, capital_adequacy_report,
)

# Load a 50-loan CDFI portfolio
loans = generate_sample_portfolio(n=50, seed=42)

# Build the Monte Carlo engine
engine = MonteCarloEngine(loans=loans, available_capital=5_000_000)

# Run a 2008-style recession scenario
scenario = from_standard("2008_recession")
result = engine.run_simulation(scenario, n_iterations=1000, seed=42)

# Print human-readable report
print(generate_stress_report(result))
# ============================================================
# CDFI PORTFOLIO STRESS TEST REPORT
# Scenario: 2008-Style Recession  [SEVERE]
# ============================================================
# LOSS METRICS
#   Expected Loss        :     $2,341,205
#   VaR (95%)            :     $3,879,450
#   VaR (99%)            :     $4,672,000
# CAPITAL ADEQUACY
#   CAR vs Expected Loss : 2.14x
#   STATUS: ADEQUATE

# Compare multiple scenarios
scenarios = [from_standard(k) for k in ["mild_downturn", "rate_spike", "2008_recession"]]
results = [engine.run_simulation(s, n_iterations=500, seed=0) for s in scenarios]
print(scenario_comparison_table(results))

# Capital adequacy deep-dive
import numpy as np
losses = np.array([result.expected_loss])   # or use internal loss distribution
report = capital_adequacy_report(5_000_000, np.random.default_rng(0).lognormal(14, 0.5, 1000))

Key Features

Feature Detail
Monte Carlo engine MonteCarloEngine with seed-controlled reproducibility
Correlated shocks Multivariate normal draws for NOI, rate, and property value
Standard scenarios 2008 recession, COVID, rate spike (+300 bps), regional CRE crash, mild downturn
Custom scenarios create_recession_scenario(), create_rate_shock_scenario(), create_sector_specific_scenario()
VaR / CVaR 95th and 99th percentile VaR; Expected Shortfall (CVaR)
Capital adequacy CAR vs EL, VaR, and CVaR; breach count and breach rate
Tier 1 under stress Post-stress Tier 1 ratio given risk-weighted assets
Sample portfolio Reproducible 50-loan CDFI portfolio with realistic parameters
LGD modeling Per-loan LGD with collateral shortfall and 30% foreclosure-cost floor
Reports generate_stress_report() and scenario_comparison_table()

Scenarios

STANDARD_SCENARIOS = {
    "2008_recession":    {"noi_shock": -0.35, "rate_shock": 0.00, "property_value_shock": -0.40, "default_rate_multiplier": 4.0},
    "covid_shock":       {"noi_shock": -0.25, "rate_shock": -0.01, "property_value_shock": -0.15, "default_rate_multiplier": 2.5},
    "rate_spike":        {"noi_shock": -0.05, "rate_shock": +0.03, "property_value_shock": -0.20, "default_rate_multiplier": 1.8},
    "regional_cre_crash":{"noi_shock": -0.20, "rate_shock": +0.01, "property_value_shock": -0.50, "default_rate_multiplier": 3.0},
    "mild_downturn":     {"noi_shock": -0.10, "rate_shock": +0.005,"property_value_shock": -0.08, "default_rate_multiplier": 1.4},
}

Use Cases

  • CDFI Fund reporting — Demonstrate capital adequacy under regulatory stress scenarios.
  • Rating agency submissions — Produce reproducible loss distributions for credit analysis.
  • Board risk committees — Run scenario comparison tables for governance reporting.
  • Investors / lenders — Stress-test CDFI portfolios during due diligence.
  • Policy researchers — Analyze CDFI sector resilience across geographic and sector concentrations.

API Reference

# Data
generate_sample_portfolio(n=50, seed=42)   # 50-loan CDFI portfolio
Loan(loan_id, borrower_name, outstanding_balance, noi, debt_service,
     property_value, interest_rate, sector, state, ltv)
  .dscr                    # noi / debt_service
  .is_stressed             # dscr < 1.0

StressScenario(name, noi_shock, rate_shock, property_value_shock,
               default_rate_multiplier, severity)
  .summary()

# Scenarios
from_standard("2008_recession")
create_recession_scenario(noi_shock, rate_shock, property_value_shock, default_rate_multiplier)
create_rate_shock_scenario(rate_shock, property_value_shock)
create_sector_specific_scenario(sector, noi_shock, property_value_shock)
apply_shock_to_loan(loan, scenario)        # returns stressed Loan

# Simulation
MonteCarloEngine(loans, available_capital, correlation_matrix)
  .run_simulation(scenario, n_iterations=1000, seed=None)  # → StressResult
  .apply_correlated_shocks(scenario, n_iterations, seed)   # → ndarray (n, 3)
  .simulate_default_events(scenario, seed)                  # → {loan_id: pd}

# VaR / Capital
value_at_risk(losses, confidence=0.95)
conditional_var(losses, confidence=0.95)
expected_loss(losses)
tail_loss(losses, pct=0.01)
capital_adequacy(available_capital, expected_loss_amount)
tier1_under_stress(tier1_capital, losses, risk_weighted_assets, confidence=0.99)
buffer_breach_count(losses, capital_buffer)
capital_adequacy_report(available_capital, losses)

# Correlations
build_correlation_matrix(noi_rate, noi_property, rate_property)
default_correlations()
is_positive_semidefinite(matrix)

# Reports
generate_stress_report(result)         # → str
scenario_comparison_table(results)     # → str

License

MIT © Jay Patel

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cdfi_stress_tester-0.1.0.tar.gz (15.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cdfi_stress_tester-0.1.0-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file cdfi_stress_tester-0.1.0.tar.gz.

File metadata

  • Download URL: cdfi_stress_tester-0.1.0.tar.gz
  • Upload date:
  • Size: 15.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.12

File hashes

Hashes for cdfi_stress_tester-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c87f922ecc10810ef1133ac7d540238c55850df4abd5bb4bc5ecc0af10d25b97
MD5 3ca9fa28de4a7347744d4e8e9f1380b9
BLAKE2b-256 29243fe1d9a8141c85ef2cdd04efbcf2ebf22e3bebceb9ae95893d578b018584

See more details on using hashes here.

File details

Details for the file cdfi_stress_tester-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cdfi_stress_tester-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fe0ae845fe048059f99307f783f8d5f83ab2e2b45d88305d5b4c639062630b08
MD5 390263c247aec8ee75c9a15dedf05528
BLAKE2b-256 10d5bf0a3a28cd6cbc5eab1a94272bef0029a92111bbb355374075fb4d4e7f6f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page