Files
strategy-lab/to_explore/pyquantnews/67_SABR.ipynb
David Brazda e3da60c647 daily update
2024-10-21 20:57:56 +02:00

9.0 KiB

No description has been provided for this image

This notebook calibrates the SABR (Stochastic Alpha, Beta, Rho) model to market data, specifically for the SPY options expiring in January 2026. It fetches option chains, extracts call and put options, and calculates the mid-prices. The SABR model is used to fit implied volatilities and generate a volatility smile. Finally, the code uses the Black model to calculate theoretical option prices and compares them to market prices. This is useful in practice for financial modeling and option pricing.

In [ ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from openbb_terminal.sdk import openbb
from pysabr import Hagan2002LognormalSABR
from pysabr import hagan_2002_lognormal_sabr as sabr
from pysabr.black import lognormal_call

Set plot style and parameters for visualizations

In [ ]:
plt.style.use("default")
plt.rcParams["figure.figsize"] = [5.5, 4.0]
plt.rcParams["figure.dpi"] = 140
plt.rcParams["lines.linewidth"] = 0.75
plt.rcParams["font.size"] = 8

Define the symbol and expiration date for the SPY options

In [ ]:
symbol = "SPY"
expiration = "2026-01-16"

Fetch the option chains for the given symbol from Yahoo Finance

In [ ]:
spy = openbb.stocks.options.chains(symbol, source="YahooFinance")

Extract call options and calculate their mid-prices

In [ ]:
calls = spy[spy.optionType == "call"]
jan_2026_c = calls[calls.expiration == expiration].set_index("strike")
jan_2026_c["mid"] = (jan_2026_c.ask + jan_2026_c.ask) / 2

Extract put options and calculate their mid-prices

In [ ]:
puts = spy[spy.optionType == "put"]
jan_2026_p = puts[puts.expiration == expiration].set_index("strike")
jan_2026_p["mid"] = (jan_2026_p.ask + jan_2026_p.ask) / 2

Extract strikes and implied volatilities for the call options

In [ ]:
strikes = jan_2026_c.index
vols = jan_2026_c.impliedVolatility * 100

Find the forward price using put-call parity and calculate the time to expiration

In [ ]:
f = (
    (jan_2026_c.mid - jan_2026_p.mid)
    .dropna()
    .abs()
    .sort_values()
    .index[0]
)

Calculate the time fraction until expiration in years

In [ ]:
t = (pd.Timestamp(expiration) - pd.Timestamp.now()).days / 365

Set the beta parameter for the SABR model

In [ ]:
beta = 0.5

Initialize the SABR model with the forward price, time to expiration, and beta

In [ ]:
sabr_lognormal = Hagan2002LognormalSABR(
    f=f,
    t=t,
    beta=beta
)

Fit the SABR model to the market implied volatilities

In [ ]:
alpha, rho, volvol = sabr_lognormal.fit(strikes, vols)
print(alpha, rho, volvol)

Calculate calibrated volatilities using the SABR model for each strike price

In [ ]:
calibrated_vols = [
    sabr.lognormal_vol(strike, f, t, alpha, beta, rho, volvol) * 100
    for strike in strikes
]

Plot the volatility smile generated by the SABR model and compare it to market implied volatilities

In [ ]:
plt.plot(
    strikes, 
    calibrated_vols
)
In [ ]:
plt.xlabel("Strike")
plt.ylabel("Volatility")
plt.title("Volatility Smile")
plt.plot(strikes, vols)
plt.show()

Calculate theoretical option prices using the Black model for each strike price and calibrated volatility

In [ ]:
black_values = []
for strike, calibrated_vol in zip(strikes.tolist(), calibrated_vols):
    black_value = lognormal_call(
        strike, 
        f, 
        t, 
        calibrated_vol / 100, 
        0.05, 
        cp="call"
    )
    black_values.append(black_value)

Create a DataFrame to compare Black model values with market mid-prices and plot the differences

In [ ]:
option_values = pd.DataFrame(
    {
        "black": black_values,
        "market": jan_2026_c.mid
    },
    index=strikes
)
In [ ]:
(option_values.black - option_values.market).plot.bar()

PyQuant News is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to get started with Python for quant finance. For educational purposes. Not investment advise. Use at your own risk.