nx_bond_lib.nx
buildroot/runtime/nx_bond_lib.nx
about
nx_bond_lib.nx -- FIXED-INCOME VALUATION: bond price, yield-to-maturity, duration. Integer-exact.
The fixed-income companion to nx_dcf_lib (equity intrinsic value). A bond is a stream of coupons plus a
face repayment; its PRICE is the present value of that stream at a discount yield, and its YIELD-TO-MATURITY
is the inverse -- the single rate that makes the PV equal the market price. Together, DCF (equities) + this
(bonds) value both sides of a real portfolio.
NO FLOATS. The discount factor is carried scaled x1e6 and rolled forward one period at a time
(df_t = df_{t-1} * 10000 / (10000 + ytm_bp)); every present value is exact integer arithmetic with defined
downward truncation, identical to nx_dcf_lib. Coupons and yields are basis points (10% -> 1000).
*YTM BY INTEGER BISECTION, NOT NEWTON-RAPHSON. Price is strictly monotone-decreasing in yield, so a
bisection on basis points is exact and cannot diverge -- unlike the float Newton step every mainstream
library uses, which can oscillate or shoot to a garbage root on a bad initial guess. And it is FAIL-CLOSED:
a target price above the zero-yield maximum (would require a negative yield) or below the max-search-yield
floor is REFUSED (BOND_NO_CONVERGE) rather than returning an invented number. A yield you cannot bracket
honestly is not a yield.
SCALE ENVELOPE (declared): face*coupon_bp and cf*df fit i64 for face up to ~9e8 minor units at bp<=1e5.
bisection is O(log(YTM_MAX) * periods). Self-contained (no imports); the df identity is shared with
nx_dcf_lib by design, not by copy of a service. license_tier: ORIGINAL No hw writes (Rule 26). LIB.
dependencies 0 imports · 2 importers
imports: none
imported by: nx_bond_gate.nxnx_finance_svc.nx
structs
| none |
consts
| 23 | const BOND_DF_SCALE: i64 = 1000000 // discount factor carried x1e6 (1.0 = 1000000) |
| 24 | const BOND_BP_FULL: i64 = 10000 // 100% in basis points |
| 25 | const BOND_DUR_SCALE: i64 = 1000 // duration reported in periods x1000 |
| 26 | const BOND_YTM_MAX: i64 = 500000 // upper bisection bound: 5000% -- declared search ceiling |
| 27 | const BOND_BAD: i64 = 0 - 2000000002 // invalid input (price <= 0) |
| 28 | const BOND_NO_CONVERGE: i64 = 0 - 2000000003 // target price unreachable within [0, BOND_YTM_MAX] |
functions
| 33 | func bond_price(coupon_bp: i64, face: i64, periods: i64, ytm_bp: i64) -> i64 |
| 51 | func bond_ytm(price: i64, coupon_bp: i64, face: i64, periods: i64) -> i64 |
| 73 | func bond_macaulay_duration(coupon_bp: i64, face: i64, periods: i64, ytm_bp: i64) -> i64 |
| 93 | func bond_modified_duration(macaulay_x1000: i64, ytm_bp: i64) -> i64 |
| 99 | func bond_current_yield_bp(coupon_bp: i64, face: i64, price: i64) -> i64 called by 1: main |
| 106 | func bond_price_class(price: i64, face: i64) -> *u8 |