The Chambers-Nawalkha Formula

This is about implied volatility. Which can for example be found as \sigma in the Black76 process

dF = \sigma F dW

with an underlying forward rate F and a brownian motion W. It is this \sigma which is often used to express a vanilla option price because is normalizes out the dependency on expiry and strike in a certain way.

It is the same \sigma that makes trouble for caps and swaptions in Euro nowadays because it also rules out negative forwards and tends to explode for low interest rate levels. But there are workarounds for this like normal volatilities (remove the F on the rhs of the equation above) or shifted lognormal volatilities (replace F by F+\alpha for a constant \alpha \geq 0). I will write more about this in a future post.

Today I focus on the implied aspect. This means you start with a price and ask for the \sigma giving this price in the Black76 model.

Why is that important ? Because implied volatilities are something that traders want to see. Or you want to use them for interpolation rather than directly the prices. Or your trading system accepts only them as market data input. Also there are useful models (or model resolutions) that work directly with volatilities, like the SABR-Hagan-2002 model or the SVI model. On the other hand there are sometimes only prices available in the first place. Could be market quotes. Could also be other models that produce premiums and not directly volatilities like other resolutions for the SABR model.

I had this issue several times already. An example is the KahaleSmileSection class which can be used to check a smile for arbitrage and replace the defective regions by an arbitrage free extrapolation. This class works in the call price space. You can retrieve implied volatilities from it, but for this I needed to use

 try {
     Option::Type type = strike >= f_ ? Option::Call : 
     vol = blackFormulaImpliedStdDev(
            type, strike, f_,
            type == Option::Put ? strike - f_ + c : c) /
} catch (...) { /* ... */}

which has c, the call price, as an input and converts that to an implied volatility using the library’s function blackFormulaImpliedStdDev. This function uses a numerical zero search and the usual “forward” black formula to find the implied volatility. With the usual downsides. It would be nicer to have a closed form solution for the implied volatility!

Another example is the No arbitrage SABR model by Paul Doust that also produces option prices and not directly volatilities. Or of course the ZABR model which we already had on this blog here and which has premium outputs at least for some of its resolutions.

On Wilmott forums someone said

there actually is a closed-form inverted Black-Scholes formula due to Bourianochevsky and Jarulamparabalam … but I’ve never seen it since it’s proprietary …

Hmm googling the two names gives exactly one result (the Wilmott thread) although they sound familiar. But he said proprietary didn’t he. And later, the same guy,

oh, and they also claim they have a closed-form formula for the American put option … again proprietary.

Also very cool. Seriously, on the same thread there is a reference to this nice paper: Can There Be an Explicit Formula for Implied Volatility?. A hint that things are difficult to say the least.

What really counts at the end of the day is what is available in QuantLib. There is blackFormulaImpliedStdDevApproximation. Which is also among the longest function names in the library. This uses (citing from the source code)

Brenner and Subrahmanyan (1988) and Feinstein (1988) approximation for at-the-money forward option, with the extended moneyness approximation by Corrado and Miller (1996)

Quite some contributors. However it does not work too well, at least not in all cases. Look at a SABR smile with \alpha=0.04, \beta=0.5, \nu=0.15, \rho=-0.5, a forward of 0.03 and time to expiry 30 years.


It is surprisingly easy to improve this following a paper by Chambers and Nawalkha, “An improved Approach to Computing Implied Volatility” (The Financial Review 38, 2001, 89-100). The cost for the improvement is that one needs one more input, namely the atm price. But this is not too bad in general. If you have prices from a model that you want to convert into implied volatilities, you can produce the atm price, no problem then. Also if you have market quotes you will often have the atm quote available because this is usually the most liquid one.

What they do is

  • compute an approximate atm volatility from the given atm price
  • use this to reprice the option in question on the atm volatility level
  • compute the vega difference between atm and the requested volatility by a second order Taylor expansion

For the first step they do the same as in blackFormulaImpliedStdDevApproximation, which is to apply the so called Brenner and Subrahmanyan formula to get the implied atm volatility from the given atm option price.

This formula is very very easy: Freeze the forward at time zero in the Black dynamics to get a normal distributed forward at option expiry. Then integrate the option payoff, which can be done explicitly in this case using school math. This gives

E( (F(t)-K)^+ ) \approx F(0)\sigma\sqrt t / (2\pi)

so that the atm volatility can be easily computed from the atm option price. I hear some people find it “deep” that \pi appears in this equation relating option prices and the implied volatility. A sign of a transcendental link between option markets and math. I don’t find that deep, but who am I to judge.

The second step is easy, just an application of the forward Black formula.

For the third step we have (star denoting atm volatility, subscripts denoting derivatives)

c(K) - c^*(K) = c_\sigma(K) (\sigma - \sigma^*) + \frac{1}{2} c_{\sigma\sigma}(K) (\sigma - \sigma^*)^2 + ...

This is a quadratic equation which can readily be solved for (\sigma - \sigma^*).

You can find working code in my master branch The name of the function is blackFormulaImpliedStdDevApproximationChambers and it is part of the file blackformula.cpp. Remember to add the compiler flag -fpermissive-overlong-identifiers during the configure step.

Let’s try it on the same data as above.


Better! Also the resulting smile shape stays natural even in regions which deviates a bit more from the original smile.

Have a very nice weekend all and a good new week.

The Chambers-Nawalkha Formula