Getting The Hull-White Model To Actually Work For Rate Derivatives

The Hull-White one-factor model is essentially a mean-reverting Vasicek model with a time-dependent drift function added so you can fit the current yield curve exactly. It sounds simple, which is the first trap. The two-factor version adds another short rate component with its own mean reversion speed, correlation between the two factors, and a separate time-dependent drift. People reach for it because it has analytic solutions for zero-coupon bonds and swaptions, and because it handles the kind of forward-starting product structures you see in rate options. Calibration is where things get interesting. You typically calibrate to the cap/floor market or to swaption volatility surfaces. For the one-factor model, this usually means solving a system of nonlinear equations to back out the mean reversion parameter, the volatility parameter, and the drift function that matches the observed market prices. I spent a solid week in 2019 debugging a two-factor calibration where the optimizer was silently collapsing one of the factors to near-zero volatility. The residual surface looked fine across most tenors, but when I checked the individual factor contributions, one factor was essentially dead. The workaround was to constrain the lower bound on the second factor's volatility to something like 1e-4 and to initialize both mean reversion speeds from separate bootstrap estimates rather than letting the optimizer pick them from the same starting point. The drift function in both versions is derived analytically. For the one-factor model, theta(t) is computed so that the model-implied bond price equals the market bond price at every maturity. The formula involves an integral over the volatility function and the exponential decay of the mean reversion factor. If you skip this step and just use a constant drift, your bond prices will be wrong and everything downstream from there inherits that error.

Pricing swaptions under Hull-White is actually straightforward because the model gives you a closed-form solution similar to Black's formula but with an effective volatility that depends on the model parameters and the option tenor. The effective volatility is a function of the mean reversion speed, the rate volatility, and the time to expiry and tenor of the underlying swap. I've seen junior quants plug the raw rate volatility into Black's formula directly, which is wrong. The difference matters most for longer-dated swaptions where mean reversion has more time to pull the rate distribution tighter. For exotics, you generally fall back to Monte Carlo simulation. The short rate in Hull-White is Gaussian, so each time step is trivial to sample. You build the path, compute the swap value at each exercise date, and discount. One edge case that caught me off guard: when simulating early-exercise products like Bermudan swaptions under the two-factor model, the annuity can become negative if rates go deeply negative and the swap is out of the money far out. The exercise decision then behaves weirdly. The fix is to clip the annuity at a small positive floor, or to use the annuity from the risk-neutral measure consistently throughout. This is not a corner case in today's market environment. A few things that are not obvious:

  • The one-factor Hull-White can only fit one volatility parameter to the entire cap/floor strip. If your market shows a pronounced volatility smile or term structure in rates vol, a single factor will misprice at-the-money options while appearing acceptable for out-of-the-money ones.
  • Negative rates are handled natively, which is an advantage over Black-type models, but the Gaussian nature means there is still a non-zero probability of extreme negative paths. In practice this only matters for very long simulation horizons.
  • Calibration to a swaption vol surface with sparse data often leads to multiple local minima. Run the optimizer from several starting points and compare the residuals, not just the final objective value.

Implementation-wise, I recommend building the calibration module and the pricing module separately. The calibration module returns the parameter set and the drift function values on a grid. The pricing module consumes those. If you inline calibration into pricing, you will end up recalibrating on every pricing call, which is slow and makes debugging nearly impossible. For the drift function computation, precompute the integral terms on a fixed grid and interpolate. Recalculating the integral from scratch each time is unnecessary and it adds numerical noise that shows up in the bond price residuals. The cost is negligible once you have the grid. There is an open-source reference implementation in Python that covers the one-factor model, the calibration routine, and the analytic swaption pricing. It does not cover the two-factor extension or the Monte Carlo pricer. I built mine on top of that codebase, then added the two-factor piece and the simulation engine. The GitHub repo is at github.com/margrabe/hullwhite-rates. You will need to read the source to understand the boundary conditions used for the calibration solver, because the comments there are sparse.

Get the Full Details

Hull-White on Derivatives: John Hull, Alan White: 9781906348298: Amazon ...
Hull-White on Derivatives: John Hull, Alan White: 9781906348298: Amazon ...

If you are pricing CMS or CMS spread products, Hull-White is not the right tool. The convexity adjustments under this model are tractable but inaccurate compared to what the market actually observes. Use a multi-factor model with stochastic vol or a local vol extension instead. Hull-White is fast and it works well for vanilla rate derivatives and many path-independent exotics, but it has limits. Knowing where those limits are is what separates a working model from a model that quietly breaks in production.