code wiki / (root) / nx_taxlot_gate.nx

nx_taxlot_gate.nx source

↩ module page · 132 lines · 6463 B

1// nx_taxlot_gate.nx -- CAPITAL-GAINS TAX-LOT + WASH-SALE GATE. 2// Proves realized gain/loss sign, holding-period classification (incl. the exactly-one-year boundary), 3// the IRC 1091 wash-sale disallowance across full / partial / outside-window / symmetric-window cases, the 4// allowed+disallowed==original conservation invariant, the basis deferral, FIFO lot consumption, and the 5// fail-closed overdraw guard. Hand-verified integer values. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 6 7import "nx_taxlot_lib.nx" 8import "nx_matter_lib.nx" 9 10func xg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 11func xg_putn(v: i64) -> i64 { 12 let t: *u8 = sys_mmap(32) 13 var o: i64 = 0 14 var m: i64 = v 15 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m } 16 let d: *u8 = sys_mmap(32) 17 var k: i64 = 0 18 if m == 0 { d[0] = 48 as u8; k = 1 } 19 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 20 var i: i64 = 0 21 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 } 22 sys_write(1, t, o) 23 return 0 24} 25func xg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 { 26 if got == want { 27 cnt[0] = cnt[0] + 1 28 xg_puts(" PASS " as *u8); xg_puts(name); xg_puts(" = " as *u8); xg_putn(got); xg_puts("\n" as *u8) 29 return 1 30 } 31 cnt[1] = cnt[1] + 1 32 xg_puts(" FAIL " as *u8); xg_puts(name); xg_puts(" got " as *u8); xg_putn(got) 33 xg_puts(" want " as *u8); xg_putn(want); xg_puts("\n" as *u8) 34 return 0 35} 36func xg_ckstr(cnt: *i64, name: *u8, got: *u8, want: *u8) -> i64 { 37 if mt_streq(got, want) == 1 { 38 cnt[0] = cnt[0] + 1 39 xg_puts(" PASS " as *u8); xg_puts(name); xg_puts(" = " as *u8); xg_puts(got); xg_puts("\n" as *u8) 40 return 1 41 } 42 cnt[1] = cnt[1] + 1 43 xg_puts(" FAIL " as *u8); xg_puts(name); xg_puts(" got " as *u8); xg_puts(got); xg_puts("\n" as *u8) 44 return 0 45} 46 47func main(argc: i64, argv: *i64) -> i64 { 48 let cnt: *i64 = sys_mmap(16) as *i64 49 cnt[0] = 0 50 cnt[1] = 0 51 52 xg_puts("NISHI-TAXLOT-GATE (capital gains, wash-sale IRC 1091, FIFO lots, integer-exact, fail-closed)\n" as *u8) 53 54 // ---- realized gain / loss sign ---- 55 xg_ck(cnt, "T1 proceeds 1200 basis 1000 -> gain 200" as *u8, tl_realized_gain(1200, 1000), 200) 56 xg_ck(cnt, "T2 proceeds 800 basis 1000 -> loss -200" as *u8, tl_realized_gain(800, 1000), 0 - 200) 57 58 // ---- holding-period classification (1=LONG, 0=SHORT); exactly 365 days is SHORT ---- 59 xg_ck(cnt, "T3 held 400 days -> LONG-TERM (1)" as *u8, tl_holding_class(0, 400), 1) 60 xg_ck(cnt, "T4 held 300 days -> SHORT-TERM (0)" as *u8, tl_holding_class(0, 300), 0) 61 xg_ck(cnt, "T5 held exactly 365 days -> SHORT-TERM (not more-than-a-year)" as *u8, tl_holding_class(0, 365), 0) 62 xg_ck(cnt, "T6 held 366 days -> LONG-TERM (1)" as *u8, tl_holding_class(0, 366), 1) 63 xg_ckstr(cnt, "T6a class label 400 days = LONG-TERM" as *u8, tl_class_str(tl_holding_class(0, 400)), "LONG-TERM" as *u8) 64 65 // ---- *WASH SALE: loss 200 on 100 shares sold on day 100 ---- 66 xg_ck(cnt, "T7 replacement day 110 (gap 10) -> full loss DISALLOWED 200" as *u8, 67 tl_wash_disallowed(200, 100, 110, 100, 100), 200) 68 xg_ck(cnt, "T7a replacement day 70 (gap 30, before the sale) -> still washed 200" as *u8, 69 tl_wash_disallowed(200, 100, 70, 100, 100), 200) 70 xg_ck(cnt, "T8 allowed loss after full wash = 0" as *u8, 71 tl_allowed_loss(200, 100, 110, 100, 100), 0) 72 xg_ck(cnt, "T9 replacement day 140 (gap 40 > 30) -> NOT washed (0)" as *u8, 73 tl_wash_disallowed(200, 100, 140, 100, 100), 0) 74 xg_ck(cnt, "T10 loss fully claimable outside the window = 200" as *u8, 75 tl_allowed_loss(200, 100, 140, 100, 100), 200) 76 77 // ---- *PARTIAL wash: only 40 of 100 sold shares replaced ---- 78 xg_ck(cnt, "T11 partial: 40 of 100 replaced -> disallowed 80" as *u8, 79 tl_wash_disallowed(200, 100, 110, 40, 100), 80) 80 xg_ck(cnt, "T12 partial: allowed loss = 120" as *u8, 81 tl_allowed_loss(200, 100, 110, 40, 100), 120) 82 let dis: i64 = tl_wash_disallowed(200, 100, 110, 40, 100) 83 let alw: i64 = tl_allowed_loss(200, 100, 110, 40, 100) 84 xg_ck(cnt, "T13 conservation: allowed + disallowed = original loss 200" as *u8, dis + alw, 200) 85 86 // ---- a GAIN (or a non-positive loss_amount) is NEVER washed ---- 87 xg_ck(cnt, "T14 loss_amount 0 (it was a gain) -> nothing washed" as *u8, 88 tl_wash_disallowed(0, 100, 110, 100, 100), 0) 89 xg_ck(cnt, "T15 negative loss_amount -> nothing washed" as *u8, 90 tl_wash_disallowed(0 - 50, 100, 110, 100, 100), 0) 91 92 // ---- *the disallowed loss is DEFERRED into the replacement lot basis (preserved, not destroyed) ---- 93 xg_ck(cnt, "T16 replacement basis 5000 + disallowed 200 -> adjusted 5200" as *u8, 94 tl_adjusted_replacement_basis(5000, 200), 5200) 95 96 // ---- FIFO SALE: lot0[100 sh, basis 1000], lot1[100 sh, basis 1200]; sell 150 @ 11/sh ---- 97 let ls: *i64 = sys_mmap(16) as *i64 98 let lb: *i64 = sys_mmap(16) as *i64 99 ls[0] = 100 100 ls[1] = 100 101 lb[0] = 1000 102 lb[1] = 1200 103 let out: *i64 = sys_mmap(24) as *i64 104 let sold: i64 = tl_sell_fifo(ls, lb, 2, 150, 11, out) 105 xg_ck(cnt, "T17 FIFO sold 150 shares" as *u8, sold, 150) 106 xg_ck(cnt, "T17a FIFO basis consumed = 1600 (1000 + 600 from second lot)" as *u8, out[1], 1600) 107 xg_ck(cnt, "T17b FIFO proceeds = 1650" as *u8, out[0], 1650) 108 xg_ck(cnt, "T17c FIFO realized gain = 50" as *u8, out[2], 50) 109 xg_ck(cnt, "T17d oldest lot fully consumed (0 shares left)" as *u8, ls[0], 0) 110 111 // ---- *FAIL-CLOSED: cannot sell more shares than the book holds ---- 112 let ls2: *i64 = sys_mmap(16) as *i64 113 let lb2: *i64 = sys_mmap(16) as *i64 114 ls2[0] = 100 115 ls2[1] = 100 116 lb2[0] = 1000 117 lb2[1] = 1200 118 let out2: *i64 = sys_mmap(24) as *i64 119 let sold2: i64 = tl_sell_fifo(ls2, lb2, 2, 250, 11, out2) 120 xg_ck(cnt, "T18 overdraw: asked 250 on a 200-share book -> sold only 200" as *u8, sold2, 200) 121 122 xg_puts("nx_taxlot_gate: pass=" as *u8); xg_putn(cnt[0]) 123 xg_puts(" fail=" as *u8); xg_putn(cnt[1]); xg_puts("\n" as *u8) 124 if cnt[1] == 0 { 125 xg_puts("TAXLOT nx_taxlot: VERDICT=GREEN (exact capital gains + wash-sale disallowance/deferral + FIFO overdraw-safe)\n" as *u8) 126 sys_exit(0) 127 return 0 128 } 129 xg_puts("TAXLOT nx_taxlot: VERDICT=RED\n" as *u8) 130 sys_exit(1) 131 return 1 132}