I am looking for a library which i can use for faster way to calculate implied volatility in python. I have options data about 1+ million rows for which i want to calculate implied volatility. what would be the fastest way i can calculate IV's. I have tried using py_vollib but it doesnt support vectorization. It takes about 5 mins approx. to calculate. Are there any other libraries which can help in faster calculation. What do people use in real time volatility calculations where there are millions of rows coming in every second?
You have to realize that the implied volatility calculation is computationally expensive and if you want realtime numbers maybe python is not the best solution.
Here is an example of the functions you would need:
import numpy as np
from scipy.stats import norm
N = norm.cdf
def bs_call(S, K, T, r, vol):
d1 = (np.log(S/K) + (r + 0.5*vol**2)*T) / (vol*np.sqrt(T))
d2 = d1 - vol * np.sqrt(T)
return S * norm.cdf(d1) - np.exp(-r * T) * K * norm.cdf(d2)
def bs_vega(S, K, T, r, sigma):
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
return S * norm.pdf(d1) * np.sqrt(T)
def find_vol(target_value, S, K, T, r, *args):
MAX_ITERATIONS = 200
PRECISION = 1.0e-5
sigma = 0.5
for i in range(0, MAX_ITERATIONS):
price = bs_call(S, K, T, r, sigma)
vega = bs_vega(S, K, T, r, sigma)
diff = target_value - price # our root
if (abs(diff) < PRECISION):
return sigma
sigma = sigma + diff/vega # f(x) / f'(x)
return sigma # value wasn't found, return best guess so far
Computing a single value is quick enough
S = 100
K = 100
T = 11
r = 0.01
vol = 0.25
V_market = bs_call(S, K, T, r, vol)
implied_vol = find_vol(V_market, S, K, T, r)
print ('Implied vol: %.2f%%' % (implied_vol * 100))
print ('Market price = %.2f' % V_market)
print ('Model price = %.2f' % bs_call(S, K, T, r, implied_vol))
Implied vol: 25.00%
Market price = 35.94
Model price = 35.94
But if you try to compute many, you will realize that it takes some time...
%%time
size = 10000
S = np.random.randint(100, 200, size)
K = S * 1.25
T = np.ones(size)
R = np.random.randint(0, 3, size) / 100
vols = np.random.randint(15, 50, size) / 100
prices = bs_call(S, K, T, R, vols)
params = np.vstack((prices, S, K, T, R, vols))
vols = list(map(find_vol, *params))
Wall time: 10.5 s
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With