Skip to main content

cdfi-benchmark 📊

CDFI and MDI peer benchmarking tool using FDIC call report data.

Pull call report financials for any FDIC-insured CDFI or MDI, compute key performance metrics, build a peer group of similar institutions, and generate a benchmarking report — using the free FDIC BankFind Suite API, no API key required.


Why cdfi-benchmark?

CDFI banks and MDIs benchmark their performance against peers manually — pulling call report data from FFIEC, computing ratios in Excel, and building comparison tables by hand. cdfi-benchmark automates the entire workflow in Python.


Installation

pip install cdfi-benchmark

Quickstart

from cdfibenchmark import (
    get_financials, build_peer_group,
    generate_report, summary_table,
)

# Pull call report data for Broadway Federal Bank (CERT 57542)
institution = get_financials(cert=57542)

# Build peer group — similar asset size, no API key needed
peers = build_peer_group(institution, same_state=True)

# Generate benchmarking report
report = generate_report(institution, peers)
print(report)

# Get results as DataFrame
df = summary_table(institution, peers)

Sample Data (No API Required)

from cdfibenchmark import build_sample_peer_group
from cdfibenchmark.data.schema import InstitutionProfile

institution = InstitutionProfile(
    cert=57542,
    name="Broadway Federal Bank",
    city="Los Angeles",
    state="CA",
    report_date="20241231",
    total_assets=655_000,
    total_deposits=520_000,
    net_loans=380_000,
    net_income=1_950,
    interest_income=28_000,
    interest_expense=8_000,
    non_interest_income=3_500,
    non_interest_expense=22_000,
    total_equity=48_000,
    tier1_ratio=12.2,
)

peers = build_sample_peer_group(institution)
report = generate_report(institution, peers)
print(report)

Metrics Computed

Metric Description Benchmark (Strong)
NIM Net Interest Margin >= 3.5%
Efficiency Ratio Non-interest expense / Revenue <= 60%
ROAA Return on Average Assets >= 1.0%
ROAE Return on Average Equity >= 10%
Tier 1 Leverage Ratio Tier 1 core capital / average assets (FDIC RBC1AAJ) >= 8%
Loans-to-Deposits Loan utilization <= 80%
NPL Ratio Non-performing loans / Gross loans <= 1.0%
Reserve Coverage Loan loss reserve / NPLs >= 100%

The Tier 1 Leverage Ratio thresholds follow bank-capital regulation, not an arbitrary target: Strong >= 8% is the Community Bank Leverage Ratio (CBLR) qualifying level (12 CFR 324.12, lowered from 9% effective 2026-07-01) and Adequate >= 5% is the leverage-ratio minimum for "well capitalized" under Prompt Corrective Action (12 CFR 324.403).


Asset Size Buckets

  • micro — Under $50MM
  • small — $50MM to $250MM
  • medium — $250MM to $1B
  • large — $1B to $5B
  • mega — Over $5B

Data Source

FDIC BankFind Suite API — free public API, no authentication required. Data covers all FDIC-insured institutions with quarterly call report data since 1934.

https://banks.data.fdic.gov/api

Error handling

The data layer fails loud. In an early-warning / anomaly-detection pipeline a silently-empty or fabricated result reads as "nothing anomalous" and masks the real problem, so the FDIC fetchers raise typed errors instead of swallowing failures:

  • FDICAPIError — a transport problem: the request never produced a usable response body. Network/timeout errors, non-2xx HTTP status, and JSON decode failures all raise this.
  • FDICResponseError — the response decoded but its structure is wrong, either at the envelope level (the top-level data key absent, null, or not a list) or at the field level inside a record: a record missing its CERT identity, a CERT that isn't int-coercible, or any core/optional financial field that is present but not numeric. A bad record is never coerced into a phantom cert=0 bank or a fabricated 0.0.
  • Legitimately empty is not an error. A successful request that returns zero rows ({"data": []}) returns the empty value for that fetcher — None, an empty DataFrame, or [] — and does not raise.

Missing-but-not-garbage fields inside an otherwise valid record are kept, not dropped: an absent core financial (e.g. ASSET) becomes NaN (unknown — it propagates to any metric computed from it rather than fabricating 0.0), and an absent optional ratio (e.g. RBCT1J) becomes None. A real present 0.0 is preserved as 0.0.

Both error types subclass CDFIBenchmarkError, so callers can catch the contract broadly or distinguish "the API is unreachable" (FDICAPIError) from "the API changed its shape" (FDICResponseError):

from cdfibenchmark import FDICAPIError, FDICResponseError

try:
    institution = get_financials(cert=57542)
except FDICAPIError:
    ...   # transport/HTTP/decode failure — retry or alert
except FDICResponseError:
    ...   # wrong-shape or present-but-garbage field — contract problem

Running Tests

PYTHONPATH=. pytest tests/ -v

96 tests across all modules.


Who This Is For

  • CDFI banks and credit unions benchmarking against peers
  • MDI management teams preparing board reports
  • CDFI Fund analysts reviewing institution performance
  • Impact investors evaluating CDFI bank investments
  • Researchers studying community banking performance trends

License

MIT 2026 Jaypatel1511

Download files

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

Source Distribution

cdfi_benchmark-0.2.1.tar.gz (22.2 kB view details)

Uploaded Source

Built Distribution

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

cdfi_benchmark-0.2.1-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file cdfi_benchmark-0.2.1.tar.gz.

File metadata

  • Download URL: cdfi_benchmark-0.2.1.tar.gz
  • Upload date:
  • Size: 22.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cdfi_benchmark-0.2.1.tar.gz
Algorithm Hash digest
SHA256 f23673775b94ed4ff84d880c9d96ce377b872569a78e8ea86ebd15115fd0f7b7
MD5 0507c2f40a93553526b8fddf6ada5e58
BLAKE2b-256 9ad8b82f6e7f122f6b3bf8821fc42bf55643c871f23b2f6cbb2ebe1a99a813ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for cdfi_benchmark-0.2.1.tar.gz:

Publisher: release.yml on Jaypatel1511/cdfi-benchmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cdfi_benchmark-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: cdfi_benchmark-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cdfi_benchmark-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 45f2306964c1a13270ddc092d488e86d9f58cf4c11e5177d09db89e3705c8241
MD5 03dd5dd3e4ace4add48dccb73ad1a554
BLAKE2b-256 1109c7e4e1190ae1006ff178486f8bda7b89f00f756fd30fc3245fa8123b2249

See more details on using hashes here.

Provenance

The following attestation bundles were made for cdfi_benchmark-0.2.1-py3-none-any.whl:

Publisher: release.yml on Jaypatel1511/cdfi-benchmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

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