code wiki / (root) / nx_amort_lib.nx

nx_amort_lib.nx

buildroot/runtime/nx_amort_lib.nx

4958 B97 linesdepth 0pulls 0 transitivereach 2 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_amort_lib.nx -- LOAN AMORTIZATION with exact penny allocation. Integer-exact, conservation-proven. The companion to nx_fin_finance (which ranks a loan's TRUE cost): this produces the actual schedule. The hard part is not the payment formula -- it is the PENNY: a level payment rarely divides the balance evenly, and naive amortizers leave a residual cent on the last payment or, worse, create one. Here the schedule is CONSERVATION-EXACT by construction -- sum of every month's principal reduction == the original principal, and the final payment is computed to clear the balance to EXACTLY ZERO (remaining balance + its last month's interest), never a lingering or invented cent. *THE LEVEL PAYMENT IS FOUND BY INTEGER BISECTION, not the pow((1+r),N) closed form (which needs floats and rounds unpredictably): the remaining balance after N payments is monotone-decreasing in the payment, so we bisect for the SMALLEST integer payment that clears the loan in exactly N months. Same technique as the bond YTM. FAIL-CLOSED: non-positive principal/term or a negative rate returns AMORT_BAD -- no schedule is produced on nonsense input. Money is minor units (cents); rate is annual basis points; monthly interest = balance * annual_bp / 120000 (=/12/10000), truncated down (borrower-favorable, absorbed by the final payment). SCALE ENVELOPE: balance up to ~9e14/annual_bp fits i64. license_tier: ORIGINAL No hw writes (Rule 26). LIB.

dependencies 0 imports · 2 importers

nx_amort_lib.nx nx_amort_gate.nx nx_finance_svc.nx

imports: none

imported by: nx_amort_gate.nxnx_finance_svc.nx

structs

none

consts

20const AMORT_BP_MONTH_DIV: i64 = 120000 // annual bp -> monthly fraction denominator (12 * 10000)
21const AMORT_BAD: i64 = 0 - 2000000002 // invalid input

functions

24func amort_monthly_interest(balance: i64, annual_bp: i64) -> i64
30func amort_balance_after(principal: i64, annual_bp: i64, payment: i64, months: i64) -> i64
45func amort_level_payment(principal: i64, annual_bp: i64, term_months: i64) -> i64
62func amort_final_payment(principal: i64, annual_bp: i64, term_months: i64) -> i64
72func amort_principal_sum(principal: i64, annual_bp: i64, term_months: i64) -> i64
called by 1: main calls 1: amort_level_payment
92func amort_total_interest(principal: i64, annual_bp: i64, term_months: i64) -> i64