nx_finhealth_lib.nx source
↩ module page · 56 lines · 3174 B
1// nx_finhealth_lib.nx -- COMPOSITE FINANCIAL HEALTH: one verdict from the whole grounded pipeline.
2//
3// This is the recombination capstone of the finance suite -- the organ that answers "is this company
4// healthy?" by COMPOSING the pieces built separately, exactly as the atlas thesis intends: real data
5// (nx_edgar) -> structural check (nx_xbrl identity) -> distress model (Altman Z, nx_fin_zscore) ->
6// fundamental strength (Piotroski F, nx_piotroski). No re-implementation; it judges the sub-results.
7//
8// ★TWO FAIL-CLOSED GATES on the verdict, in priority order:
9// 1. INCOMPLETE -- if the F-score could not be computed (a fact was missing, the pipeline sentinel),
10// the whole verdict is INCOMPLETE. A health call on partial facts is a lie with a number on it.
11// 2. FLAGGED -- if the balance sheet does NOT balance (Assets != Liabilities + Equity), the verdict is
12// FLAGGED regardless of how good the scores look. You cannot trust a distress score or an F-score
13// computed from books that do not add up -- the structural check GATES the analytical one.
14// Only past both gates does it grade STRONG / MODERATE / WEAK from the distress zone and the F-score.
15//
16// license_tier: ORIGINAL No hw writes (Rule 26). LIB.
17
18import "nx_fin_zscore.nx"
19import "nx_piotroski_lib.nx"
20
21const FH_INCOMPLETE: i64 = 0 - 1 // a required fact was missing -- not gradable
22const FH_WEAK: i64 = 0
23const FH_MODERATE: i64 = 1
24const FH_STRONG: i64 = 2
25const FH_FLAGGED: i64 = 3 // books do not balance -- do not trust any score
26
27// ★THE JUDGE. Combines the distress zone, the F-score, and whether the balance sheet balances.
28// f_score < 0 means Piotroski returned INCOMPLETE (missing fact) -> INCOMPLETE dominates everything.
29func fh_grade(z_zone: i64, f_score: i64, identity_balanced: i64) -> i64 {
30 if f_score < 0 { return FH_INCOMPLETE }
31 if identity_balanced == 0 { return FH_FLAGGED }
32 if z_zone == AZ_SAFE { if f_score >= 7 { return FH_STRONG } }
33 if z_zone == AZ_DISTRESS { return FH_WEAK }
34 if f_score <= 2 { return FH_WEAK }
35 return FH_MODERATE
36}
37
38// ★ONE-CALL ANALYSIS: run the Altman model + the identity check internally, judge with a pre-computed
39// F-score (the caller runs pio_fscore, which itself composes nx_xbrl/nx_edgar for the missing-sentinel).
40// assets/liabilities/equity feed the balance-sheet identity gate.
41func fh_analyze(working_capital: i64, retained_earnings: i64, ebit: i64, mv_equity: i64, total_liabilities: i64, sales: i64, total_assets: i64, f_score: i64, assets: i64, liabilities: i64, equity: i64) -> i64 {
42 let z: i64 = az_zscore(working_capital, retained_earnings, ebit, mv_equity, total_liabilities, sales, total_assets)
43 let zone: i64 = az_zone(z)
44 var balanced: i64 = 0
45 if assets == liabilities + equity { balanced = 1 }
46 return fh_grade(zone, f_score, balanced)
47}
48
49// human label for a verdict.
50func fh_verdict_str(v: i64) -> *u8 {
51 if v == FH_INCOMPLETE { return "INCOMPLETE" as *u8 }
52 if v == FH_FLAGGED { return "FLAGGED" as *u8 }
53 if v == FH_STRONG { return "STRONG" as *u8 }
54 if v == FH_MODERATE { return "MODERATE" as *u8 }
55 return "WEAK" as *u8
56}