ブラックショールズ方程式のPythonライブラリ
ブラックショールズ方程式のライブラリーです。自動取引の支援に使う予定です。基本的には一番下にある出典に全部載っています。
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 10 13:13:31 2024
@author: Lune 2121
IB/option_utils.py
"""
import numpy as np
from scipy.stats import norm
#https://www.codearmo.com/python-tutorial/options-trading-black-scholes-model
#https://www.macroption.com/black-scholes-formula/
"""
right = 'C' or 'P'
s = Spot Price
k = Strike Price
t = Days to expiration
rfr = Risk-free Rate
sigma = volatility
div = Annual dividend rate. Defaulted to zero.
price = Known option price. Necessary for implied_volatility function
"""
def d_one(s, k, t, rfr, sigma, div=0):
"""d1 calculation"""
d_1 = (np.log(s / k) +
(rfr - div + sigma ** 2 / 2) * t) / (sigma * np.sqrt(t))
return d_1
def d_two(s, k, t, rfr, sigma, div=0):
"""d2 calculation"""
d_2 = d_one(s, k, t, rfr, sigma, div) - sigma * np.sqrt(t)
return d_2
def nd_one(right, s, k, t, rfr, sigma, div=0):
"""nd1 calculation"""
if right == 'C':
nd_1 = norm.cdf(d_one(s, k, t, rfr, sigma, div), 0, 1)
elif right == 'P':
nd_1 = norm.cdf(-d_one(s, k, t, rfr, sigma, div), 0, 1)
return nd_1
def nd_two(right, s, k, t, rfr, sigma, div=0):
"""nd2 calculation"""
if right == 'C':
nd_2 = norm.cdf(d_two(s, k, t, rfr, sigma, div), 0, 1)
elif right == 'P':
nd_2 = norm.cdf(-d_two(s, k, t, rfr, sigma, div), 0, 1)
return nd_2
def option_price(right, s, k, t, rfr, sigma, div=0):
"""option price"""
right = right.upper()
t /= 365.0
s = abs(s)
k = abs(k)
if right == 'C':
if t <= 0:
if s > k:
price = s - k
else:
price = 0
else:
price = (s * np.exp(-div * t) *
nd_one(right, s, k, t, rfr, sigma, div)
- k * np.exp(-rfr * t) *
nd_two(right, s, k, t, rfr, sigma, div))
elif right == 'P':
if t <= 0:
if k > s:
price = k - s
else:
price = 0
else:
price = (k * np.exp(-rfr * t) *
nd_two(right, s, k, t, rfr, sigma, div)
- s * np.exp(-div * t) *
nd_one(right, s, k, t, rfr, sigma, div))
return price
def option_delta(right, s, k, t, rfr, sigma, div=0):
"""option delta"""
t /= 365
if right == 'C':
delta = np.exp(-div * t) * norm.cdf(d_one(s,k,t,rfr,sigma,div))
else:
delta = - np.exp(-div * t) * norm.cdf(-d_one(s,k,t,rfr,sigma,div))
return delta
def option_gamma(right, s, k, t, rfr, sigma, div=0):
"""option gamma"""
t /= 365
gamma = np.exp(-div*t)/s/sigma/np.sqrt(t) * norm.pdf(d_one(s,k,t,rfr,sigma,div))
return gamma
def option_theta(right, s, k, t, rfr, sigma, div=0): #r, S, K, T, sigma, type="c"):
"""option theta"""
t /= 365
if right == "C":
thetat = -s*np.exp(-div*t)*norm.pdf(d_one(s,k,t,rfr,sigma,div), 0, 1)*sigma/(2*np.sqrt(t)) \
- rfr*k*np.exp(-rfr*t)*norm.cdf(d_two(s,k,t,rfr,sigma), 0, 1) \
+ div*s*np.exp(-div*t)*norm.cdf(d_one(s,k,t,rfr,sigma,div),0,1)
else:
thetat = -s*np.exp(-div*t)*norm.pdf(d_one(s,k,t,rfr,sigma,div), 0, 1)*sigma/(2*np.sqrt(t)) \
+ rfr*k*np.exp(-rfr*t)*norm.cdf(-d_two(s,k,t,rfr,sigma,div), 0, 1) \
- div*s*np.exp(-div*t)*norm.cdf(-d_one(s,k,t,rfr,sigma,div),0,1)
theta = thetat/365
return theta
def option_vega(s, k, t, rfr, sigma, div=0):
"""option vega"""
t /= 365
vega = (.01 * s * np.exp(-div * t) * np.sqrt(t)
* norm.pdf(d_one(s, k, t, rfr, sigma, div)))
return vega
def implied_vol(right, s, k, t, rfr, market_price, div=0, tol=0.00001):
"""Compute the implied volatility of a European Option
s: stock price
k: strike
t: maturity
rfr: risk-free rate
market_price: market observed price
tol: tolerance
"""
max_iter = 200 #max number of iterations
vol_old = 0.30 #initial guess
for i in range(max_iter):
bs_price = option_price(right, s, k, t, rfr, vol_old, div)
Cprime = option_vega(s,k,t,rfr,vol_old, div)*100
C = bs_price - market_price
vol_new = vol_old - C/Cprime
bs_new = option_price(right, s, k, t, rfr, vol_new, div)
if (abs(vol_old - vol_new) < tol or abs(bs_new - market_price) < tol):
break
vol_old = vol_new
implied_vol = vol_old
return implied_vol
基本下のサイトを参考に作りました。
この記事が気に入ったらサポートをしてみませんか?