Home / Worked examples / ABF tape hunter
DEMO-07 · D15 · SAMPLE DATA · as of 2026-09-30
ABF loan tape anomaly hunter
SAMPLE DATA · fictional. Every name and number on this page is synthetic, generated by a script in the site source. No real borrower, lender, fund or deal.
Before an ABF analyst computes delinquency or roll rates, someone has to check that the tape is clean. This demo runs ten deterministic checks over a 2,000-row synthetic consumer-instalment tape. The generator planted 33 breaks of known types. The hunter, a separate script, found 33 of them with 0 false positives. Companion to .
2,000SAMPLE loans on the tape
33rows flagged
33/33planted breaks caught
0false positives
Flags by rule
| Rule | Rows |
|---|---|
| Days past due disagree with delinquency status | 4 |
| 60+ days late to current in one month (check for re-aging) | 4 |
| Current balance above original amount | 4 |
| Zero balance but still delinquent | 3 |
| Maturity on or before origination | 3 |
| Originated after the tape's as-of date | 3 |
| Invalid state code | 3 |
| APR outside 0–36% | 3 |
| FICO outside 300–850 | 3 |
| Duplicate loan ID | 3 |
Every flag
| Loan | Rule | Detail |
|---|---|---|
| S-00052 | Zero balance but still delinquent | zero balance but 45 dpd |
| S-00137 | Days past due disagree with delinquency status | dpd 97 implies 90+, tape says current |
| S-00151 | Maturity on or before origination | maturity 2025-09-27 on/before origination 2026-04-15 |
| S-00178 | Originated after the tape's as-of date | originated 2026-10-12 after as-of 2026-09-30 |
| S-00204 | Originated after the tape's as-of date | originated 2026-10-12 after as-of 2026-09-30 |
| S-00228 | Zero balance but still delinquent | zero balance but 45 dpd |
| S-00260 | Invalid state code | state code ZZ |
| S-00452 | 60+ days late to current in one month (check for re-aging) | 90+ → current in one month; check for re-age/modification |
| S-00475 | Current balance above original amount | balance 26,338 > original 22,320 |
| S-00600 | 60+ days late to current in one month (check for re-aging) | 90+ → current in one month; check for re-age/modification |
| S-00618 | Maturity on or before origination | maturity 2025-09-16 on/before origination 2026-04-04 |
| S-00655 | Current balance above original amount | balance 24,674 > original 20,910 |
| S-00692 | Current balance above original amount | balance 35,459 > original 30,050 |
| S-00707 | Zero balance but still delinquent | zero balance but 45 dpd |
| S-00712 | APR outside 0–36% | APR 45.9% outside (0, 36%] |
| S-00724 | Maturity on or before origination | maturity 2025-05-31 on/before origination 2025-12-17 |
| S-00746 | Days past due disagree with delinquency status | dpd 97 implies 90+, tape says current |
| S-00805 | FICO outside 300–850 | FICO 912 outside 300–850 |
| S-00943 | Days past due disagree with delinquency status | dpd 97 implies 90+, tape says current |
| S-01170 | Current balance above original amount | balance 16,945 > original 14,360 |
| S-01291 | FICO outside 300–850 | FICO 912 outside 300–850 |
| S-01302 | APR outside 0–36% | APR 45.9% outside (0, 36%] |
| S-01397 | APR outside 0–36% | APR 45.9% outside (0, 36%] |
| S-01405 | Originated after the tape's as-of date | originated 2026-10-12 after as-of 2026-09-30 |
| S-01509 | 60+ days late to current in one month (check for re-aging) | 90+ → current in one month; check for re-age/modification |
| S-01513 | Invalid state code | state code ZZ |
| S-01581 | Invalid state code | state code ZZ |
| S-01795 | FICO outside 300–850 | FICO 912 outside 300–850 |
| S-01916 | Days past due disagree with delinquency status | dpd 97 implies 90+, tape says current |
| S-01994 | 60+ days late to current in one month (check for re-aging) | 90+ → current in one month; check for re-age/modification |
| S-00160 | Duplicate loan ID | loan_id appears 2 times |
| S-00389 | Duplicate loan ID | loan_id appears 2 times |
| S-00509 | Duplicate loan ID | loan_id appears 2 times |
Then the roll-rate matrix (clean rows only)
Loan counts, prior-month status (rows) to current status (columns), after removing flagged rows. A synthetic tape has no real performance, so read this as the format, not a finding.
| Prior \ Now | current | 1-29 | 30-59 | 60-89 | 90+ |
|---|---|---|---|---|---|
| current | 1721 | 21 | 0 | 0 | 0 |
| 1-29 | 0 | 76 | 18 | 18 | 0 |
| 30-59 | 0 | 0 | 49 | 13 | 0 |
| 60-89 | 0 | 0 | 0 | 10 | 21 |
| 90+ | 0 | 0 | 0 | 0 | 17 |
Limits
- Real tapes break in ways a ten-rule list will not catch: servicer field changes, modification flags, charge-off timing. These rules are a floor.
- A clean result on synthetic data is easy, because the generator and the rules were written together. On a real tape, expect false positives. A person decides what counts as a break.
- Never upload a real borrower-level tape to a consumer AI tool.
Scripts: data/abf/gen_tape.py (seed 20261016) and data/abf/hunt.py. Download the SAMPLE tape (CSV) or the results. Not investment advice.