Внедрение модели Блэка-Шоулза в 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 - волатильность

Больше идей и разборов в нашем Телеграм 👍

Внедрение модели Блэка-Шоулза в Python
2
1 комментарий