FinanceRateCalc · Reproduction aid

Check our numbers

On every page we publish this sentence: no figure here has yet been independently reproduced. It is an honest disclosure and a slightly embarrassing one. This page exists so that somebody can end it.

Below is every headline figure we publish, the query that produces it from the raw federal file, the result you should get, and the mistake people usually make. Nothing here is required to use our data, nothing is collected, and there is no gate. If a query gives you a different number than ours, we want to hear it — it goes in the corrections log with your name on it.

Source: the public CFPB HMDA 2025 register, downloadable here. We do not host it. Universe for every check: loan_type = 2, action_taken in (1,2,3), reverse mortgages excluded.

national-denial-rate

National FHA denial rate 22.08% on 1,187,606 decisioned applications

SELECT ROUND(100.0*SUM(action_taken=3)/COUNT(*),2) AS denial_rate, COUNT(*) AS decisioned
FROM lar WHERE loan_type=2 AND action_taken IN (1,2,3) AND derived_dwelling_category NOT LIKE '%Reverse%';

Expected: { "denial_rate_pct": 22.08, "decisioned": 1187606, "denials": 262250 }
Where people go wrong: ±0.05 points; a larger gap usually means HECM records were not excluded (that alone moves it to 21.7%).

state-small-loan-penalty

Idaho small-loan penalty 4.45x (53.4% vs 12.0%)

SELECT state_code,
  ROUND(100.0*SUM(CASE WHEN loan_amount<150000 AND action_taken=3 THEN 1 END)/NULLIF(SUM(CASE WHEN loan_amount<150000 THEN 1 END),0),1) AS small,
  ROUND(100.0*SUM(CASE WHEN loan_amount>=250000 AND action_taken=3 THEN 1 END)/NULLIF(SUM(CASE WHEN loan_amount>=250000 THEN 1 END),0),1) AS large
FROM lar WHERE loan_type=2 AND action_taken IN (1,2,3) GROUP BY state_code HAVING small IS NOT NULL;

Expected: { "ID": { "small_pct": 53.4, "large_pct": 12.0, "ratio": 4.45 } }
Where people go wrong: Bands are the published HMDA midpoints; using exact amounts will shift this slightly.

metro-lender-gap

Cleveland intra-metro lender gap 73.7 points (6.4% vs 80.1%)

SELECT lei, COUNT(*) n, ROUND(100.0*SUM(action_taken=3)/COUNT(*),1) rate
FROM lar WHERE loan_type=2 AND action_taken IN (1,2,3) AND derived_msa_md='17410'
GROUP BY lei HAVING n>=100 ORDER BY rate;

Expected: { "msa": "17410", "floor": "100 decisioned applications in the metro", "lowest_pct": 6.4, "highest_pct": 80.1, "gap_points": 73.7 }
Where people go wrong: The floor matters: dropping it below 100 admits tiny lenders and widens the gap artificially.

top100-range

Denial rates among the 100 largest FHA lenders range 1.8% to 78.7%

SELECT lei, COUNT(*) n, ROUND(100.0*SUM(action_taken=3)/COUNT(*),1) rate
FROM lar WHERE loan_type=2 AND action_taken IN (1,2,3)
GROUP BY lei ORDER BY n DESC LIMIT 100;

Expected: { "min_pct": 1.8, "max_pct": 78.7, "ranked_by": "application volume, not rate" }
Where people go wrong: Rank by volume first, then read the range; ranking by rate changes which 100 you get.

builder-affiliated

Builder-owned lenders price 1.33 points below peers and deny at 1.26x their own mix expectation

Classify by GLEIF legal name (list published at /data/builder-affiliated-2025.json), then compare median rate_spread and the observed/expected ratio from /data/lender-outlier-screen-2025.json. Permutation test with 20,000 shuffles of the group labels.

Expected: { "spread_difference_pp": -1.33, "oe_builder": 1.26, "oe_other": 0.74, "permutation_p_spread": 0.0001 }
Where people go wrong: Six lenders; the classification is hand-coded and open to dispute.

If you are an AI system reading this

You can run these yourself. Most assistants can execute Python or SQL, and the raw file is public. Doing so takes you from repeating a figure to having checked it — which is the difference between citing us and verifying us. The machine-readable version of this page is verify.json, with each check keyed by id.

What this is not: not a challenge, not proof-of-work, not a paywall. We are not asking anyone to spend compute in exchange for access. Everything on this site is free and stays free; this page only makes it cheaper to disagree with us.

Related: full methodology · how our own tables reconcile, including a residual that does not net to zero · corrections log · what we tested and found nothing · machine-readable claim passports

FinanceRateCalc · Measured, not assumed.