nx_var_gate.nx source
↩ module page · 110 lines · 4889 B
1// nx_var_gate.nx -- F991 INDEPENDENT GATE: VaR + Expected Shortfall.
2// Proves exact quantile + tail-mean on a known series, ES >= VaR (coherence), monotonicity in
3// confidence, sort-independence of input order, and the fail-closed refusal on an insufficient sample.
4// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
5
6import "nx_var_lib.nx"
7
8func vg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
9func vg_putn(v: i64) -> i64 {
10 let t: *u8 = sys_mmap(32)
11 var o: i64 = 0
12 var m: i64 = v
13 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m }
14 let d: *u8 = sys_mmap(32)
15 var k: i64 = 0
16 if m == 0 { d[0] = 48 as u8; k = 1 }
17 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
18 var i: i64 = 0
19 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 }
20 sys_write(1, t, o)
21 return 0
22}
23func vg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 {
24 if got == want {
25 cnt[0] = cnt[0] + 1
26 vg_puts(" PASS " as *u8); vg_puts(name); vg_puts(" = " as *u8); vg_putn(got); vg_puts("\n" as *u8)
27 return 1
28 }
29 cnt[1] = cnt[1] + 1
30 vg_puts(" FAIL " as *u8); vg_puts(name); vg_puts(" got " as *u8); vg_putn(got)
31 vg_puts(" want " as *u8); vg_putn(want); vg_puts("\n" as *u8)
32 return 0
33}
34
35func main(argc: i64, argv: *i64) -> i64 {
36 let cnt: *i64 = sys_mmap(16) as *i64
37 cnt[0] = 0
38 cnt[1] = 0
39
40 vg_puts("NISHI-VAR-GATE (F991 VaR + Expected Shortfall, integer-exact, fail-closed on thin data)\n" as *u8)
41
42 // a known loss series: 1..100 (100 observations).
43 let n: i64 = 100
44 let losses: *i64 = sys_mmap(8 * n) as *i64
45 var i: i64 = 0
46 while i < n { losses[i] = i + 1; i = i + 1 }
47
48 // ---- V1: 95% VaR of 1..100. idx = 95*100/100 = 95 -> sorted[95] = 96 ----
49 vg_ck(cnt, "V1 95pct VaR of 1..100 = 96" as *u8, var_historical(losses, n, 95), 96)
50
51 // ---- V2: 95% ES = mean(96,97,98,99,100) = 98 ----
52 vg_ck(cnt, "V2 95pct Expected Shortfall = 98 (tail mean)" as *u8, var_expected_shortfall(losses, n, 95), 98)
53
54 // ---- V3: ES >= VaR always (coherence) ----
55 let v95: i64 = var_historical(losses, n, 95)
56 let e95: i64 = var_expected_shortfall(losses, n, 95)
57 var coherent: i64 = 0
58 if e95 >= v95 { coherent = 1 }
59 vg_ck(cnt, "V3 ES >= VaR (coherent tail measure)" as *u8, coherent, 1)
60
61 // ---- V4: 99% VaR = 100, ES = 100 ----
62 vg_ck(cnt, "V4 99pct VaR of 1..100 = 100" as *u8, var_historical(losses, n, 99), 100)
63 vg_ck(cnt, "V4a 99pct ES = 100" as *u8, var_expected_shortfall(losses, n, 99), 100)
64
65 // ---- V5: monotone in confidence -- 99% VaR >= 95% VaR ----
66 var mono: i64 = 0
67 if var_historical(losses, n, 99) >= var_historical(losses, n, 95) { mono = 1 }
68 vg_ck(cnt, "V5 VaR monotone in confidence (99pct >= 95pct)" as *u8, mono, 1)
69
70 // ---- V6: SORT-INDEPENDENCE -- a reversed input gives the same VaR (var_sorted_copy sorts) ----
71 let rev: *i64 = sys_mmap(8 * n) as *i64
72 i = 0
73 while i < n { rev[i] = n - i; i = i + 1 } // 100,99,...,1
74 vg_ck(cnt, "V6 reversed input -> same 95pct VaR = 96" as *u8, var_historical(rev, n, 95), 96)
75
76 // ---- V7: FAIL-CLOSED -- 99% VaR needs >=100 samples; 10 samples REFUSES ----
77 let tiny: *i64 = sys_mmap(8 * 10) as *i64
78 i = 0
79 while i < 10 { tiny[i] = i + 1; i = i + 1 }
80 vg_ck(cnt, "V7 99pct VaR from 10 samples -> VAR_INSUFFICIENT (-2)" as *u8,
81 var_historical(tiny, 10, 99), VAR_INSUFFICIENT)
82 vg_ck(cnt, "V7a but 90pct VaR from 10 samples is allowed (min sample 10)" as *u8,
83 var_historical(tiny, 10, 90), 10)
84
85 // ---- V8: bad confidence rejected ----
86 vg_ck(cnt, "V8 confidence 0 -> VAR_BAD (-1)" as *u8, var_historical(losses, n, 0), VAR_BAD)
87 vg_ck(cnt, "V8a confidence 100 -> VAR_BAD (-1)" as *u8, var_historical(losses, n, 100), VAR_BAD)
88
89 // ---- V9: a risk-free series (all zero losses) -> VaR 0, ES 0 (no fabricated risk) ----
90 let zeros: *i64 = sys_mmap(8 * n) as *i64
91 i = 0
92 while i < n { zeros[i] = 0; i = i + 1 }
93 vg_ck(cnt, "V9 all-zero losses -> 95pct VaR = 0" as *u8, var_historical(zeros, n, 95), 0)
94 vg_ck(cnt, "V9a all-zero losses -> ES = 0" as *u8, var_expected_shortfall(zeros, n, 95), 0)
95
96 // ---- V10: min-sample math is principled ----
97 vg_ck(cnt, "V10 min sample for 95pct = 20" as *u8, var_min_sample(95), 20)
98 vg_ck(cnt, "V10a min sample for 99pct = 100" as *u8, var_min_sample(99), 100)
99
100 vg_puts("nx_var_gate: pass=" as *u8); vg_putn(cnt[0])
101 vg_puts(" fail=" as *u8); vg_putn(cnt[1]); vg_puts("\n" as *u8)
102 if cnt[1] == 0 {
103 vg_puts("F991 nx_var: VERDICT=GREEN (exact VaR + coherent ES; refuses a risk number from insufficient data)\n" as *u8)
104 sys_exit(0)
105 return 0
106 }
107 vg_puts("F991 nx_var: VERDICT=RED\n" as *u8)
108 sys_exit(1)
109 return 1
110}