I have a Class object which calculates implied volatility, I have a csv for a company I am interested in with multiple strikes, contract lengths etc. But I cant work out how to get my df to interact with the object.
Ive added the code for the calculation as well as the df with the desired result which is the IV column.
df["IV"] = df.apply(implied_vol('p', df["Premium"], df["Stock Price"], df["Strike"], 0.001, df["Length / 365"], df["Div Yield"]))
from math import log, sqrt, pi, exp
from scipy.stats import norm
def d1(S,K,T,r,q,sigma):
return(log(S/K)+(r - q +sigma**2/2.)*T)/sigma*sqrt(T)
def d2(S,K,T,r,q,sigma):
return d1(S,K,T,r,q,sigma)-sigma*sqrt(T)
## define the call options price function
def bs_call(S,K,T,r,q,sigma):
return S*exp(-q*T)*norm.cdf(d1(S,K,T,r,q,sigma))-K*exp(-r*T)*norm.cdf(d2(S,K,T,r,q,sigma))
def bs_put(S,K,T,r,q,sigma):
return K*exp(-r*T)-S*exp(-q*T)+bs_call(S,K,T,r,q,sigma)
def implied_vol(option_type, option_price, S, K, r, T, q):
precision = 0.0000001
upper_vol = 99.0
max_vol = 99.0
min_vol = 0.0001
lower_vol = 0.0001
iteration = 0
while 1:
iteration +=1
mid_vol = (upper_vol + lower_vol)/2.0
if option_type == 'c':
price = bs_call(S,K,T,r,q,mid_vol)
lower_price = bs_call(S,K,T,r,q,lower_vol)
if (lower_price - option_price) * (price - option_price) > 0:
lower_vol = mid_vol
else:
upper_vol = mid_vol
if abs(price - option_price) < precision: break
if mid_vol > max_vol - 5 :
mid_vol = 0.0001
break
elif option_type == 'p':
price = bs_put(S,K,T,r,q,mid_vol)
upper_price = bs_put(S,K,T,r,q,upper_vol)
if (upper_price - option_price) * (price - option_price) > 0:
upper_vol = mid_vol
else:
lower_vol = mid_vol
if abs(price - option_price) < precision: break
if iteration > 1000: break
return mid_vol
Strike Stock Price Premium Length Div Yield Length / 365 IV
480 490.649994 13.35 17 0 0.046575342 0.451331908
485 490.649994 15.025 17 0 0.046575342 0.427791225
490 490.649994 17.35 17 0 0.046575342 0.419756262