Skip to main content

CDFI loan pricing model — cost of capital, target ROAA, expected loss, and admin cost analysis to compute minimum viable loan rate

Project description

cdfi-loan-pricing

PyPI Python License

CDFI loan pricing model — compute minimum viable loan rates from first principles: cost of capital, expected loss, admin cost, and target ROAA. Built for Community Development Financial Institutions that need transparent, component-driven pricing rather than market-rate following.

Why

CDFIs lend into markets where credit is scarce or expensive. Pricing a loan "to market" often means either leaving money on the table or charging more than borrowers can bear. This library models pricing from the CDFI's own cost structure so you can:

  • Find the true breakeven rate for any loan
  • Set a rate that achieves a target return while staying mission-aligned
  • Quantify the cross-subsidy your profitable loans provide to mission loans
  • Run sensitivity analysis on any cost assumption

Installation

pip install cdfi-loan-pricing

Quickstart

from cdfipricing import (
    LoanRequest,
    CDFICostStructure,
    recommend_rate,
    compute_breakeven_rate,
    sensitivity_analysis,
    cdfi_standard_scenarios,
    loan_profitability,
    portfolio_profitability,
    cross_subsidy_analysis,
    compare_pricing_scenarios,
    market_rate_comparison,
)

# Define a loan to price
loan = LoanRequest(
    loan_amount=750_000,
    term_years=10,
    amortization_years=20,
    sector="small_business",
    ltv=0.75,
    dscr_at_origination=1.25,
    borrower_credit_score=660,
    geographic_distress_level="medium",
)

# Define the CDFI's cost structure
cost_structure = CDFICostStructure(
    cost_of_funds=0.0300,       # 3.00% weighted average cost of debt
    target_roaa=0.0075,         # 0.75% target return on average assets
    target_roae=0.0450,         # 4.50% target return on average equity
    admin_cost_pct=0.0300,      # 3.00% annual operating cost
    loan_loss_reserve_rate=0.0150,  # 1.50% annual loan loss provision
    capital_charge_rate=0.15,   # 15% equity capital requirement
    fee_income_pct=0.0050,      # 0.50% net fee income
)

# Get the full pricing recommendation
result = recommend_rate(loan, cost_structure)
print(result.summary())
# CDFI Loan Pricing Summary
# ========================================
#   Recommended rate :  9.5775%
#   Breakeven rate   :  8.0775%
#   Target rate      :  9.5775%
# ...

# Check breakeven alone
be = compute_breakeven_rate(loan, cost_structure)
print(f"Breakeven rate: {be:.2%}")

# Sensitivity to cost of funds
rows = sensitivity_analysis(loan, cost_structure, "cost_of_funds", [0.02, 0.03, 0.04, 0.05])
for r in rows:
    print(f"CoF {r['value']:.1%} → recommended {r['recommended_rate']:.2%}")

# Use pre-built scenarios for different CDFI types
scenarios = cdfi_standard_scenarios()
comparisons = compare_pricing_scenarios(loan, scenarios)
for c in comparisons:
    print(f"{c['scenario']:22s}  {c['recommended_rate']:.2%}")

# Single-loan profitability at an actual rate
prof = loan_profitability(loan, cost_structure, actual_rate=0.085)
print(f"Net income: ${prof['net_income']:,.0f}  ROAA: {prof['roaa']:.2%}")

# Portfolio analysis
from cdfipricing import LoanRequest
loan2 = LoanRequest(500_000, 7, 15, "affordable_housing", 0.60, 1.40, 710, "low")
port = portfolio_profitability([loan, loan2], [0.085, 0.065], cost_structure)
print(f"Portfolio ROAA: {port['portfolio_roaa']:.2%}")

# Cross-subsidy: which loans subsidize which?
subsidy = cross_subsidy_analysis([loan, loan2], [0.085, 0.055], cost_structure)
print(f"Self-sustaining: {subsidy['is_self_sustaining']}")
print(f"Annual subsidy: ${subsidy['total_subsidy_amount']:,.0f}")

# Compare against market rate
mkt = market_rate_comparison(loan, cost_structure, market_rate=0.115)
print(f"Mission discount: {mkt['mission_subsidy_bps']:.0f} bps  (${mkt['annual_subsidy_dollars']:,.0f}/yr)")

Key Features

  • Component-driven pricing — cost of funds, expected loss, admin cost, capital charge, and target return each contribute a transparent, auditable slice of the rate
  • Sector-specific default rates — 10 sectors (small business, affordable housing, healthcare, agriculture, etc.) with calibrated expected-loss assumptions
  • Geographic distress premiums — four distress levels (low / medium / high / severe) with risk add-ons
  • Risk-tier classification — DSCR, LTV, and credit score combine into four pricing tiers
  • Pre-built CDFI scenarios — rural, urban, healthcare-focused, affordable housing-focused, small business-focused
  • Sensitivity analysis — vary any cost or loan parameter and see rate impact across a range
  • Cross-subsidy analysis — identify which loans fund mission-rate lending in your portfolio
  • Market rate benchmarking — quantify mission discount in bps and dollars

Use Cases

  • Loan officers pricing individual credits against the CDFI's actual cost structure
  • CFOs modeling the blended portfolio rate needed to sustain net asset growth
  • Board/CDFI Fund reporting — documenting the mission subsidy embedded in below-market loans
  • Grant applications — quantifying the subsidy value of concessionary capital
  • Scenario planning — how does a 100 bps rise in cost of funds affect minimum viable rates?

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_loan_pricing-0.1.0.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

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

cdfi_loan_pricing-0.1.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for cdfi_loan_pricing-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d41708e6ed9b77ae79236f7226075a2af54f2ad6a001d8d5b67535091d8a6d0
MD5 006b8f0b4f8ed0d6adff2d88eaae3304
BLAKE2b-256 867160b732cf51c37d7d28d6d86af4adc4300b0a3c638699a5d857c042ce39b6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for cdfi_loan_pricing-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0154ca81f557157e8fdf8d28eb3e31089a309cee8ac329707dd7f1c76e0133a9
MD5 bb31579d6487542c9bdf205f78578f70
BLAKE2b-256 8f893710cd4d8b5326fee71e9dff8b5317effe14ffc7c3375993ea55371731fc

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