0% found this document useful (0 votes)
16 views

BlackVariance - Ipynb - Colab

Black variance
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

BlackVariance - Ipynb - Colab

Black variance
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

10/27/24, 8:34 PM BlackVariance.

ipynb - Colab

!pip install QuantLib


import QuantLib as ql
from math import pow, sqrt
import numpy as np

Requirement already satisfied: QuantLib in /usr/local/lib/python3.10/dist-packages (1.36)

day_count = ql.Actual365Fixed()
calendar = ql.UnitedStates(ql.UnitedStates.NYSE)
calculation_date = ql.Date(16, 9, 2024)

spot = 659.37
ql.Settings.instance().evaluationDate = calculation_date

risk_free_rate = 0.01
dividend_rate = 0.0
yield_ts = ql.YieldTermStructureHandle(
ql.FlatForward(calculation_date, risk_free_rate, day_count))
dividend_ts = ql.YieldTermStructureHandle(
ql.FlatForward(calculation_date, dividend_rate, day_count))

expiration_dates = [
ql.Date(16,10,2024), ql.Date(16,11,2024), ql.Date(16,12,2024), # starting from October 2024
ql.Date(16,1,2025), ql.Date(16,2,2025), ql.Date(16,3,2025),
ql.Date(16,4,2025), ql.Date(16,5,2025), ql.Date(16,6,2025),
ql.Date(16,7,2025), ql.Date(16,8,2025), ql.Date(16,9,2025),
ql.Date(16,10,2025), ql.Date(16,11,2025), ql.Date(16,12,2025),
ql.Date(16,1,2026), ql.Date(16,2,2026), ql.Date(16,3,2026),
ql.Date(16,4,2026), ql.Date(16,5,2026), ql.Date(16,6,2026),
ql.Date(16,7,2026), ql.Date(16,8,2026), ql.Date(16,9,2026)
]

strikes = [600.00, 630.00, 660.00, 690.00, 720.00, 750.00, 780.00, 810.00]

data = [
[0.28519, 0.26577, 0.24394, 0.22832, 0.21453, 0.20916, 0.20941, 0.21127],
[0.29450, 0.27769, 0.25330, 0.23614, 0.22575, 0.21729, 0.21228, 0.21202],
[0.31419, 0.29372, 0.27729, 0.26492, 0.25601, 0.24883, 0.24036, 0.23568],
[0.32498, 0.30847, 0.29475, 0.28399, 0.27715, 0.26943, 0.26098, 0.25506],
[0.32941, 0.31516, 0.30296, 0.29275, 0.28867, 0.27969, 0.27239, 0.26631],
[0.33521, 0.32242, 0.31154, 0.30190, 0.29948, 0.29096, 0.28424, 0.27840],
[0.34442, 0.33267, 0.32288, 0.31374, 0.31245, 0.30474, 0.29838, 0.29283],
[0.35384, 0.34286, 0.33386, 0.32507, 0.32460, 0.31745, 0.31135, 0.30600],
[0.36338, 0.35300, 0.34464, 0.33614, 0.33630, 0.32961, 0.32371, 0.31852],
[0.37301, 0.36312, 0.35526, 0.34698, 0.34766, 0.34132, 0.33558, 0.33052],
[0.38272, 0.37322, 0.36574, 0.35765, 0.35873, 0.35267, 0.34705, 0.34209],
[0.39246, 0.38330, 0.37617, 0.36822, 0.36965, 0.36383, 0.35831, 0.35344],
[0.40226, 0.39336, 0.38651, 0.37869, 0.38040, 0.37477, 0.36934, 0.36453],
[0.41207, 0.40342, 0.39681, 0.38911, 0.39106, 0.38561, 0.38025, 0.37550],
[0.42171, 0.41327, 0.40679, 0.39931, 0.40190, 0.39665, 0.39139, 0.38675],
[0.43128, 0.42300, 0.41658, 0.40937, 0.41276, 0.40769, 0.40255, 0.39802],
[0.44086, 0.43274, 0.42637, 0.41943, 0.42360, 0.41872, 0.41368, 0.40927],
[0.45049, 0.44252, 0.43618, 0.42948, 0.43432, 0.42959, 0.42465, 0.42034],
[0.46016, 0.45231, 0.44602, 0.43953, 0.44498, 0.44040, 0.43554, 0.43132],
[0.46986, 0.46213, 0.45587, 0.44957, 0.45556, 0.45110, 0.44631, 0.44217],
[0.47959, 0.47196, 0.46573, 0.45961, 0.46610, 0.46176, 0.45704, 0.45296],
[0.48934, 0.48181, 0.47561, 0.46964, 0.47658, 0.47235, 0.46769, 0.46368],
[0.49912, 0.49167, 0.48550, 0.47967, 0.48701, 0.48288, 0.47827, 0.47432],
[0.50891, 0.50154, 0.49539, 0.48970, 0.49742, 0.49337, 0.48881, 0.48492]
]

expiration_dates = sorted(set(expiration_dates))

implied_vols = ql.Matrix(len(strikes), len(expiration_dates))


for i in range(implied_vols.rows()):
for j in range(implied_vols.columns()):
implied_vols[i][j] = data[j][i]

black_var_surface = ql.BlackVarianceSurface(
calculation_date, calendar,
expiration_dates, strikes,
implied_vols, day_count)

strike = 600.0
expiry = 1.2 # years

https://colab.research.google.com/drive/1SqrzcMfAx5JaUjNKqFmxEbiaALWq_d0f#printMode=true 1/3
10/27/24, 8:34 PM BlackVariance.ipynb - Colab
black_var_surface.blackVol(expiry, strike)

0.28519

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

# Define strikes grid and expiry


strikes_grid = np.arange(strikes[0], strikes[-1], 10)
expiry = 1.0 # Expiry in years

# Calculate implied volatilities


implied_vols = [black_var_surface.blackVol(expiry, s) for s in strikes_grid]

# Fetch actual market data


actual_data = data[11] # Data for the selected expiry

# Plotting
plt.figure(figsize=(8, 6))
plt.plot(strikes_grid, implied_vols, label="Black Surface")
plt.plot(strikes, actual_data, "o", label="Actual")
plt.xlabel("Strikes", fontsize=12)
plt.ylabel("Volatilities", fontsize=12)
plt.legend(loc="upper right")
plt.title(f"Volatility Surface at Expiry = {expiry} years")
plt.show()

# Define the range for strikes and years


plot_years = np.arange(0, 2, 0.1)
plot_strikes = np.arange(600, 800, 1)

# Create a meshgrid of strikes and years


X, Y = np.meshgrid(plot_strikes, plot_years)

# Calculate implied volatilities for each (year, strike) pair


Z = np.array([black_var_surface.blackVol(float(y), float(x))
for xr, yr in zip(X, Y)
for x, y in zip(xr,yr) ]
).reshape(len(X), len(X[0]))

# Create the 3D plot


fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')

# Plot the surface

https://colab.research.google.com/drive/1SqrzcMfAx5JaUjNKqFmxEbiaALWq_d0f#printMode=true 2/3
10/27/24, 8:34 PM BlackVariance.ipynb - Colab
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, rstride=1, cstride=1, linewidth=0.1)

# Add a color bar for reference


fig.colorbar(surf, shrink=0.5, aspect=5)

# Set labels
ax.set_xlabel('Strikes')
ax.set_ylabel('Years')
ax.set_zlabel('Implied Volatility')

plt.title('Implied Volatility Surface')


plt.show()

https://colab.research.google.com/drive/1SqrzcMfAx5JaUjNKqFmxEbiaALWq_d0f#printMode=true 3/3

You might also like