code wiki / (root) / nx_fin_finance.nx

nx_fin_finance.nx source

↩ module page · 86 lines · 4635 B

1// nx_fin_finance.nx -- R7 (financing-cost optimizer) of THE NISHI FINANCIAL ECOSYSTEM: find AFFORDABLE 2// funding by ranking options on TRUE TOTAL COST + screening RISK. Operator's crisis: the US system isn't 3// offering an affordable rate; the answer is NOT a fantasy "cheap international loan" (that space is mostly 4// ADVANCE-FEE FRAUD), it is (1) exact apples-to-apples total-cost ranking of REAL options (credit unions, 5// CDFIs, balance transfers, debt-management plans, member/microfinance) and (2) a SCAM/PREDATORY shield. 6// 7// TRUE COST (#11 no magic, exact no-float via nx_debt amortization): an option's cost = origination fee + 8// total interest to pay off `balance` at `payment`/month. Headline APR alone is a LIE -- fees + term decide 9// the real cost; this compares them honestly on ONE scenario. 10// RISK (the never-brick analog #26: the system must NEVER lead a desperate borrower into a scam): flags 11// ADVANCE_FEE (lender demands money BEFORE disbursing -> the #1 loan-scam tell; a real lender never does) 12// PREDATORY (APR above the usury line -- payday/loan-shark territory) 13// UNLICENSED (no recognized regulator -- offshore/"international" cold-offers) 14// An option carrying ADVANCE_FEE or UNLICENSED is EXCLUDED from ranking even if its ADVERTISED rate is the 15// lowest -- the scam's bait rate must never win. Data-driven: options + the usury line are DATA (any lender, 16// any country). No floats, no hardware writes, no auto-apply (emit ranking; the operator decides). license_tier: ORIGINAL 17import "nx_syscalls.nx" 18import "nx_money.nx" 19import "nx_debt_payoff.nx" 20 21const FE_ADVANCE_FEE: i64 = 1 22const FE_PREDATORY: i64 = 2 23const FE_UNLICENSED: i64 = 4 24 25// true total cost of an option = origination fee + total interest to payoff `balance` at `payment`/month. 26// writes months-to-payoff to out_months[0]. returns -1 if the payment can't amortize it (unaffordable). 27func fe_total_cost(balance: i64, payment: i64, apr_scaled: i64, orig_fee: i64, out_months: *i64) -> i64 { 28 let intr: *i64 = sys_mmap(16) as *i64 29 let months: i64 = dbt_payoff_months(balance, apr_scaled, payment, intr) 30 if months < 0 { out_months[0] = months; return 0 - 1 } 31 out_months[0] = months 32 return mny_add(orig_fee, intr[0]) 33} 34 35// risk flags for an option vs the usury line. 0 = clean. 36func fe_risk(apr_scaled: i64, upfront_required: i64, licensed: i64, usury_apr_scaled: i64) -> i64 { 37 var f: i64 = 0 38 if upfront_required == 1 { f = f + FE_ADVANCE_FEE } 39 if apr_scaled > usury_apr_scaled { f = f + FE_PREDATORY } 40 if licensed == 0 { f = f + FE_UNLICENSED } 41 return f 42} 43 44// recommendable only if it carries NEITHER the advance-fee scam tell NOR the unlicensed tell. (A predatory- 45// but-licensed option is not excluded here -- it simply loses on true cost; the scam baits do NOT.) 46func fe_is_safe(flags: i64) -> i64 { 47 if (flags & FE_ADVANCE_FEE) != 0 { return 0 } 48 if (flags & FE_UNLICENSED) != 0 { return 0 } 49 return 1 50} 51 52// rank: among SAFE + affordable options, the lowest true cost. writes best index to out_idx[0]; 53// returns the best total cost, or -1 if none qualify. 54func fe_rank_best(balance: i64, payment: i64, aprs: *i64, fees: *i64, upfronts: *i64, lic: *i64, n: i64, usury: i64, out_idx: *i64) -> i64 { 55 var best: i64 = 0 - 1 56 var bestcost: i64 = 0 57 let m: *i64 = sys_mmap(16) as *i64 58 var i: i64 = 0 59 while i < n { 60 let flags: i64 = fe_risk(aprs[i], upfronts[i], lic[i], usury) 61 if fe_is_safe(flags) == 1 { 62 let cost: i64 = fe_total_cost(balance, payment, aprs[i], fees[i], m) 63 if cost >= 0 { 64 if best < 0 { best = i; bestcost = cost } 65 else { if cost < bestcost { best = i; bestcost = cost } } 66 } 67 } 68 i = i + 1 69 } 70 out_idx[0] = best 71 if best < 0 { return 0 - 1 } 72 return bestcost 73} 74 75// SURVIVAL RUNWAY (financial resilience -- the core JOB-LOSS question): if income stopped today, how long 76// does `savings` (liquid cash on hand) cover `monthly_obligations` (cadence-normalized bills)? Exact integer 77// arithmetic, no floats. Returns -1 ("indefinite": no recurring obligations). Months = savings / obligations. 78func fe_runway_months(savings: i64, monthly_obligations: i64) -> i64 { 79 if monthly_obligations <= 0 { return 0 - 1 } 80 return savings / monthly_obligations 81} 82// runway in DAYS (30-day month), so a sub-month runway stays legible ("6 days", not a floored "0 months"). 83func fe_runway_days(savings: i64, monthly_obligations: i64) -> i64 { 84 if monthly_obligations <= 0 { return 0 - 1 } 85 return savings * 30 / monthly_obligations 86}