code wiki / (root) / nx_dcf_lib.nx

nx_dcf_lib.nx source

↩ module page · 84 lines · 3971 B

1// nx_dcf_lib.nx -- DISCOUNTED CASH FLOW: intrinsic valuation + margin of safety, integer-exact. 2// 3// The operator's "projections -> intrinsic value vs price" ask. This is Graham/Buffett value math: project 4// a firm's free cash flows, discount them (and a terminal value) back to today at the required return, sum 5// to an INTRINSIC value, and compare to the market PRICE with a margin of safety. A stock is a buy only 6// when intrinsic exceeds price by a real margin -- price is what you pay, value is what you get. 7// 8// NO FLOATS: the discount factor is carried scaled x1e6 and rolled forward one period at a time 9// (df_t = df_{t-1} * 10000 / (10000 + rate_bp)); every present value is exact integer arithmetic with 10// defined truncation. Rates and growth are basis points (10% -> 1000). 11// 12// ★FAIL-CLOSED ON THE DCF TRAP: the Gordon terminal value final*(1+g)/(r-g) EXPLODES to nonsense when 13// growth >= discount rate (division by <=0). Analysts produce absurd trillion-dollar valuations exactly 14// this way. dcf_terminal REFUSES (DCF_UNDEFINED) rather than emitting a garbage number. A valuation you 15// cannot compute honestly is not a valuation. 16// 17// SCALE ENVELOPE (declared): cashflow * df fits i64 for cashflows up to ~9e12 units at df~1e6. DRY: 18// composes nx_matter_lib helpers. license_tier: ORIGINAL No hw writes (Rule 26). LIB. 19 20import "nx_matter_lib.nx" 21const DCF_MAGIC_1500: i64 = 1500 22 23const DCF_DF_SCALE: i64 = 1000000 // discount factor carried x1e6 (1.0 = 1000000) 24const DCF_BP_FULL: i64 = 10000 // 100% in basis points 25const DCF_UNDEFINED: i64 = 0 - 2000000001 // terminal value undefined (growth >= rate) 26const DCF_BAD: i64 = 0 - 2000000002 // invalid input (e.g. price <= 0) 27 28// discount factor for `period` at `rate_bp`, scaled x1e6. period 0 -> 1.0 (1000000). 29func dcf_discount_factor(rate_bp: i64, period: i64) -> i64 { 30 var df: i64 = DCF_DF_SCALE 31 var t: i64 = 0 32 while t < period { 33 df = df * DCF_BP_FULL / (DCF_BP_FULL + rate_bp) 34 t = t + 1 35 } 36 return df 37} 38 39// present value of a single cashflow `period` years out at `rate_bp`. 40func dcf_pv(cashflow: i64, rate_bp: i64, period: i64) -> i64 { 41 return cashflow * dcf_discount_factor(rate_bp, period) / DCF_DF_SCALE 42} 43 44// ★Gordon-growth terminal value: final_cf * (1+g) / (r-g). DCF_UNDEFINED if r <= g (the trap). 45func dcf_terminal(final_cf: i64, growth_bp: i64, rate_bp: i64) -> i64 { 46 if rate_bp <= growth_bp { return DCF_UNDEFINED } 47 return final_cf * (DCF_BP_FULL + growth_bp) / (rate_bp - growth_bp) 48} 49 50// ★INTRINSIC VALUE: PV of each projected cashflow (cashflows[0] is period 1) + PV of the terminal value 51// received at the end of period n. Returns DCF_UNDEFINED if the terminal is undefined (propagates the trap). 52func dcf_intrinsic(cashflows: *i64, n: i64, rate_bp: i64, terminal_value: i64) -> i64 { 53 if terminal_value == DCF_UNDEFINED { return DCF_UNDEFINED } 54 var total: i64 = 0 55 var t: i64 = 0 56 while t < n { 57 total = total + dcf_pv(cashflows[t], rate_bp, t + 1) 58 t = t + 1 59 } 60 total = total + dcf_pv(terminal_value, rate_bp, n) 61 return total 62} 63 64// margin of safety in basis points: (intrinsic - price)/price. positive = undervalued. 65func dcf_margin_of_safety_bp(intrinsic: i64, price: i64) -> i64 { 66 if price <= 0 { return DCF_BAD } 67 return (intrinsic - price) * DCF_BP_FULL / price 68} 69 70// ★verdict: 1 UNDERVALUED (>15% margin), 0 FAIRLY-VALUED, -1 OVERVALUED (>15% below), DCF_BAD on bad price. 71func dcf_verdict(intrinsic: i64, price: i64) -> i64 { 72 if price <= 0 { return DCF_BAD } 73 let m: i64 = (intrinsic - price) * DCF_BP_FULL / price 74 if m > DCF_MAGIC_1500 { return 1 } 75 if m < 0 - DCF_MAGIC_1500 { return 0 - 1 } 76 return 0 77} 78 79func dcf_verdict_str(v: i64) -> *u8 { 80 if v == DCF_BAD { return "BAD-INPUT" as *u8 } 81 if v == 1 { return "UNDERVALUED" as *u8 } 82 if v == 0 - 1 { return "OVERVALUED" as *u8 } 83 return "FAIRLY-VALUED" as *u8 84}