FA-58382 / Loan amortization schedules / Member archive
Schedule rows from a fixed payment: final principal clamp · case 02
The last schedule row drives the balance negative.
Case contract
x = {'principal', 'rate_bp', 'payment', 'max_months'}. For months 1..max_months while the balance is positive: interest = round_half_up(balance*bp/120000); if payment <= interest return {'error': 'negative_amortization', 'month': k}; principal paid = min(payment - interest, balance); append [k, interest, principal, balance after]. Return {'rows', 'balloon': remaining principal}.
Why this case matters
Amortization engines drive borrower statements, payoff quotes and investor remittances; a misplaced rounding step, boundary or ordering rule compounds across hundreds of periods.
One recorded failure
Sample boundary fixtureThis sample comes from the broken implementation of a controlled reproducer.
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: final principal clamp | {"balloon": -349984, "rows": [[1, 0, 16666, 33334], [2, 0, 16666, 16668], [3, 0, 16666, 2], [4, 0, 16666, -16664], [5, 0, 16666, -33330], [6, 0, 16666, -49996], [7, 0, 16666, -66662], [8, 0, 16666, -83328], [9, 0, 16666, -99994], [10, 0, 16666, -116660], [11, 0, 16666, -133326], [12, 0, 16666, -149992], [13, 0, 16666, -166658], [14, 0, 16666, -183324], [15, 0, 16666, -199990], [16, 0, 16666, -216656], [17, 0, 16666, -233322], [18, 0, 16666, -249988], [19, 0, 16666, -266654], [20, 0, 16666, -283320], [21, 0, 16666, -299986], [22, 0, 16666, -316652], [23, 0, 16666, -333318], [24, 0, 16666, -349984]]} | {"balloon": 0, "rows": [[1, 0, 16666, 33334], [2, 0, 16666, 16668], [3, 0, 16666, 2], [4, 0, 2, 0]]} | Failed |
MEMBER ARCHIVE
The complete case is available to members.
This record includes three runnable implementations, regression fixtures, execution results, and source hashes.
Member access is invitation-based. Sign in with your invited account to inspect the sources.
Sign in to the archive ↗