Task: Implement G2++ two-factor Gaussian short-rate process
Table of Contents
This page documents a task in the IR curve follow-ups story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Add a working G2++ engine to process_factory with Catch2 tests covering: exact two-factor Gaussian transition, discount_factor() consistency with next(), zero-correlation reduces to two independent Hull-White factors, and bond-price matches QuantLib reference values.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | IR curve follow-ups |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-08-07 |
Acceptance
- G2++ process compiles and passes all tests on Linux
- process_factory::make_yield_curve_process dispatches two_factor_gaussian correctly
- discount_factor() matches QuantLib G2 reference values for a standard parameter set
Plan
(Implementation strategy. Written when work starts; key decisions
are distilled into the parent story's * Decisions at close, but the
plan itself stays — it is the historical record of what we did.)
Notes
Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario, run
through the QA Validation Runner panel) that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
PRs
| PR | Title |
|---|---|
| #1892 | [ores.analytics.quant] Implement G2 (Two-Factor Gaussian) short-rate process |
Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | Degenerate kappa: ou_decay unguarded vs ou_variance guarded — inconsistent for negative kappa | two_factor_gaussian_process.cpp | Accepted | Added kappa >= 0 constructor validation, eliminating the inconsistency |
| 2 | Initial state split: initial_rate in factor_y contradicts docstring's one-factor reduction claim | two_factor_gaussian_process.hpp/cpp, tests | Accepted | Moved initial_rate to factor_x_; updated docstring and all affected tests |
| 3 | "One-factor reduction" test doesn't verify the reduction — uses finite kappa_y, generic bounds | two_factor_gaussian_process_tests.cpp | Accepted | Rewrote: large kappa_y with sigma_y=0, statistical equivalence to HW |
| 4 | QuantLib V() never tested with non-zero vol — transcription bug wouldn't be caught | two_factor_gaussian_process_tests.cpp | Accepted | Added V(t) positivity and monotonicity test with non-zero vol |
| 5 | Loop-invariant recomputation in discount_factor() | two_factor_gaussian_process.cpp | Accepted | Hoisted decay_x/y, var_x/y, cov_xy outside the loop |
Result
Implemented two_factor_gaussian_process: a two-factor Gaussian short-rate engine
with correlated Ornstein-Uhlenbeck factors. 21 Catch2 tests covering
parameter validation, deterministic and statistical behaviour, discrete
recursion exact match, continuous-limit convergence, QuantLib G2
closed-form cross-check (A, B, V functions), one-factor reduction, and
loop-invariant hoisting. Registered in component_files.cmake.
All 251 ores.analytics.quant tests pass on Linux. Not yet wired into
process_factory (deferred to PR 2: system infra wiring).