FX Option Volatility Surface Calculator

FX Options Volatility Surface


This article provide a simple method to calculate volatility smiles from market quotations. We will be using simplified model using at the money, risk reversal and strangle volatilities quotations for the purpose. We assume that readers have at least some knowledge to these terms and what they refer to.


Table 1 will be the data we will be using for this article. Interest rate used are continuous to simplify the process and tenors used will be simplified to fraction of a year calculated as number of month divided by 12. We will also assumed that the delta convention used in the volatility quotation as forward delta.

The calculation of deltas and strikes uses formula from CPQF Working Paper Series No. 20 'FX Volatility Smile Construction' by Dimitri Reiswich and Uwe Wystup which can be found here. The same paper was published in WILMOTT magazine and accessible here.

Table 1: Sample Volatilities

The Model

Using strangle, the vol for call and put are defined as:

\( \begin{align} \sigma_{25c}&=\sigma_{atm} + \frac{1}{2}\sigma_{25rr} + \sigma_{25str}\\ \sigma_{25p}&=\sigma_{atm} - \frac{1}{2}\sigma_{25rr} + \sigma_{25str}\\ \text{where } \sigma_{25c} &= \text{volatiltiy for 25 delta call}\\ \sigma_{atm} &= \text{volatility for at the money option}\\ \sigma_{25rr} &= \text{volatility for 25 delta risk reversal}\\ \sigma_{25str} &= \text{volatility for 25 delta strangle}\\ \sigma_{25p} &= \text{volatiltiy for 25 delta put}\\ \end{align} \)

Table 2: Volatility Surface

The result of out calculation is presented as Table 2 (click 'Calculate' button). Now that we have the volatilities for various tenors and delta, how do we use it? Note that as in interest rate products, option volatilities are quoted in standard tenors. Unfortunately, once a trade is made and position kept in the book/porfolio, the expiry of the option may no longer falls on standard tenors. The need to mark to market the option position gives rise to the need for the correct volatility (or the best volatility estimate) to be derived from a model. As a short cut, we can simply interpolate from the 'ATM' term structure to estimate the volatility of our option position. But there is a dimension not taken into account, if we do it that way. The strike of our option may not be 'ATM' or at the standard 25 or 10 deltas. We will address the issue in a short while.

In the meantime, lets have a look at the chart below which will appear after clicking 'Calculate' button. The default chart looks a little jaggy/edgy as it simply connects the points linearly. We can smooth the curve a bit by interpolating the generated surface. Click 'Toggle Surface Chart' to see the difference after we use python package scipy.interpolate.interp2d to interpolate the various values between the points in Table 2 and smooths the curve. The same method will be used to find the appropriate volatility value for a position.

A note on our chart. Notice that there is no information on anything with delta beyond 50% (at the money) yet we charted volatilities for delta > 50. This is based on the put-call parity premise where the sum of the put and call absolute deltas is 1. Hence the volatility for 25 delta put is the same as the 75 delta call. This is valid for forward delta only. For spot delta the sum will be the present value of 1.

The first step to find a good volatility estimate for our position is convert the delta in the chart into strikes. For the purpose we need to make several assumptions.

  1. Flat interest rate term structure. We will assume the same continuous interest rate for all tenor/maturity. The domestic rate is assumed to be 2.50% while the foreign interest rate is 0.05%.
  2. Spot foreign exchange rate is 4.2000
Relevant closed form solution used to solve are obtained from the article mentioned above. It is worth to note that it is not too dissimilar to Black 76 model.

The forward fx rate is defined as:

\( \begin{align} f &= Se^{(r_d-r_f)t}\\ \text{where }f&=\text{forward fx rate}\\ S&=\text{spot fx rate}\\ r_d&=\text{domestic interest rate}\\ r_f&=\text{foreign interest rate}\\ t&=\text{time} \end{align} \)

The option value is defined as:

\( \begin{align} v &= \phi e^{-r_dt}\left[ fN(\phi d_+)-KN(\phi d_-)\right]\\ \text{where } v&=\text{value of the option}\\ d_{\pm} &= \dfrac{ln\left(\frac{f}{K}\right) \pm\frac{1}{2}\sigma^2t} {\sigma\sqrt{t}}\\ \phi&=\text{+1 for call and -1 for put}\\ K&=\text{strike}\\ \sigma &=\text{volatility}\\ N(x)&= \text{cumulative normal distribution function} \end{align} \)

We made the assumption that the deltas for all the quotations are forward deltas. The formula for the forward delta is:

\( \begin{align} \delta = \phi N(\phi d_+) \end{align} \)

Finally, the formula for obtaining the strike from a forward delta:

\( \begin{align} K &= fe^{-\phi N^{-1}(\phi\delta)\sigma\sqrt{t}+ \frac{1}{2}\sigma^2t}\\ \text{where } N^{-1}(x)&= \text{inverse cumulative normal distribution function} \end{align} \)

Now that we have set up the formulas, the next step is to calculate the strikes for given delta. We can use the data in Table 2 together with out assumptions to obtain the strikes. Click 'Calculate' in Table 3 to see the result of our calculations.

Table 3: Strikes Surface

We have actually mapped out the strike for each volatility and expiry. Note that the strikes for out of money option (10 and 25 deltas) are higher that the at the money and going lower the higher the delta. We made our strikes calculation based on call option. For put option, we can either recalculate the table or simply change the value of the column header by 100 - column header i.e if the column header is 10 Delta (%), it becomes 90 Delta (%). Strike remains due to the put-call parity imposed earlier.

Let's assumed that we have a call option with 0.33 years to expiry and a strike of 4.3000. How do we get the volatility, since we do not know the delta of the option and delta is a function of volatility? How do we estimate the delta?

A crude way is by interpolating the delta using time and then interpolate the volatility using the interpolated delta. We use scipy.interpolate.interp2d (function in scipy package for python) to do so. Table 3 is derived by calculating strike from delta and time i.e strike as a function of delta and time - \(K(\delta,t)\). The function used require two variables, namely the \(\delta\) and \(t\), which means we have to do additional interpolation to find the right delta. For this purpose we used Newton-Raphson method to find the \(\delta\) by changing the strike. Once the strike is our option strike, iteration stop, and the interpolated delta is used as the delta of our option.

Interpolated Vol From Vol Surface

With our new found delta, interpolating the volatility is simpler. We use data in Table 2, the same scipy function and feed the delta and time to the function. The result is the interpolated volatility that can be used to revalue the option holding and recalculate the greeks. A calculator to perform the task is provided.