API

src.calcbsimpvol.calcbsimpvol(arg_dict)[source]

calculates implied volatility surface or smile. Translated from MATLAB code. As it is a bare-metal package I would suggest to write an adapter class to feed the function.

Parameters
  • arg_dict (dict) –

  • cp (ndarray) – int…..Call = [+1], Put = [-1]…[m x n] or [1 x 1]

  • P (ndarray) – float…Option Price Matrix…[m x n]

  • S (ndarray) – float…Underlying Price…[1 x 1]

  • K (ndarray) – float…Strike Price…[m x n]

  • tau (ndarray) – float…Time to Expiry in Years…[m x n]

  • r (ndarray) – float…Continuous Risk-Free Rate…[m x n] or [1 x 1]

  • q (ndarray) – float…Continuous Dividend Yield…[m x n] or [1 x 1]

Returns

  • iv (ndarray) – float…The Implied Volatility…[m x n]

Examples

This is the first example which is also included separate file within the examples folder.

from calcbsimpvol import calcbsimpvol
import numpy as np
S = np.asarray(100)
K_value = np.arange(40, 160, 25)
K = np.ones((np.size(K_value), 1))
K[:, 0] = K_value
tau_value = np.arange(0.25, 1.01, 0.25)
tau = np.ones((np.size(tau_value), 1))
tau[:, 0] = tau_value
r = np.asarray(0.01)
q = np.asarray(0.03)
cp = np.asarray(1)
P = [[59.35, 34.41, 10.34, 0.50, 0.01],
[58.71, 33.85, 10.99, 1.36, 0.14],
[58.07, 33.35, 11.50, 2.12, 0.40],
[57.44, 32.91, 11.90, 2.77, 0.70]]
P = np.asarray(P)
[K, tau] = np.meshgrid(K, tau)
sigma = calcbsimpvol(dict(cp=cp, P=P, S=S, K=K, tau=tau, r=r, q=q))
print(sigma)
# [[       nan,        nan, 0.20709362, 0.21820954, 0.24188675],
# [       nan, 0.22279836, 0.20240934, 0.21386148, 0.23738982],
# [       nan, 0.22442837, 0.1987048 , 0.21063506, 0.23450013],
# [       nan, 0.22188111, 0.19564657, 0.20798285, 0.23045406]]
#%% Plotting the results
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
m = np.log(S/K)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(m, tau, sigma)
ax.set_xlabel('log Moneyness')
ax.set_ylabel('Time Until Expiry')
ax.set_zlabel('implied Volatility [% p.a.]')
plt.show()

This is the second example which is also included separate file within the examples folder.

from calcbsimpvol import calcbsimpvol
import numpy as np
P = [[59.14, 34.21, 10.17, 16.12, 40.58],
[58.43, 33.59, 10.79, 17.47, 41.15],
[57.87, 33.16, 11.363, 18.63, 41.74],
[57.44, 32.91, 11.90, 19.58, 42.27]]
P = np.asarray(P)
S = np.asarray(100)
K = np.arange(40, 160, 25)
tau = np.arange(0.25, 1.01, 0.25)
K, tau = np.meshgrid(K, tau)
cp = np.hstack((np.ones((4, 3)), -1 * np.ones((4, 2))))  # [Calls[4,3], Puts[4,2]]
r = 0.01 * np.ones((4, 5)) * np.asarray([1.15, 1.10, 1.05, 1]).reshape((4, 1))
q = 0.03 * np.ones((4, 5)) * np.asarray([1.3, 1.2, 1.1, 1]).reshape((4, 1))
sigma = calcbsimpvol(dict(cp=cp, P=P, S=S, K=K, tau=tau, r=r, q=q))
print(sigma)
# [[0.27911614, 0.23659105, 0.20714849, 0.21834553, 0.24225733],
# [0.2797917 , 0.2315275 , 0.20249323, 0.21436123, 0.23823301],
# [0.27436779, 0.22679618, 0.1987485 , 0.21097384, 0.23450519],
# [0.26918174, 0.22235213, 0.19572994, 0.20807133, 0.2310324 ]]
#%% Plotting the results
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import
import matplotlib.pyplot as plt
m = np.log(S/K)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(m, tau, sigma)
ax.set_xlabel('log Moneyness')
ax.set_ylabel('Time Until Expiry')
ax.set_zlabel('implied Volatility [% p.a.]')
plt.show()

References

  1. Li, 2006, “You Don’t Have to Bother Newton for Implied Volatility”

  1. http://en.wikipedia.org/wiki/Householder’s_method

  2. http://en.wikipedia.org/wiki/Greeks_(finance)

  3. https://www.mathworks.com/matlabcentral/fileexchange/41473-calcbsimpvol-cp-p-s-k-t-r-q

src.calcbsimpvol._fcnv(p, m, n, i, j, x, c)[source]

Eq. (19), Li (2006)

src.calcbsimpvol._fcnN(x)[source]

cumulative density function (cdf) of normal distribution

src.calcbsimpvol._fcnn(x)[source]

probability density function (pdf) of normal distribution