code wiki / (root) / nx_fin_zscore_gate.nx

nx_fin_zscore_gate.nx source

↩ module page · 62 lines · 3448 B

1// nx_fin_zscore_gate.nx -- proves the Altman Z-score engine: exact x1000 score from raw figures + correct 2// zone classification (safe / grey / distress) including the boundary thresholds and the no-data edge. 3// Exits 0 iff ALL pass. license_tier: ORIGINAL 4import "nx_syscalls.nx" 5import "nx_fin_zscore.nx" 6 7func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 8func g_putn(v: i64) -> i64 { 9 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 10 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 11 let d: *u8 = sys_mmap(24); var k: i64 = 0 12 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 13 var j: i64 = k - 1 14 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 15 return 0 16} 17func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 { 18 if got == want { st[0] = st[0] + 1; g_puts(" PASS "); g_puts(name); g_puts("\n") } 19 else { st[1] = st[1] + 1; g_puts(" FAIL "); g_puts(name); g_puts(" got="); g_putn(got); g_puts(" want="); g_putn(want); g_puts("\n") } 20 return 0 21} 22 23func main() -> i64 { 24 let st: *i64 = sys_mmap(16) as *i64 25 st[0] = 0; st[1] = 0 26 27 // HEALTHY firm: WC=1000 RE=2000 EBIT=800 MVE=5000 TL=2000 Sales=4000 TA=5000 28 // X1=.2 X2=.4 X3=.16 X4=2.5 X5=.8 -> Z=(12*200+14*400+33*160+6*2500+10*800)/10 = 36280/10 = 3628 (Z=3.628) 29 let zh: i64 = az_zscore(1000, 2000, 800, 5000, 2000, 4000, 5000) 30 g_puts(" [info] healthy Z*1000 = "); g_putn(zh); g_puts("\n") 31 chk("healthy firm Z*1000 = 3628", zh, 3628, st) 32 chk("healthy firm zone = SAFE", az_zone(zh), AZ_SAFE, st) 33 34 // GREY firm: WC=500 RE=1000 EBIT=400 MVE=5000 TL=3000 Sales=3000 TA=5000 35 // X1=100 X2=200 X3=80 X4=1666 X5=600 -> (1200+2800+2640+9996+6000)/10 = 22636/10 = 2263 (Z=2.263) 36 let zg: i64 = az_zscore(500, 1000, 400, 5000, 3000, 3000, 5000) 37 g_puts(" [info] grey Z*1000 = "); g_putn(zg); g_puts("\n") 38 chk("grey firm Z*1000 = 2263", zg, 2263, st) 39 chk("grey firm zone = GREY", az_zone(zg), AZ_GREY, st) 40 41 // DISTRESSED firm: negative working capital + losses. WC=-500 RE=-1000 EBIT=-200 MVE=500 TL=4000 Sales=2000 TA=3000 42 // X1=-166 X2=-333 X3=-66 X4=125 X5=666 -> (-1992-4662-2178+750+6660)/10 = -1422/10 = -142 (Z=-0.142) 43 let zd: i64 = az_zscore(0 - 500, 0 - 1000, 0 - 200, 500, 4000, 2000, 3000) 44 g_puts(" [info] distress Z*1000 = "); g_putn(zd); g_puts("\n") 45 chk("distressed firm Z*1000 = -142", zd, 0 - 142, st) 46 chk("distressed firm zone = DISTRESS", az_zone(zd), AZ_DISTRESS, st) 47 48 // ZONE BOUNDARIES (thresholds 2.99 / 1.81 scaled x1000) 49 chk("Z=2991 -> SAFE (just over 2.99)", az_zone(2991), AZ_SAFE, st) 50 chk("Z=2990 -> GREY (exactly 2.99 is not 'safe')", az_zone(2990), AZ_GREY, st) 51 chk("Z=1810 -> GREY (exactly 1.81)", az_zone(1810), AZ_GREY, st) 52 chk("Z=1809 -> DISTRESS (just under 1.81)", az_zone(1809), AZ_DISTRESS, st) 53 54 // EDGE: no data (total assets 0) -> 0 -> DISTRESS (don't pretend health from nothing) 55 chk("no data (TA=0) -> Z=0", az_zscore(1, 1, 1, 1, 1, 1, 0), 0, st) 56 chk("no data -> DISTRESS zone", az_zone(az_zscore(1, 1, 1, 1, 1, 1, 0)), AZ_DISTRESS, st) 57 58 g_puts("nx_fin_zscore_gate: PASS="); g_putn(st[0]); g_puts(" FAIL="); g_putn(st[1]); g_puts("\n") 59 if st[1] == 0 { g_puts("MARKETS R-MKT1 nx_fin_zscore: GREEN\n"); return 0 } 60 g_puts("MARKETS R-MKT1 nx_fin_zscore: RED\n") 61 return 1 62}