オプショングリークスの計算
ブラックショールズモデルにおけるオプショングリークスの計算式とプログラムを載せるだけ
何故か日本語で詳しく計算を追ってる記事が見つからなかったため
グリークスとは
株式に配当が含まれている場合の、ブラックショールズ方程式におけるヨーロピアンコール/プットオプション価格()は現在時刻t、原資産価格、ボラティリティ、行使価格K、無リスク金利r、配当利回りq、満期Tまでの時間によって決まる。具体的には以下の式
ただし、
グリークスとはこの式を各変数で偏微分したものであり、つまりは各変数に対するオプション価格の感応度を表したものである。 具体的には以下の通り1
計算
準備
この先度々出てくる式を先に計算する。
1.(微積分の交換)
2.
3.
4.(プットコールパリティ)
デルタ(Δ)
コール/プットオプションのデルタをそれぞれと表す。
コールのデルタ
ここで、
と(1)式より
が得られる。更に二項目は(2)式を用いることで、
であることから0である。従って、
プットのデルタ
(4)式より、
よって、
ガンマ(γ)
コール/プットオプションのデルタをそれぞれと表す。
コールのガンマ
デルタの計算結果を用いて以下のように計算することが出来る。
(1)式より、
プットのガンマ
(4)式より、
よって、
ベガ(ν)
コール/プットオプションのベガをそれぞれと表す。
コールのベガ
ここで、(1)式より
また、(3)式より
であるから
ここで、コールのガンマを求める際と同様に、第一項は0になる。従って
プットのベガ
(4)式より、
従って、
ロー(ρ)
コールのロー
ここで、
と(1)式より
コールのガンマを求める際と同様に、第二項は0であるので
プットのロー
(4)式より、
従って、
イプシロン(ε)
コールのイプシロン
ここで、
と(1)式より
コールのガンマを求める際と同様に、第二項は0であるので
プットのイプシロン
(4)式より
従って、
シータ(Θ)
コールのシータ
(1)式より
ここで、(3)式より
と(2)式より
プットのシータ
(4)式より
よって
従って
実装
pythonで各グリークスを実装する。
準備
共通する準備の部分
#グリークスを計算する。 #値の設定 K = 105; r = 0.01; q = 0.02; sigma = 0.3; tau = 0.1; #T - t ##d1,d2を計算する。 import math from scipy.stats import norm import matplotlib.pyplot as plt def d1(S,K,r,q,sigma,tau): d1 = (math.log(S/K) + (r - q + sigma**2 / 2) * tau) / (sigma * math.sqrt(tau)) return d1 def d2(S,K,r,q,sigma,tau): d1 = (math.log(S/K) - (r - q + sigma**2 / 2) * tau) / (sigma * math.sqrt(tau)) return d1 #株価のリストを作成 S_list = list(range(80,120)) d1_list = [] d2_list = [] #d1を計算する。 for i in S_list: d1_list.append(d1(i,K,r,q,sigma,tau)) #d2を計算する。 for i in S_list: d2_list.append(d2(i,K,r,q,sigma,tau))
デルタ
#デルタを求める。 ###コールのデルタ def call_delta(q,T,d1): delta = math.exp(- q * T) * norm.cdf(d1, loc = 0, scale = 1) return delta ###プットのデルタ def put_delta(q,T,d1): delta = - math.exp(- q * T) * norm.cdf(- d1, loc = 0, scale = 1) return delta ##コール、プットのデルタを計算し、格納する。 c_delta_list = [] p_delta_list = [] for i in range(len(S_list)): c_delta_list.append(call_delta(q,T,d1_list[i])) p_delta_list.append(put_delta(q,T,d1_list[i])))) #デルタをプロットする。 import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot(S_list, c_delta_list, label="CallDelta") ax.plot(S_list, p_delta_list, label="PutDelta") ax.set_title("Call and Put Delta") ax.legend(loc = 0) ax.set_xlabel("underlying asset price") ax.set_ylabel("Delta") plt.show();
ガンマ
#ガンマを求める ##ガンマを求める関数を定義 def gamma(S,sigma,tau,d): gamma = (1 / (S * sigma * math.sqrt(tau))) * (1 / math.sqrt(2 * math.pi)) * math.exp(- d ** 2 / 2) * math.exp(- q * tau) return gamma ##ガンマを実際に求め、値を格納する。 gamma_list = [] for i in range(len(S_list)): gamma_list.append(gamma(S_list[i],sigma,tau,d1_list[i])) ##ガンマをプロットする。 import matplotlib.pyplot as plt fig, ax = plt.subplots() plt.plot(S_list, gamma_list, label="Gamma") plt.title("Gamma") plt.xlabel("underlying asset price") plt.ylabel("Gamma") plt.show()
ベガ
#ベガを計算する。 ##ベガを計算する関数を定義する def vega(S,sigma,tau,d1): vega = S * math.sqrt(tau / (2 * math.pi)) * math.exp( -d1 ** 2 / 2 - q * tau) return vega ##ベガを実際に求める。 vega_list = [] for i in range(len(S_list)): vega_list.append(vega(S_list[i],sigma,tau,d1_list[i])) ##ベガをプロットする。 fig, ax = plt.subplots() plt.plot(S_list, vega_list, label="Vega") plt.title("Vega") plt.xlabel("underlying asset price") plt.ylabel("Vega") plt.show()
ロー
#ローを計算する。 ##ローを計算する関数を定義する ###コールのロー def call_rho(K,r,tau,d2): rho = K * tau * math.exp(-r * tau) * norm.cdf(d2, loc = 0, scale = 1) return rho ###プットのロー def put_rho(K,r,tau,d2): rho = -K * tau * math.exp(-r * tau) * norm.cdf(-d2, loc = 0, scale = 1) return rho ##ローを実際に求める。 c_rho_list = [] p_rho_list = [] for i in range(len(S_list)): c_rho_list.append(call_rho(K,r,tau,d2_list[i])) p_rho_list.append(put_rho(K,r,tau,d2_list[i])) #ローをプロットする。 fig, ax = plt.subplots() ax.plot(S_list, c_rho_list, label="CallRho") ax.plot(S_list, p_rho_list, label="PutRho") ax.set_title("Call and Put Rho") ax.legend(loc = 0) ax.set_xlabel("underlying asset price") ax.set_ylabel("Rho") plt.show();
イプシロン
#ローエフを計算する。 ##ローエフを計算する関数を定義する ###コールのローエフ def call_rhof(S,q,tau,d1): rhof = - S * tau * math.exp(- q * tau) * norm.cdf(d1, loc = 0, scale = 1) return rhof ###プットのローエフ def put_rhof(S,q,tau,d1): rhof = S * tau * math.exp(- q * tau) * norm.cdf(- d1, loc = 0, scale = 1) return rhof ##ローエフを実際に求める。 c_rhof_list = [] p_rhof_list = [] for i in range(len(S_list)): c_rhof_list.append(call_rhof(S_list[i],q,tau,d1_list[i])) p_rhof_list.append(put_rhof(S_list[i],q,tau,d1_list[i])) #ローエフをプロットする。 fig, ax = plt.subplots() ax.plot(S_list, c_rhof_list, label="CallRhof") ax.plot(S_list, p_rhof_list, label="PutRhof") ax.set_title("Call and Put Rhof") ax.legend(loc = 0) ax.set_xlabel("underlying asset price") ax.set_ylabel("Rhof") plt.show();
シータ
#シータを計算する。 ##コールのシータ def call_theta(S,K,r,q,sigma,tau,d1,d2): theta = q * S * math.exp(- q * tau) * norm.cdf(d1, loc = 0, scale = 1) - r * K * math.exp(- r * tau) * norm.cdf(d2, loc = 0, scale = 1) - S * sigma * math.exp(-q * tau) / (2 * math.sqrt(tau)) * (1 / math.sqrt(2 * math.pi)) * math.exp( - d1 ** 2 / 2) return theta ###プットのシータ def put_theta(S,K,r,q,sigma,tau,d1,d2): theta = - q * S * math.exp(- q * tau) * norm.cdf(- d1, loc = 0, scale = 1) + r * K * math.exp(- r * tau) * norm.cdf(- d2, loc = 0, scale = 1) - S * sigma * math.exp(-q * tau) / (2 * math.sqrt(tau)) * (1 / math.sqrt(2 * math.pi)) * math.exp( - d1 ** 2 / 2) return theta ##シータを実際に求める。 c_theta_list = [] p_theta_list = [] for i in range(len(S_list)): c_theta_list.append(call_theta(S_list[i],K,r,q,sigma,tau,d1_list[i],d2_list[i])) p_theta_list.append(put_theta(S_list[i],K,r,q,sigma,tau,d1_list[i],d2_list[i])) #シータをプロットする。 fig, ax = plt.subplots() ax.plot(S_list, c_theta_list, label="CallTheta") ax.plot(S_list, p_theta_list, label="PutTheta") ax.set_title("Call and Put Theta") ax.legend(loc = 0) ax.set_xlabel("underlying asset price") ax.set_ylabel("Theta") plt.show();
何か間違い等あればコメントで教えてください。
おわり