前回の記事では、オプション計算機を作成したことを紹介した。
計算式が分かれば、オプション計算機を作ることはそんなに難しくない。
(ExcelやC#の知識があれば)
今回は、オプション計算機の作り方を紹介しようと思う。
なお、ここではExcelやC#の初歩的な知識があることを前提とする。
まずは、計算式から。
ブラックショールズモデル(BSモデル)の計算式
BSモデルのコールオプション価格(C)およびプットオプション価格(P)の計算式は以下。
$$C=SN(d1)-e^{-RT}KN(d2)$$
$$P=-SN(-d1)+e^{-RT}KN(-d2)$$
ここで、
$$d1=\frac{ln(\frac{S}{K})+(R+\frac{V^2}{2})T}{V\sqrt{T}}$$
$$d2=d1-V\sqrt{T}$$
そして、
S:原資産価格(前回の記事ではこの値を「ミニ先物価格\(\times e^{-RT}\)」とした)
K:権利行使価格
R:無リスク利子率(%)/100
T:SQまでの残日数(日)/365
V:ボラティリティ(%)/100
N():標準正規分布の累積分布関数
BSモデルのギリシャ指標の計算式は以下。
$$デルタ(コール)=N(d1)$$
$$デルタ(プット)=-N(-d1)=N(d1)-1$$
$$ガンマ(コール)=ガンマ(プット)=\frac{N'(d1)}{VS\sqrt{T}}$$
$$ベガ(コール)=ベガ(プット)=N'(d1)S\sqrt{T}$$
$$シータ(コール)=\frac{-VSN'(d1)}{2\sqrt{T}}-RKe^{-RT}N(d2)$$
$$シータ(プット)=\frac{-VSN'(d1)}{2\sqrt{T}}+RKe^{-RT}N(-d2)$$
ここで、
$$N'(d1)=\frac{1}{\sqrt{2π}}e^{-\frac{d1^2}{2}}$$
$$π:円周率$$
注意事項として、
・ベガは上記数式では、100%ベガなので1%ベガにするためには、上記計算結果に対し100で割る必要がある。
・シータは上記数式では、1年シータなので1日シータにするためには、上記計算結果に対し365で割る必要がある。
ブラック76モデルの計算式
ブラック76モデルのコールオプション価格(C)およびプットオプション価格(P)の計算式は以下。
$$C=e^{-RT}[ FN(d1)-KN(d2) ]$$
$$P=e^{-RT}[-FN(-d1)+KN(-d2)]$$
ここで、
$$d1=\frac{ln(\frac{F}{K})+\frac{V^2}{2}T}{V\sqrt{T}}$$
$$d2=d1-V\sqrt{T}$$
そして、
F:原資産価格(前回の記事ではこの値を「ミニ先物価格」とした)
他の項はBSモデル同様。
ブラック76モデルのギリシャ指標の計算式は以下。
$$デルタ(コール)=e^{-RT}N(d1)$$
$$デルタ(プット)=e^{-RT}[N(d1)-1]$$
$$ガンマ(コール)=ガンマ(プット)=e^{-RT}\frac{N'(d1)}{VF\sqrt{T}}$$
$$ベガ(コール)=ベガ(プット)=e^{-RT}N'(d1)F\sqrt{T}$$
$$シータ(コール)=-e^{-RT}VF\frac{N'(d1)}{2\sqrt{T}}+RC$$
$$シータ(プット)=-e^{-RT}VF\frac{N'(d1)}{2\sqrt{T}}+RP$$
N'(d1)はBSモデル同様。
ベガ、シータに関する注意事項はBSモデル同様。
前回の記事で書いたように、じっくり両モデルの式を見比べれば、
原資産価格=ミニ先物価格\(×e^{-RT}\) としたBSモデル
と
原資産価格=ミニ先物価格 としたブラック76モデル
では、
コール価格、プット価格、ベガについてはどちらのモデルでも同じ値となることが分かる。
また、R=0のとき、デルタ、ガンマ、シータの値も一致することが分かる。
(注 \(e^0=1\))
オプション価格ならびにギリシャ指標の計算
一般的なオプション計算機であれば、S,K,R,T,Vの値を入力し、BSモデルの式を用いてオプション価格ならびにギリシャ指標を計算するものになるだろう。
前回の記事で紹介した日経225オプションの計算機では、F,K,R,T,Vの値を入力し、BSモデルおよびブラック76モデルの両方を計算した(Excel版)。
このとき、BSモデルではSの項に \(F×e^{-RT}\) の値を使った。
Sの項に日経平均を用いても良いのかも知れないが、問題をはらんでいることを前回の記事で書いた。
Excelの場合、下図のように、F,K,R,T,Vの入力用のセルを設け、そこに値を入力すれば良い。
そして、d1、d2、N(d1)など何度も出てくる項を計算するセルを作成しておけば便利だ。
目障りであれば、完成後に行を非表示にしておけば良い。
C#の場合、F,K,R,T,Vを入力する画面を作成しておく必要があるが、その説明は割愛する。
前回の記事での画面フォーム例を参考に、ラベルやテキストボックスを配置すれば良い。
Excel、C#とも計算に必要な関数は用意されている。
\(ln(x)\)は、
Excel:LN(x)
C#:Math.Log(x)
\(e^x\)は、
Excel:EXP(x)
C#:Math.Exp(x)
\(\sqrt{x}\)は
Excel:SQRT(x)
C#:Math.Sqrt(x)
円周率は、
Excel:PI()
C#:Math.PI
\(N(x)\)は、
Excel:NORMSDIST(x)(上図の赤枠を参照)
C#:NormalDistribution(x)
C#の場合、なぜかChartクラスの奥深くにあるので、次のように関数を作っておけば便利だ。
// ***** 標準正規分布の累積分布関数 *****
private Chart ch = new Chart();
public double NormSDist(double x)
{
return ch.DataManipulator.Statistics.NormalDistribution(x);
}
ここで、事前設定として、
・System.Windows.Forms.DataVisualization.dll を参照設定しておく必要がある。
・using System.Windows.Forms.DataVisualization.Charting; を記述しておく必要がある。
以上見てきたように、オプション価格ならびにギリシャ指標の計算に必要な関数が揃っているので、難しくない。
四則演算するだけだ。
IVを逆算するプログラム
インプライドボラティリティ(IV)を逆算するアルゴリズムは次のようになる。
1.IVを算出する範囲の初期値を決める。
2.IVの範囲の中間点の値を求める。
3.2の値を元にオプション価格を計算する。
4.3の結果と実際のオプション価格を比較する。
5.3の結果の方が大きい場合、IVの算出範囲の後側を2の値とし、
5’.そうでない場合、IVの算出範囲の前側を2の値とし、IVを算出する範囲を狭める。
6.2に戻り、2~5’を繰り返す。
7.IV算出範囲が十分に小さくなるか、所定のループ回数に達したら、終了する。
8.終了直前の2の値がIVの値となる。
これを図で示すと下図のようになる。
以下がC#のコード例。
// ********************************* IV逆算 *********************************
public double Cal_IV(bool bCall, double R, double T, double S, double K, double Price)
{
// bCall:コールのIV計算時はTrue、プットのIV計算時はFalse
// Price:コールのIV計算時はコールの価格を、プットのIV計算時はプットの価格を与える
int cnt = 0; // ループカウンター
double IV_min = 0; // IV計算範囲最小値 初期値=0%
double IV_max = 1; // IV計算範囲最大値 初期値=100%
double IV_mid, P_mid, d1, d2;
IV_mid = (IV_min + IV_max) / 2; // IVの中間値初期値
do
{
// 中間値でオプション価格計算
d1 = Cal_d1(S, K, IV_mid, T, R); // d1
d2 = Cal_d2(d1, IV_mid, T); // d2
P_mid = Cal_OptionPrice(bCall, R, T, S, K, d1, d2); // オプション価格
if ( Price < P_mid) // 実際のオプション価格と中間値で計算した価格を比べる
{
IV_max = IV_mid; // 中間値では値が大きいので、今回の中間値が次回の最大値となる
}
else
{
IV_min = IV_mid; // 中間値では値が小さいので、今回の中間値が次回の最小値となる
}
IV_mid = (IV_min + IV_max) / 2; // IVを計算範囲の中間値で仮置きする
if (++cnt >= 1000) break; // ループ回数上限
}
while (Math.Abs(IV_min - IV_max) > 0.000001); // ループ継続条件
return IV_mid;
}
注意事項として、
上記プログラムでは、IV計算範囲の初期値を0~1(0~100%)としているため、IVが100%を超える場合、正しい結果が得られない。
(99.9999…%として出力される。)
この、「Cal_IV」は、画面に配置された『IV逆算』ボタンのクリックイベント処理で呼び出される。
(呼び出し箇所は割愛する。)
また、d1、d2ならびにオプション価格を計算する関数のコードは下記。
なお、オプション価格の計算式はBSモデル。
そして、先ほど紹介した「NormSDist」を使っている。
// オプション価格計算(bCall:コールの計算時はTrue、プットの計算時はFalseを呼び出し側で付与する) public double Cal_OptionPrice(bool bCall, double R, double T, double S, double K, double d1, double d2) { double Ret = bCall ? S * NormSDist(d1) - K * Math.Exp(-R * T) * NormSDist(d2): // コール -S * NormSDist(-d1) + K * Math.Exp(-R * T) * NormSDist(-d2); // プット return Ret; } // d1値計算 public double Cal_d1(double S, double K, double V, double T, double R) { return (Math.Log(S / K) + (R + V * V / 2) * T) / (V * Math.Sqrt(T)); } // d2値計算 public double Cal_d2(double d1, double V, double T) { return (d1 - V * Math.Sqrt(T)); }
Excel版ではIVを逆算するプログラムを作っていないので、残念ながら紹介できない。
さすがにセル関数では無理かと思う。マクロ(VBA)を組む必要があるだろう。