Interpolating Volatility Skew Beyond Observed Strikes
Summary
The document asks how to extend a volatility skew from a set of observed strike and volatility points across a much wider strike range. The initial cubic spline approach produces negative values at distant strikes, raising concerns about overshoot and extrapolation behavior.
The response recommends linear interpolation with linear extrapolation as a simpler alternative, and notes that other interpolation orders can be tried. This can avoid some spline oscillation, but it does not impose financial constraints or guarantee sensible behavior over a long extrapolation range. The response supplies code and plotting guidance, but no comparison of methods, error analysis, or evidence that linear extrapolation is appropriate for the particular volatility surface. In practice, the choice depends on the surface representation, available market data, and constraints required for downstream pricing.
Key ideas
- Cubic splines can overshoot when extended beyond the observed strike range.
- Linear interpolation and extrapolation are offered as a simpler way to extend the data.
- Changing interpolation order may produce different curves, but the document gives no comparative evaluation.
- Extrapolation across a wide strike range remains sensitive to modeling assumptions and surface constraints.
Tags
Full text
# How to interpolate volatility's skew using spline in Python
# How to interpolate volatility's skew using spline in Python
I have two lists to describe the function y(x) that represents strikes and the relative value of the skew of a volatility surface:
```
x_points = [22.56, 27.07, 31.58, 36.10, 40.61, 45.12, 49.63, 54.14, 58.66, 63.17, 67.68] %strikes value
y_points = [97.44, 87.32, 79.73, 75.47, 73.58, 74.53, 78.61, 83.64, 88.03, 92.26, 96.44] %vol value
```
I would like to perform cubic spline interpolation to retrieve the range 0;200 of the skew but, using the below code, i get some negative values (not consistent solution):
```
def f(x):
x = np.linspace(0, 200, 399)
tck = interpolate.splrep(x_points, y_points)
return interpolate.splev(x, tck)
```
Can you please give me some feedback and help to get the problem solved? Maybe the curve should not be fit with Cubic Spline or i should add some constraints to the optimization problem (no idea at all ...)
## Answer by Pleb (score 2)
https://quant.stackexchange.com/a/74843
#### Use linear interpolation/extrapolation:
You are overfitting your volatility surface if you use a Cubic spline, hence giving you negative values for large strikes. In order to avoid this, you can simply do a linear extrapolation of the volatility surface:
```
import scipy as sc
import numpy as np
import matplotlib.pyplot as plt
Strikes = [22.56, 27.07, 31.58, 36.10, 40.61, 45.12, 49.63, 54.14, 58.66, 63.17, 67.68]
Vols = [97.44, 87.32, 79.73, 75.47, 73.58, 74.53, 78.61, 83.64, 88.03, 92.26, 96.44]
LinInterpolation = sc.interpolate.interp1d(Strikes, Vols,kind = 'linear',fill_value='extrapolate')
x = np.linspace(0, 200, 399)
plt.plot(x, LinInterpolation(x))
```
You can play around with the interpolator by changing the string in `kind` to eg. "quadratic" or "cubic". Documentation can be found here.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.