Внедрение модели Блэка-Шоулза в Python
Коллеги, всем привет! Сегодня «внедрим» модель Блэка-Шоулза для прайсинга опциона в Python.
Описание и расшифровку самой модели писать не будем, так как этого добра на просторах рунэта пруд пруди, а вот реализации в Python с работающим кодом почти нет.
Итак, заходим в jupyter notebook, создаем новую запись и поехали:
In [1]:
! pip freeze
# install libs
! pip install py_vollib
In [2]
from py_vollib.black_scholes import black_scholes as bs
from py_vollib.black_scholes.greeks.analytical import delta, gamma, vega, theta, rho
import numpy as np
from scipy.stats import norm
from py_vollib.black_scholes import black_scholes as bs
from py_vollib.black_scholes.greeks.analytical import delta, gamma, vega, theta, rho
In [3]
def blackScholes(r, S, K, T, sigma, type="c"):
"Calculate BS price of call/put"
d1 = (np.log(S/K) + (r + sigma**2/2)*T)/(sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
try:
if type == "c":
price = S*norm.cdf(d1, 0, 1) - K*np.exp(-r*T)*norm.cdf(d2, 0, 1)
elif type == "p":
price = K*np.exp(-r*T)*norm.cdf(-d2, 0, 1) - S*norm.cdf(-d1, 0, 1)
return price, bs(type, S, K, T, r, sigma)
except:
print("Please confirm option type, either 'c' for Call or 'p' for Put!")
In [4]
def delta_calc(r, S, K, T, sigma, type="c"):
"Calculate delta of an option"
d1 = (np.log(S/K) + (r + sigma**2/2)*T)/(sigma*np.sqrt(T))
try:
if type == "c":
delta_calc = norm.cdf(d1, 0, 1)
elif type == "p":
delta_calc = -norm.cdf(-d1, 0, 1)
return delta_calc, delta(type, S, K, T, r, sigma)
except:
print("Please confirm option type, either 'c' for Call or 'p' for Put!")
In [5]
def gamma_calc(r, S, K, T, sigma, type="c"):
"Calculate gamma of a option"
d1 = (np.log(S/K) + (r + sigma**2/2)*T)/(sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
try:
gamma_calc = norm.pdf(d1, 0, 1)/(S*sigma*np.sqrt(T))
return gamma_calc, gamma(type, S, K, T, r, sigma)
except:
print("Please confirm option type, either 'c' for Call or 'p' for Put!")
In [6]
def vega_calc(r, S, K, T, sigma, type="c"):
"Calculate BS price of call/put"
d1 = (np.log(S/K) + (r + sigma**2/2)*T)/(sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
try:
vega_calc = S*norm.pdf(d1, 0, 1)*np.sqrt(T)
return vega_calc*0.01, vega(type, S, K, T, r, sigma)
except:
print("Please confirm option type, either 'c' for Call or 'p' for Put!")
In [7]
def theta_calc(r, S, K, T, sigma, type="c"):
"Calculate BS price of call/put"
d1 = (np.log(S/K) + (r + sigma**2/2)*T)/(sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
try:
if type == "c":
theta_calc = -S*norm.pdf(d1, 0, 1)*sigma/(2*np.sqrt(T)) - r*K*np.exp(-r*T)*norm.cdf(d2, 0, 1)
elif type == "p":
theta_calc = -S*norm.pdf(d1, 0, 1)*sigma/(2*np.sqrt(T)) + r*K*np.exp(-r*T)*norm.cdf(-d2, 0, 1)
return theta_calc/365, theta(type, S, K, T, r, sigma)
except:
print("Please confirm option type, either 'c' for Call or 'p' for Put!")
In [8]
def rho_calc(r, S, K, T, sigma, type="c"):
"Calculate BS price of call/put"
d1 = (np.log(S/K) + (r + sigma**2/2)*T)/(sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
try:
if type == "c":
rho_calc = K*T*np.exp(-r*T)*norm.cdf(d2, 0, 1)
elif type == "p":
rho_calc = -K*T*np.exp(-r*T)*norm.cdf(-d2, 0, 1)
return rho_calc*0.01, rho(type, S, K, T, r, sigma)
except:
print("Please confirm option type, either 'c' for Call or 'p' for Put!")
In [9]
# Define variables
r = 0.053
S = 89.61
K = 89.50
T = 90/365
sigma = 0.12
option_type='c'
print("Call Price: ", [round(x,3) for x in blackScholes(r, S, K, T, sigma, option_type)])
print(" Delta: ", [round(x,3) for x in delta_calc(r, S, K, T, sigma, option_type)])
print(" Gamma: ", [round(x,3) for x in gamma_calc(r, S, K, T, sigma, option_type)])
print(" Vega : ", [round(x,3) for x in vega_calc(r, S, K, T, sigma, option_type)])
print(" Theta: ", [round(x,3) for x in theta_calc(r, S, K, T, sigma, option_type)])
print(" Rho : ", [round(x,3) for x in rho_calc(r, S, K, T, sigma, option_type)])
option_type='p'
print("Put Price: ", [round(x,3) for x in blackScholes(r, S, K, T, sigma, option_type)])
print(" Delta: ", [round(x,3) for x in delta_calc(r, S, K, T, sigma, option_type)])
print(" Gamma: ", [round(x,3) for x in gamma_calc(r, S, K, T, sigma, option_type)])
print(" Vega : ", [round(x,3) for x in vega_calc(r, S, K, T, sigma, option_type)])
print(" Theta: ", [round(x,3) for x in theta_calc(r, S, K, T, sigma, option_type)])
print(" Rho : ", [round(x,3) for x in rho_calc(r, S, K, T, sigma, option_type)])
На выходе после запуска кода получаем следующий расчет:
В In [9] меняем следующие параметры под себя:
r - ставка
s - спот
k - страйк
t - время до экспирации
sigma - волатильность
Больше идей и разборов в нашем Телеграм 👍