Tier 2 · Internal Risk Management

Interest Rate & FX Derivative Pricing — Multi-Curve / Hull-White / Black-Bachelier / SABR Family

M-132 · lifecycle: monitoring · RAT-132-v1.0.1

Intended Use

Interest Rate & FX Derivative Pricing — Multi-Curve / Hull-White / Black-Bachelier / SABR Family Price interest rate and FX derivatives (IRS, swaptions, caps/floors, FX forwards, cross-currency swaps, FRAs, inflation swaps) for ALM and hedge program valuation.

Family-level model covering interest rate derivative pricing under a multi-curve framework (separate discount and projection curves). Optionality is priced by SABR-fed Black-76 (lognormal) / Bachelier (normal) market models; SABR (Hagan) supplies the smile-consistent implied vol that feeds the swaption/rate-option pricers. Inflation swaps use real vs nominal curve decomposition. FX derivatives use covered interest rate parity and cross-currency basis. Implementations: 7 FinView L1 + 4 Gold Copy L1 challengers. (Name corrected per RAT-132-v1.0.0 COND-001, 2026-06-06: at that time no Hull-White short-rate engine was implemented. RAT-132-v1.0.1 build (INV-006, Decision 053 1L #2434, 2026-06-08): a real Hull-White 1-factor short-rate engine `finview.L1.hull_white_1f` was built — no-arbitrage term-structure model calibrated to the canonical curve by construction (exact A/B affine refit), with analytic ZCB-option / Jamshidian-swaption pricing and a HW-vs-Bachelier challenger lane — so "Hull-White" is restored to the family name. The engine's a/sigma vol params are exogenous/uncalibrated; its OPTION outputs are non-production until calibration lands, the curve/bond analytics are production. See production_scope.)


Components

Inputs, processing, outputs

data sources
DS-001 · DS-002 · DS-003 · DS-005 · DS-013 · DS-031 · DS-058
assumptions
A-050, A-051, A-052, A-053, A-054, A-284, A-285
engines
finview.L1.irs_pricer
finview.L1.hull_white_1f
finview.L1.swaption_pricer
finview.L1.rate_option_pricer
finview.L1.inflation_swap_pricer
finview.L1.fx_forward_pricer
finview.L1.xccy_swap_pricer
goldcopy.L1.swap_pricer
goldcopy.L1.swaption_pricer
goldcopy.L1.fra_pricer
goldcopy.L1.fx_swap_pricer
contracts
ir_fx_derivative_pricing_v1
upstream
M-136 · M-137
dimensions
D2 · D4

Model Documentation

Production Scope (RAT-132-v1.0.0 COND-002 — read first)

Not all members are production-ready. The optionality and cross-currency members rest on uncalibrated placeholder inputs (A-054 FX correlation is default-zero; DS-058 swaption-vol / FX-basis source is planned, with the strike-grid swaption IV history a structural paid-only gap — CME DataMine barred by DR-007). Per Decision 053 §4 these inputs are not fabricated; instead the affected members are scoped non-production until calibration lands.

Member Status Why
finview.L1.irs_pricer (IRS) production Multi-curve; no FX-corr / vol-surface dependence
finview.L1.inflation_swap_pricer production Real/nominal curve decomposition
finview.L1.fx_forward_pricer (FX fwd) production Covered-interest parity point estimate (no A-054 dependence)
finview.L0.curve_builder (curve spine) production Bootstrap / multi-curve construction
finview.L1.hull_white_1f (HW 1F bond/curve analytics) production Calibrated to the canonical curve by construction (exact A/B affine refit); independent of a,σ
finview.L1.hull_white_1f (HW 1F option outputs) non-production (under_development) a (A-284) / σ (A-285) exogenous & uncalibrated; DS-058 strike-grid IV is the DR-007 paid-only gap
finview.L1.swaption_pricer non-production (under_development) Uncalibrated vol surface (DS-058 planned)
finview.L1.rate_option_pricer (caps/floors) non-production (under_development) Same uncalibrated vol surface (DS-058 planned)
finview.L1.xccy_swap_pricer (xccy) non-production (under_development) Depends on A-054 FX correlation, currently default-zero

The non-production members re-promote via 2L re-review once A-054 is calibrated and/or DS-058 is sourced (tracked under PL-07 / WS3). The mirror of this table lives in model_registry.yaml::M-132.production_scope. The swaption snapshot below is retained as an illustrative (non-production) example, clearly labelled.


Methodology & Mechanics

Methodology

M-132 is the interest-rate and FX derivative pricing family (Tier 2). It prices linear rate products, cross-currency products, FX forwards, and the optionality layered on top of them. The family is FinView-resident: every engine lives under finview.L0/finview.L1 in [redacted], and there is no InsModel-side implementation — the InsModel virtual-env merely re-runs the same FinView source (confirmed reproducible below).

Multi-curve discounting (the foundation)

All members share one discounting spine. Curves are bootstrapped from par instruments by finview.L0.curve_builder (finlib/curve_builder.py::bootstrap_sofr_curve and build_sofr_curve):

  • Maturities ≤ 1Y are stripped as simple money-market instruments (df = 1 / (1 + cT)); maturities > 1Y are stripped by sequential semi-annual coupon bootstrapping, treating each input as a par rate.
  • Zero rates are continuously compounded (z = -ln(df)/T); inter-tenor forward rates are computed from adjacent discount-factor ratios.
  • Interpolation is log-linear on discount factors by default, with an optional PCHIP (monotone cubic Hermite) mode that produces smooth, non-oscillating forwards (_interpolate_df, interpolate_curve).

The multi-curve framework proper is the CurveSet dataclass (finview.L0.curve_set): it holds separate Treasury, OIS/SOFR discount, and SOFR projection curves plus rating-keyed credit-spread curves, with graceful fallback to the Treasury curve when a discount or projection curve is absent (has_multi_curve, get_discount_dfs, get_projection_fwds). This is the OIS-discounting / forward-projection separation that post-LIBOR rate pricing requires: the float leg is projected off the projection curve while cashflows are discounted off the OIS curve.

Family members (engines)

Engine File Product Key outputs
finview.L1.irs_pricer derivatives/irs_pricer.py Vanilla fixed-vs-float IRS fair_value, fixed/float leg PV, dv01, key_rate_dv01
finview.L1.hull_white_1f derivatives/hull_white_1f.py Hull-White 1F short-rate term-structure instantaneous_forward, zero_bond_price, caplet/floorlet, swaption (Jamshidian), theta_implied
finview.L1.swaption_pricer derivatives/swaption_pricer.py European swaption premium, forward_swap_rate, annuity, delta, vega
finview.L1.rate_option_pricer derivatives/rate_option_pricer.py Caps/floors/rate options premium, delta, gamma, vega, theta
finview.L1.inflation_swap_pricer derivatives/inflation_swap_pricer.py Zero-coupon/year-on-year inflation swap fair_value, breakeven_rate, real/nominal dv01
finview.L1.fx_forward_pricer derivatives/fx_forward_pricer.py FX forward (covered-interest parity) fair_value, fair_forward, dv01_domestic/foreign
finview.L1.xccy_swap_pricer derivatives/xccy_swap_pricer.py Cross-currency basis swap npv, domestic/foreign leg PV, fx_delta, dv01
finview.L0.curve_builder / curve_set curve_builder.py Multi-curve construction discount/zero/forward arrays, CurveSet
finview.L?.vol_surface (SABR/SVI) vol_surface.py Vol surface for optionality sabr_implied_vol, calibrate_sabr, SABRSurface

Gold-copy challengers exist for the derivative engines (finlib/gold_test_derivatives.py, finlib/gold_test_derivatives frozen reference values, e.g. CME_ERIS_10Y) and provide an independent cross-check lane for the IRS/futures math.

Representative pricer in detail — vanilla IRS (IRSPricer)

The cleanest-running, most load-bearing member is the vanilla interest-rate swap, so it is the snapshot exemplar. IRSPricer.compute_fair_value:

  1. Builds the semi-annual payment grid to maturity (_payment_times).
  2. Discounts each payment time off the input curve, re-deriving zero rates from the discount factors and re-interpolating (_discount_at).
  3. Fixed leg PV = N · c · Δt · Σ df(tᵢ).
  4. Float leg PV = N · Δt · Σ fwd(tᵢ) · df(tᵢ) when a projection forward curve is supplied (the multi-curve path); otherwise it collapses to the single-curve par identity N · (1 − df_last).
  5. DV01 is computed by full reprice under a parallel +1bp bump of zero and forward rates (_compute_dv01) — a genuine bump-and-reprice, not a closed-form approximation.
  6. Key-rate DV01 bumps each of the {1,2,5,10,20,30}Y buckets with a triangular weighting kernel (_compute_key_rate_dv01, _triangle_weight) and reprices, giving the bucketed rate exposure.

The par swap rate and the annuity are emitted directly by compute_fair_value. The engine builds the annuity as Δt · Σ df(tᵢ) and the par rate as float_leg_pv / (N · annuity) — the rate that zeroes the swap — and returns both, exposing par_rate, its consumer-facing alias par_swap_rate, and annuity in the result dict (irs_pricer.py lines 18, 86–95, sha 22d4662, FinView #92, 2026-06-04). The snapshot reads these straight from the engine output rather than re-deriving them; the contract's declared outputs and the returned dict now agree.

Hull-White / SABR for optionality

Optionality is priced two ways in-repo:

  • SwaptionPricer computes the forward par swap rate and the annuity off the curve, then applies either Black-76 (lognormal) or Bachelier (normal) to the forward, returning premium, delta and vega. This is the standard market-model swaption, reusing the swap annuity rather than re-deriving swap math.
  • SABR (Hagan's approximation) lives in vol_surface.py (sabr_implied_vol(F, K, T, alpha, beta, rho, nu), calibrate_sabr, SABRSurface). It produces the smile-consistent implied vol at a given strike that would feed the Black/Bachelier swaption — i.e. SABR supplies the vol surface, the swaption pricer consumes it. The snapshot shows the ATM SABR lognormal vol alongside the Bachelier-priced swaption to make the surface→pricer handoff explicit.
  • Hull-White 1-factor short-rate engine (finview.L1.hull_white_1f, derivatives/hull_white_1f.py, INV-006 1L build #2434, 2026-06-08) models the short rate as dr = [θ(t) − a·r] dt + σ dW. The time-dependent drift θ(t) is implied by the exact A(t,T)/B(t,T) affine reconstruction so that P_hw(0,T) ≡ P_market(0,T) by construction — i.e. the model is calibrated to the canonical curve by identity, making it a genuine no-arbitrage term-structure model rather than a comment reference. It derives the instantaneous forward f(0,t) = −d/dt ln P(0,t) analytically from the pchip log-DF interpolant (NOT curve_builder's discrete simple forward_rates[] — the forward-curve fix mandated by the 1L design review). It prices a European ZCB option analytically (HW bond-option formula), hence caplets/floorlets, and a European swaption via the Jamshidian (1989) decomposition (solve for r* that makes the coupon bond hit the strike; decompose into a portfolio of ZCB options). The analytic prices are independently verified against an exact-transition Monte-Carlo simulator in the test suite. The HW analytic swaption is cross-checked against the existing Bachelier swaption — the family's first genuine cross-model challenger lane for optionality (documented soft, non-gated tolerance because a,σ are uncalibrated). a (A-284) and σ (A-285) are exogenous, caller-supplied, uncalibrated inputs (literature-typical defaults a=0.03, σ=0.01); the bond/curve analytics are exact (production) and the option outputs are non-production until calibration lands (DS-058 strike-grid swaption IV is the paid-only DR-007 gap). See Limitations 1 and the Production Scope table.

Key Assumptions

Key Assumptions and Their Justification

Assumption Value / choice Where Justification
Discount curve SOFR/OIS bootstrap from par yields bootstrap_sofr_curve Post-LIBOR OIS discounting is the market standard for collateralised rate books.
Projection curve SOFR forward curve, separable from discount CurveSet.get_projection_fwds Multi-curve separation of projection vs discount is mandatory post-2008/post-LIBOR.
Compounding Continuous (z = -ln(df)/T) curve_builder.py Internally consistent, convention-free; converted to discrete only at leg level.
Coupon frequency Semi-annual fixed and float IRSPricer(payment_frequency=2) USD swap-market convention for fixed legs; matches the bootstrap grid.
Interpolation Log-linear on DFs (PCHIP optional) _interpolate_df, interpolate_curve Log-linear keeps forwards positive; PCHIP available where smooth forwards matter.
Day-count Uniform act/act assumed (Δt = 1/freq) _payment_times Stated simplification in the curve_builder governance docstring; see Limitation 2.
Swaption vol model Bachelier (normal) default, Black-76 optional SwaptionPricer(vol_type=...) Normal vols dominate the low/negative-rate swaption market; lognormal available.
Smile model SABR β = 0.5 (CEV), Hagan approx sabr_implied_vol, calibrate_sabr β = 0.5 is the standard rates default; Hagan is the industry closed-form smile.
DV01 / KR-DV01 Full bump-and-reprice, ±1bp, triangular KR weights _compute_dv01, _compute_key_rate_dv01 Reprice-based risk is exact for the model; triangular KR kernel is the desk standard.

Prose. The discounting assumptions are the post-LIBOR consensus: OIS/SOFR discounting with a separable projection curve. The two material modelling choices a validator should scrutinise are (a) the uniform day-count shortcut (Δt = 1/frequency rather than true accrual fractions), which the curve_builder docstring itself flags, and (b) the absence of a convexity adjustment for any futures-derived calibration point. Neither is hidden; both are documented in code and carried into Limitations. The vol assumptions (Bachelier default + SABR β=0.5) are deliberately the low-rate-regime defaults, which is correct for a USD swaption book.


Output Snapshot

Output Snapshot

Run via python scripts/model_snapshots.py M-132. The snap_M_132() provider resides in InsModel (ecosystem/InsModel/Models/scripts/model_snapshots.py) and path-inserts FinView ([redacted]) before importing the finlib engines — the model is FinView-resident but the snapshot harness is InsModel-side (BV-032 cross-repo pattern). It re-runs IRSPricer and SwaptionPricer against a frozen par curve. The IRS/swaption/curve engines are regression-asserted by tests/test_irs_pricer.py, tests/test_swaption_pricer.py, and tests/test_curve_builder.py (34 passed at capture).

Instrument: 5-year pay-fixed vanilla IRS, $10,000,000 notional, semi-annual, fixed at 4.50% (deliberately off-market) on a frozen upward-sloping SOFR/Treasury par curve (4.30% → 4.45% across 3M→30Y).

output value meaning
npv / fair_value -$212,990.86 pay-fixed @4.50% is out-of-the-money vs ~4.03% market → negative MV
fixed_leg_pv $2,020,142.05 PV of the 4.50% fixed coupons
float_leg_pv $1,807,151.19 PV of the projected SOFR float coupons
par_swap_rate 4.0255% fixed rate that zeroes the swap; emitted directly by the engine (par_swap_rate alias of par_rate)
dv01 (parallel +1bp) $4,544.54 MV change per 1bp parallel curve shift (bump-and-reprice)
key_rate_dv01 [1Y / 2Y / 5Y] $964.88 / $1,823.46 / $1,511.33 bucketed exposure; mass concentrated at 2Y–5Y as expected for a 5Y swap
swaption 1Yx5Y payer, K=4.00% optionality layer (Bachelier, 75bp normal vol)
forward_swap_rate 4.0071% forward par rate of the 5Y swap starting in 1Y
annuity (per $1) 4.315015 PV of $1/period over the underlying 5Y tenor
premium $130,650.91 swaption premium
delta / vega 2.1739 / $17,213,642.22 annuity-scaled forward delta; vega per 100% vol
sabr_atm_lognormal_vol (illustrative) 7.5898% SABR(α=1.5%,β=0.5,ρ=-0.25,ν=0.40) ATM vol that would feed Black-76

Prose. The signs and magnitudes are internally coherent: an off-market pay-fixed swap struck ~47bp above the 4.03% par rate carries a negative MV of roughly -$213k, which is close to DV01 × (4.50% − 4.0255%) × 10000 ≈ $4,545 × 47.45 ≈ -$215k, i.e. the NPV reconciles with the reported DV01 to within bootstrap/interpolation curvature. The key-rate DV01 correctly places exposure in the 2Y–5Y buckets and zero beyond 10Y (a 5Y swap has no 10Y+ sensitivity). The swaption's forward par rate (4.0071%) matches the spot par rate to a few bp, as expected on a gently-sloped curve, and the premium is consistent with a near-ATM 1Yx5Y payer at 75bp normal vol. The SABR ATM vol is shown as an illustrative surface input — it parametrises the smile that would supply the Black-76 vol, not a calibrated production surface.

Captured 2026-06-04 · deterministic, no live data.


Limitations

Limitations and Known Gaps

  1. Hull-White 1F is implemented but its vol parameters are uncalibrated (INV-006, 2026-06-08). A real Hull-White 1-factor short-rate engine (finview.L1.hull_white_1f) is now built and bound to M-132 (resolving the prior "not implemented" gap). It is calibrated to the canonical curve by construction (exact A/B refit; the curve/bond analytics are production), but its mean-reversion a (A-284) and short-rate vol σ (A-285) are exogenous, caller-supplied, and NOT calibrated to market swaption vols — the DS-058 strike-grid swaption IV history is the structural paid-only DR-007 gap (CME DataMine barred). Per Decision 053 §4 these are explicit documented inputs, not default-zero fabrication. Consequently the engine's option outputs are scoped non-production (illustrative until a,σ calibration lands; same honest pattern as the swaption member), while the bond/curve analytics are exact. The HW-vs-Bachelier swaption cross-check is therefore a soft, non-gated sanity/challenger lane, not a pass/fail on absolute price. Single-factor HW cannot fit the full vol surface/smile (that stays SABR's job) and is Gaussian (admits negative rates — acceptable for the post-LIBOR USD regime, consistent with the family's Bachelier default). Multi-curve basis inside HW is out of scope for v1 (uses the single discount curve). Genuinely multi-factor / Bermudan-callable term-structure needs remain future work.
  2. Uniform day-count. Accrual fractions are taken as 1/frequency rather than true act/360, act/365, or 30/360 day-count fractions. The curve_builder governance docstring states this ("uniform day-count convention (actual/actual assumed)"). It introduces small accrual bias on stub and broken-dated trades.
  3. No convexity adjustment. The curve builder applies no convexity adjustment for any futures-based calibration input (also stated in the curve_builder docstring). Futures-strip calibration would be biased at the long end without it.
  4. Par rate / annuity engine emission — RESOLVED (2026-06-04). Previously IRSPricer.compute_fair_value did not return par_rate/annuity despite their appearing in the ENGINE_CONTRACT outputs list, so the snapshot re-derived them. This contract/implementation mismatch was resolved by FinView #92 (sha 22d4662): compute_fair_value now returns par_rate, the par_swap_rate alias, and annuity directly (irs_pricer.py lines 18, 86–95), and the snapshot reads them from the engine output. No open gap.
  5. SABR surface is illustrative, not calibrated end-to-end in the pricer. sabr_implied_vol produces a smile-consistent vol, and calibrate_sabr can fit (α, ρ, ν), but SwaptionPricer takes a scalar vol input — it does not yet pull a strike-specific vol from a calibrated SABRSurface automatically. The surface→pricer wiring is manual.
  6. Single-curve fallback is silent. When no projection/discount curve is supplied, IRSPricer collapses the float leg to the par identity N·(1−df_last) and CurveSet falls back to the Treasury curve without warning. This is convenient but can mask a missing-curve configuration.
  7. Cross-repo / FinView-resident. This model is grounded entirely in FinView Python; there are no 10-K-derived inputs and no InsModel-side engine. The InsModel venv reproduces the numbers only because it imports the same FinView source. Governance treats this under BV-032 (cross-repo FinView-resident model) — the card is descriptive of in-repo code, not of a productionised market-data pipeline.

Ratification status (RAT-132-v1.0.0 remediation, 2026-06-06). - INV-006 / COND-001 — CLOSED (doc-correction). "Hull-White" was dropped from the registry name + description and this card title + description; the declared methodology now matches the implemented SABR-fed Black-76/Bachelier code. The short-rate-engine alternative was not built (would be re-submitted for re-review if it is). See Limitation 1 and the Name-correction callout. - COND-002 — CLOSED (honest scoping). A-054 (FX correlation, default-zero) and DS-058 (swaption vols + FX basis, planned; strike-grid IV is the paid-only DR-007 gap) are not fabricated. The placeholder-dependent members (swaption, rate-option, xccy) are scoped non-production — see the Production Scope table at the top and model_registry.yaml::M-132.production_scope. Calibrating A-054 / sourcing DS-058 stays an honest pending build (PL-07 / WS3). - Validation evidence — Tier-2 pack assembled at modelling/validation_evidence/M-132/v1.0.0/README.md (real tests + reconciliation + gold-copy challenger lane; honest gaps preserved). The (T1) full pack is not required at Tier-2 (charter §4.2). - INV-032 — still tracked (non-gating, LG-132-03): FinView-resident model consumed by InsModel via sys.path insertion; no packaged interface / cross-repo drift gate.


Validation Evidence

Validation Packet

Check Evidence Status
Par-swap FV ≈ 0 at inception test_irs_pricer.py::test_par_swap_fv_near_zero pass
Pay/receive direction symmetry test_irs_pricer.py::test_direction_symmetry pass
DV01 strictly positive test_irs_pricer.py::test_dv01_positive pass
Key-rate DV01 concentrates at swap tenor test_irs_pricer.py::test_key_rate_concentration pass
Off-market swap has non-zero FV (correct sign) test_irs_pricer.py::test_off_market_swap_has_nonzero_fv pass
Result-key contract present test_irs_pricer.py::test_result_keys pass
Swaption pricer suite tests/test_swaption_pricer.py pass
Curve bootstrap suite tests/test_curve_builder.py pass
HW exact curve refit (P_hw(0,T)=DF) test_hull_white_1f.py::test_exact_curve_refit pass
HW f(0,t) integrates back to curve test_hull_white_1f.py::test_instantaneous_forward_matches_curve pass
HW B(t,T) limits / monotonicity test_hull_white_1f.py::test_B_function_limits pass
HW caplet analytic vs exact-MC test_hull_white_1f.py::test_caplet_analytic_vs_montecarlo pass
HW Jamshidian swaption vs exact-MC test_hull_white_1f.py::test_swaption_jamshidian_vs_montecarlo pass
HW ZCB-option put-call parity test_hull_white_1f.py::test_put_call_parity_zcb_option pass
HW premium monotone in σ test_hull_white_1f.py::test_vol_monotonicity pass
HW σ→0 collapses to intrinsic test_hull_white_1f.py::test_zero_vol_intrinsic pass
HW-vs-Bachelier challenger (soft) test_hull_white_1f.py::test_hw_vs_bachelier_swaption_crosscheck pass
HW ENGINE_CONTRACT outputs present test_hull_white_1f.py::test_engine_contract_outputs_present pass
HW consumes curve, not discrete fwds test_hull_white_1f.py::test_consumes_curvebuilder_not_discrete_forwards pass
HW engine binding / market_data test_hull_white_1f.py::test_engine_binding_and_market_data pass
NPV ↔ DV01 reconciliation snapshot: -$212,990.86 ≈ DV01 $4,544.54 × 47.45bp consistent
Gold-copy challenger cross-check finlib/gold_test_derivatives.py (e.g. CME_ERIS_10Y) available
Cross-venv reproducibility identical output under FinView .venv and InsModel Models/.venv confirmed
Suite total at capture 34 passed (irs + swaption + curve) pass

Gaps relative to a full Tier-2 packet: no calibrated production vol surface, no HW short-rate validation, no day-count/convexity sensitivity tests. These trace directly to Limitations 1–3 and 5.


References

References

Multi-curve / OIS discounting: - Henrard, M. (2014). Interest Rate Modelling in the Multi-Curve Framework. - Bianchetti, M. (2010). "Two Curves, One Price." - Mercurio, F. (2009). "Interest Rates and the Credit Crunch: New Formulas and Market Models." (post-LIBOR projection vs discount separation)

SABR / smile: - Hagan, P., Kumar, D., Lesniewski, A., Woodward, D. (2002). "Managing Smile Risk." Wilmott — the SABR approximation implemented in vol_surface.py::sabr_implied_vol / calibrate_sabr. - Obłój, J. (2008). "Fine-tune your smile: correction to Hagan et al."

Hull-White / short-rate (implemented — finview.L1.hull_white_1f, INV-006 2026-06-08): - Hull, J. & White, A. (1990). "Pricing Interest-Rate Derivative Securities." - Brigo, D. & Mercurio, F. (2006). Interest Rate Models — Theory and Practice, ch. 3 (Hull-White affine bond/option formulas, §3.11 Jamshidian). - Jamshidian, F. (1989). "An Exact Bond Option Formula." J. Finance — the coupon-bond-option decomposition used for the analytic HW swaption. - Glasserman, P. (2004). Monte Carlo Methods in Financial Engineering — exact Gaussian short-rate transition (test-only independent estimator).

Engine files (FinView-resident): - finlib/curve_builder.pybootstrap_sofr_curve, build_sofr_curve, CurveSet (finview.L0.curve_builder / curve_set / interpolation). - finlib/derivatives/irs_pricer.pyIRSPricer (finview.L1.irs_pricer). - finlib/derivatives/swaption_pricer.pySwaptionPricer (finview.L1.swaption_pricer). - finlib/derivatives/rate_option_pricer.py, inflation_swap_pricer.py, fx_forward_pricer.py, xccy_swap_pricer.py — remaining family members. - finlib/vol_surface.py — SABR (sabr_implied_vol, calibrate_sabr, SABRSurface) and SVI. - finlib/gold_test_derivatives.py — gold-copy challenger reference values.

Tests: - tests/test_irs_pricer.py, tests/test_swaption_pricer.py, tests/test_curve_builder.py, tests/test_fx_forward_pricer.py, tests/test_inflation_swap_pricer.py, tests/test_rate_option_pricer.py, tests/test_gold_derivatives.py, tests/test_hull_white_1f.py (the 12 HW acceptance tests — INV-006).

Internal: - BV-032 — cross-repo FinView-resident model boundary (no 10-K inputs; FinView Python is the source of truth for this card).


Change Log

Change Log

Card change history. Code-side change history lives in git log of the component files.

  • 2026-06-08 (INV-006 — Hull-White 1F engine built, Decision 053 1L build #2434). Took the alternative the RAT-132-v1.0.0 COND-001 remediation explicitly left open: built a real Hull-White 1-factor short-rate engine (finview.L1.hull_white_1f, finlib/derivatives/hull_white_1f.py) and bound it to M-132. The engine is calibrated to the canonical curve_builder discount curve by construction (exact A/B affine refit; instantaneous forward f(0,t) derived analytically from the pchip log-DF interpolant — the forward-curve fix mandated by the 1L design review, NOT the discrete forward_rates[]), with analytic ZCB-option / caplet-floorlet pricing, a European swaption via Jamshidian decomposition, and a test-only exact-transition Monte-Carlo cross-checker. Added the HW-vs-Bachelier swaption challenger lane (soft, non-gated). 12 real deterministic tests (tests/test_hull_white_1f.py) all pass. Restored "Hull-White" to the family name (registry + this card title/description); rewrote the Methodology HW bullet and replaced Limitation 1 ("not implemented" → "implemented, vol params uncalibrated"). Registered the engine (engine_registry.yaml, total_engines 131→132) and A-284 (mean-reversion a) / A-285 (short-rate σ) as exogenous/uncalibrated assumptions (NOT default-zero fabrication; per Decision 053 §4). Production scope: HW bond/curve analytics are production, HW option outputs are non-production until a,σ are calibrated (DS-058 strike-grid IV is the DR-007 paid-only gap) — mirror in model_registry.yaml::M-132.production_scope. Tier-2 evidence pack at validation_evidence/M-132/v1.0.1/. Regenerated the FinView binding manifest. No engine outputs, back-test numbers, or validation results were fabricated. Prepared for 2L re-review (RAT-132-v1.0.1); 1L did not edit the RAT record or the 2L workspace.
  • 2026-05-08 — stub created from registry data per Decision 023 Phase 5 / B-07.
  • 2026-06-06 (1L remediation, RAT-132-v1.0.0 COND-001 + COND-002) — Remediated the two gating conditions under the Decision 053 1L charter §2.2 (no engine outputs, back-test numbers, or validation results fabricated). COND-001 (doc): dropped the unimplemented "Hull-White" from the model name
  • description (registry + this card) — now "Multi-Curve / Black-Bachelier / SABR"; added the Name-correction callout. COND-002 (doc/scoping): split the family into a production linear-IR core and non-production placeholder-dependent members (swaption / rate-option / xccy) via a Production Scope table here and model_registry.yaml::M-132.production_scope; A-054 / DS-058 calibration is left as an honest pending build (PL-07 / WS3), not fabricated. LG-132-01 (doc): reconciled documentation_pack flags (model_card + change_log → present; validation_evidence → present, pack assembled). Assembled the Tier-2 validation-evidence pack at validation_evidence/M-132/v1.0.0/. Re-stamped doc-currency. Prepared for 2L re-review; 1L did not edit the RAT record or the 2L workspace.
  • 2026-06-06 — 2L code-grounded documentation refresh against irs_pricer.py (sha 22d4662) + sofr_futures_pricer.py + the InsModel snapshot harness. Reconciled par_rate / par_swap_rate / annuity to engine emission (FinView #92, 2026-06-04): rewrote the Representative-pricer paragraph and the Output-Snapshot prose to read these from engine output rather than re-deriving, and converted Limitation 4 to a RESOLVED note. Added the Standards Coverage section (framework-level ASOP 56 / SR 26-2; no numbered standard prescribes the IR/FX pricing math). Tightened the Hull-White wording in Methodology and Limitation 1 to "no HW short-rate engine/class is implemented (grep finds only a comment reference in sofr_futures_pricer.py)". Corrected the snapshot-provider note: snap_M_132 resides in InsModel Models/scripts/model_snapshots.py and path-inserts FinView. Noted gated/ratification items (INV-006, Tier-2 validation evidence, A-054 / DS-058, INV-032) under Limitations. Non-output-changing: no model outputs, back-test numbers, or validation results were fabricated or changed.

2L Inventory Review

Open findings (2)

Independent 2nd-line review (INV-2026-06) — implemented capability vs registered scope. Each carries a recommended fix and is tracked in insightalm-mrm until closed.

HIGH INV-029 · P5 · validation-gap

Validation evidence + change logs missing across most of the inventory

Only M-001/M-020/M-050 carried full documentation packs before this pass. Most models record validation_evidence: missing and change_log: missing with peer_review: pending. Gold tests freeze behaviour but many assert only structural invariants (e.g. reserve>0), not correctness against external truth. The flagship T0-vs-10-K match is circular (BV-032).

Recommendation: For each Tier-1 model: produce a validation-evidence pack (back-test vs disclosed results once BV-032 re-calibration lands, sensitivity suite, challenger comparison), a change log, and a 2L ratification. Sequence behind BV-032 (firm-data) for anything needing 10-K reconciliation.

LOW INV-032 · cross-repo · cross-repo

FinView-resident pricing/CECL engines reached cross-repo with no drift gate

M-040 (CECL) and M-130-137 (asset pricing) are FinView-resident, consumed by InsModel only via sys.path insertion. No packaged interface or drift gate — a finlib signature change silently breaks the InsModel snapshot harness / consumers.

Recommendation: Define a packaged interface (or a versioned contract) for the FinView pricing library and a CI drift gate, so cross-repo consumers fail loudly on signature change. Tie to D041 ownership.


Validation Coverage

Per-tier expectations

Per MRM Framework §10.2 + §10.3, this model's regulatory_frameworks tag list activates the following overlays:

asop_56 sr_26_2 internal
component tier-2 expectation status
Registry entry required present
Model card (§10.5 doc pack) required present
Validation evidence required present
Change log required present
Independent effective challenge (2L) required attested

Ratification

Ratified — RAT-132-v1.0.1

Latest ratification on file: RAT-132-v1.0.1. Authored by 2L (mrm-peer-reviewer) per Decision 028 charter §5 Pattern A.