nx_fin_taxlot_gate.nx source
↩ module page · 43 lines · 2255 B
1// nx_fin_taxlot_gate.nx -- GATE for tax-lot accounting: exact holding-period days across a leap year, short/long
2// classification, realized gain/loss, wash-sale detection, and harvest benefit -- all hand-computed. Exits 0 iff
3// all pass. license_tier: ORIGINAL
4import "nx_gate.nx"
5import "nx_fin_taxlot.nx"
6
7func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 {
8 if got == want { st[0] = st[0] + 1; gw(" PASS " as *u8); gw(name); gw("\n" as *u8) }
9 else { st[1] = st[1] + 1; gw(" FAIL " as *u8); gw(name); gw(" got=" as *u8); gn(got); gw(" want=" as *u8); gn(want); gw("\n" as *u8) }
10 return 0
11}
12
13func main() -> i64 {
14 let st: *i64 = sys_mmap(16) as *i64
15 st[0] = 0; st[1] = 0
16
17 // exact day counts (2023 non-leap = 365 ; 2024 leap = 366)
18 chk("days 2024-01-01 -> 2024-01-02 = 1" as *u8, tl_days_between(20240101, 20240102), 1, st)
19 chk("days 2023-01-01 -> 2024-01-01 = 365" as *u8, tl_days_between(20230101, 20240101), 365, st)
20 chk("days 2024-01-01 -> 2025-01-01 = 366 (leap)" as *u8, tl_days_between(20240101, 20250101), 366, st)
21
22 // short vs long term (long = held MORE than 365 days)
23 chk("366 days -> long-term" as *u8, tl_is_longterm(366), 1, st)
24 chk("365 days -> short-term" as *u8, tl_is_longterm(365), 0, st)
25
26 // realized gain / loss
27 chk("realized gain (12->10 basis)*100 = +20000c" as *u8, tl_realized_cents(1200, 1000, 100), 20000, st)
28 chk("realized loss (9->10 basis)*100 = -10000c" as *u8, tl_realized_cents(900, 1000, 100), 0 - 10000, st)
29
30 // wash sale (loss re-bought within +/-30 days)
31 chk("loss + rebuy in 5d -> WASH" as *u8, tl_is_wash(0 - 10000, 5), 1, st)
32 chk("loss + rebuy in 45d -> not wash" as *u8, tl_is_wash(0 - 10000, 45), 0, st)
33 chk("gain -> never wash" as *u8, tl_is_wash(20000, 5), 0, st)
34
35 // harvest benefit at 37% (3700 bps)
36 chk("harvest $100 loss @37% = $37 (3700c)" as *u8, tl_harvest_benefit(0 - 10000, 3700), 3700, st)
37 chk("gain harvests nothing = 0" as *u8, tl_harvest_benefit(20000, 3700), 0, st)
38
39 gw("nx_fin_taxlot_gate: PASS=" as *u8); gn(st[0]); gw(" FAIL=" as *u8); gn(st[1]); gw("\n" as *u8)
40 if st[1] == 0 { gw("R7 nx_fin_taxlot: GREEN\n" as *u8); return 0 }
41 gw("R7 nx_fin_taxlot: RED\n" as *u8)
42 return 1
43}