nx_fin_microcap.nx source
↩ module page · 43 lines · 2835 B
1// nx_fin_microcap.nx -- the 1000-MICROCAP FUNNEL: screen a universe of small names down to the few worth
2// trading, by COMPOSING the analysis brain we already have -- mg_grade (nx_fin_mgmt_grade: are the PEOPLE good
3// stewards?), an Altman-Z distress floor (is it a real business, not about to fail?), a liquidity floor + the
4// md_capacity scaling wall (can I actually trade it at my size?), a market-cap band (is it truly a microcap?),
5// and a price floor (avoid sub-$1 delisting/penny junk). Every threshold is DATA (Cardinal 11), passed in.
6// mc_screen returns 0=PASS or the gate number that rejected (diagnosable, like the fetch error codes). mc_score
7// ranks the survivors. Pure, i64. This is where "1000 microcaps" becomes "the handful with an edge + a real
8// business + tradeable liquidity". license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_fin_marketdata.nx"
11import "nx_fin_mgmt_grade.nx"
12
13const MC_PASS: i64 = 0
14const MC_REJ_CAPBAND: i64 = 1 // outside the microcap market-cap band
15const MC_REJ_LIQUIDITY: i64 = 2 // ADV below the liquidity floor
16const MC_REJ_PRICE: i64 = 3 // price below the floor (penny/delisting risk)
17const MC_REJ_DISTRESS: i64 = 4 // Altman-Z below the safe zone (bankruptcy risk)
18const MC_REJ_STEWARD: i64 = 5 // management grade below the bar
19const MC_REJ_CAPACITY: i64 = 6 // target position won't fit within participation% of ADV
20
21// Screen ONE candidate. cap_musd = market cap in $millions; adv_cents / price_cents / target_pos_cents in cents;
22// z_x100 = Altman-Z x100 (Z=3.00 -> 300); mgmt_score = 0..8 (fed to mg_grade). Config thresholds passed in.
23// Returns MC_PASS (0) or the first failing MC_REJ_* gate.
24func mc_screen(cap_musd: i64, adv_cents: i64, price_cents: i64, z_x100: i64, mgmt_score: i64, target_pos_cents: i64,
25 min_cap_musd: i64, max_cap_musd: i64, min_adv_cents: i64, min_price_cents: i64,
26 z_safe_x100: i64, min_grade: i64, participation_bps: i64) -> i64 {
27 if cap_musd < min_cap_musd { return MC_REJ_CAPBAND }
28 if cap_musd > max_cap_musd { return MC_REJ_CAPBAND }
29 if adv_cents < min_adv_cents { return MC_REJ_LIQUIDITY }
30 if price_cents < min_price_cents { return MC_REJ_PRICE }
31 if z_x100 < z_safe_x100 { return MC_REJ_DISTRESS }
32 if mg_grade(mgmt_score) < min_grade { return MC_REJ_STEWARD }
33 if target_pos_cents > md_capacity(adv_cents, participation_bps) { return MC_REJ_CAPACITY }
34 return MC_PASS
35}
36
37// composite quality score for ranking the survivors (higher = better): survival (Z) + weighted stewardship +
38// a catalyst boost. Weights are DATA (passed in).
39func mc_score(z_x100: i64, mgmt_score: i64, has_catalyst: i64, w_mgmt: i64, w_catalyst: i64) -> i64 {
40 var s: i64 = z_x100 + mgmt_score*w_mgmt
41 if has_catalyst == 1 { s = s + w_catalyst }
42 return s
43}