Gnanam QuanTech

Model · in development · Apache-2.0

Gnanam ESG

What it is

Gnanam ESG is an open-source economic scenario generator for actuaries and quantitative risk professionals. It produces Monte Carlo scenario sets across three risk families — interest rates (Hull–White one- and two-factor), equity (GBM, Heston, jump-diffusion), and credit (Merton structural, Jarrow–Turnbull reduced-form) — plus a portfolio layer that simulates one model per family jointly off a single cross-correlated master draw. Every model runs under the risk-neutral measure and also produces a real-world (P-measure) projection of the same paths, so one run serves both pricing-consistent and projection work. Each of the seven models ships with a citation-grade methodology document, an operator-facing user guide, a UAT specification, and a pytest regression harness that locks bit-identical simulation fingerprints. It was built by an FIA with twenty-plus years in life insurance ALM, Solvency II, NAIC RBC, and IFRS 17 frameworks, for reviewers who expect to check the numbers rather than trust them.

Methodology

Each model family is summarised below in the notation of its own methodology document; the full documents ship with the repository, and every formula used in the code is written out in them.

Rates — Hull–White one-factor (HW1F)

A single-factor Gaussian short-rate model under the risk-neutral measure:

dr(t)=(θ(t)αr(t))dt+σ(t)dW(t)dr(t) = \bigl(\theta(t) - \alpha \, r(t)\bigr)\,dt + \sigma(t)\,dW(t)

θ(t)\theta(t) is never constructed explicitly. The implementation uses the decomposition r(t)=x(t)+φ(t)r(t) = x(t) + \varphi(t), with φ\varphi chosen in closed form so the model reproduces the input discount curve exactly — no numerical differentiation of a noisy forward curve. The piecewise-constant σ(t)\sigma(t) is bootstrapped from an ATM swaption vol grid via Jamshidian’s decomposition of each payer swaption into puts on zero-coupon bonds; each step is a one-dimensional Brent root-find on a monotone function, with no Monte Carlo anywhere in calibration.

Rates — Hull–White two-factor / G2++ (HW2F)

Two correlated Ornstein–Uhlenbeck factors, so the short and long ends of the curve can decorrelate, steepen, and flatten:

r(t)=x(t)+y(t)+φ(t)r(t) = x(t) + y(t) + \varphi(t) dx(t)=ax(t)dt+σ(t)dW1(t),dy(t)=by(t)dt+η(t)dW2(t),corr(dW1,dW2)=ρdx(t) = -a\,x(t)\,dt + \sigma(t)\,dW_1(t), \qquad dy(t) = -b\,y(t)\,dt + \eta(t)\,dW_2(t), \qquad \operatorname{corr}(dW_1, dW_2) = \rho

Piecewise-constant σ(t)\sigma(t) and η(t)\eta(t) are bootstrapped from a dual-tenor swaption grid; swaption pricing is by 32-point Gauss–Hermite quadrature with a conditional Jamshidian decomposition (Brigo–Mercurio §4.2). The mean reversions aa, bb and the factor correlation ρ\rho are user-supplied constants — joint calibration of all five parameters is deliberately not attempted.

Equity — Geometric Brownian motion (GBM)

dS(t)S(t)=(μq)dt+σdW(t)\frac{dS(t)}{S(t)} = (\mu - q)\,dt + \sigma\,dW(t)

Simulation always runs under the risk-neutral measure with μ=r\mu = r; the closed-form log solution makes the log-Euler scheme exact. The single σ\sigma is fitted to a 5×5 implied-vol grid by a bounded scalar optimiser minimising the equal-weighted sum of squared implied-vol residuals; the per-cell residual heatmap shows exactly what a one-parameter model cannot say about the surface. Multi-asset runs (up to 50 assets) correlate the Brownian increments through a Cholesky factor of the input matrix.

Equity — Heston stochastic volatility

dS(t)S(t)=(rq)dt+v(t)dWS(t),dv(t)=κ(θv(t))dt+ξv(t)dWv(t)\frac{dS(t)}{S(t)} = (r - q)\,dt + \sqrt{v(t)}\,dW_S(t), \qquad dv(t) = \kappa\bigl(\theta - v(t)\bigr)\,dt + \xi\sqrt{v(t)}\,dW_v(t)

with dWS,Wv(t)=ρdtd\langle W_S, W_v\rangle(t) = \rho\,dt. All five parameters (κ,θ,ξ,ρ,v0)(\kappa, \theta, \xi, \rho, v_0) are fitted to the same 5×5 surface by least squares on implied-vol residuals, priced analytically via the Lewis (2001) characteristic-function integral in the Albrecher “little trap” formulation. Simulation uses Andersen’s (2008) Quadratic-Exponential scheme, which keeps variance positive by construction — including in sub-Feller calibrations, where naive Euler schemes go negative and must truncate.

Equity — Jump-diffusion (Merton 1976)

dS(t)S(t)=(rqλk)dt+σdW(t)+(eJ1)dN(t),k=eμJ+σJ2/21\frac{dS(t)}{S(t^{-})} = (r - q - \lambda k)\,dt + \sigma\,dW(t) + \bigl(e^{J} - 1\bigr)\,dN(t), \qquad k = e^{\mu_J + \sigma_J^2/2} - 1

N(t)N(t) is a Poisson process of intensity λ\lambda and jump sizes are JN(μJ,σJ2)J \sim \mathcal{N}(\mu_J, \sigma_J^2); the compensator λk\lambda k in the drift keeps the discounted spot a martingale with jumps switched on. The four parameters (σ,λ,μJ,σJ)(\sigma, \lambda, \mu_J, \sigma_J) are fitted by least squares on implied-vol residuals, with each candidate priced by Merton’s closed-form Poisson-weighted mixture of Black–Scholes prices. The methodology document is explicit that a 25-cell surface identifies these parameters only weakly, and reads railed parameters as a statement about the surface, not solver success.

Credit — Merton structural (1974)

The firm’s asset value follows a geometric diffusion and equity is a European call on the assets struck at the debt face DD:

dV(t)V(t)=rdt+σVdW(t)\frac{dV(t)}{V(t)} = r\,dt + \sigma_V\,dW(t)

The unobservable pair (V,σV)(V, \sigma_V) is recovered from observed equity value and equity volatility by the two-equation solver

E=VN(d1)DerTN(d2),σEE=N(d1)σVVE = V\,N(d_1) - D\,e^{-rT}N(d_2), \qquad \sigma_E\,E = N(d_1)\,\sigma_V\,V

solved by bounded least squares inside no-arbitrage bounds; a solve is accepted only when both round-trip relative residuals are at or below 10810^{-8}. Default is assessed at debt maturity — the classic zero-coupon contract — with analytic default probability, distance to default, and credit spread as closed-form checks on the simulation.

Credit — Jarrow–Turnbull reduced-form (1995)

Default is the first jump of a counting process with hazard rate λ(t)\lambda(t), taken piecewise-constant between spread tenors:

Q(t)=exp(Λ(t)),Λ(t)=0tλ(s)dsQ(t) = \exp\bigl(-\Lambda(t)\bigr), \qquad \Lambda(t) = \int_0^t \lambda(s)\,ds

The hazard vector is bootstrapped from an operator-supplied credit-spread term structure under recovery of face paid at default, one Brent root-find per tenor with the recovery integral evaluated in closed form; curves implying a negative segment hazard are rejected outright rather than clipped. Default times are simulated by exact inverse transform of the survival law, so the paths carry the calibrated survival curve with no discretisation.

Portfolio — joint multi-risk simulation

One model per risk family consumes its own slice of a single correlated Gaussian master draw:

X=LZ,LLT=CX = L\,Z, \qquad L\,L^{\mathsf{T}} = C

The master matrix CC composes each engine’s within-family correlation block with operator-specified cross-family correlations; an infeasible composition is repaired by eigenvalue clipping and the repair is always reported, never silent. Dependence is Gaussian by default, with an optional Student-t copula for joint tail dependence (ν\nu configurable, and its documented effect on whole-horizon aggregates disclosed). Three sleeves map paths to a portfolio value index — a 10-year constant-maturity zero-coupon bond (rates), a total-return basket (equity), a risky bond (credit) — with VaR, CVaR, drawdown, and diversification-benefit diagnostics.

Validation

The validation regime is the same across the platform: closed-form reprice of the calibration instruments, analytic-versus-Monte-Carlo diagnostics, and a regression harness that locks results bit-for-bit.

A prospective adopter can re-run all of it: clone the repository, run the pytest suite, and reproduce any published run from its saved recipe file and seed. The reprice tables and convergence diagnostics are on screen in every run — the tests are the specification, not prose claims.

Limitations

Stated in the methodology documents’ own terms:

Do not use it to price smile-dependent exotics, to model portfolio credit tranches, or as a substitute for your own validation and sign-off: it generates scenarios, and the adopting actuary owns everything built on top of them.

Licence and warranty

Apache-2.0. No warranty of any kind. Nothing here is actuarial advice: the adopting actuary owns validation and sign-off in their own control environment, as they would for any model, purchased or built.

Take it

The repository — code, methodology documents, user guides, UAT specifications, and the full regression harness — will be public at launch.

Want it fitted?

If you want this engine calibrated to your business — your curves, your vol surfaces, your reporting basis, your control framework — that is exactly the work I do. Write to bala@gnanamquantech.com.

Questions, or want it fitted to your business?bala@gnanamquantech.com