業務でC#を用いることになったので、最近勉強していなくて朧気になってきた知識をReviseする意味でも、以下の書籍を読みながらC#で実装してみる。今日はP.16まで。
2. グリークス
オプションは、理論価格があるために、入力パラメータが明示的にわかっている。あらためて挙げるとこのとおり:
このため、この5つの変化がオプション価格に影響を与える。そこでリスク(価格変化)を管理するには、それらが変化したときにオプション価格がどの程度動くかを評価する。各パラメータに対する価格変化の指標をまとめてグリークス(Greeks)という。
あるパラメータ(他のパラメータは固定)に対してオプション価格をのまわりでTaylor展開してみると、として
が成り立つ。がそこまで大きくなければ、1次項または2次項(1次微分もしくは2次微分)を評価すればリスク管理としては充分と言える。つまり、
に注目することになる。2.1 デルタ
原資産価格の変化はもっとも重要なパラメータであるから、原資産価格の動きに対するオプション価格の変化がもっとも重要なリスク管理尺度である。
原資産価格の変化に対するオプション価格の変化をデルタという。
なおプット・オプションのデルタは、プット・コール・パリティを用いれば*1
となることから分かる。
さらに展開してみよう。
である。ここに
を代入することで
さらに
にの定義から得られる
を代入して得た、
を代入することで
を得る。
なおプット・オプションについては
まとめよう:
- コール・オプションのデルタ
- プット・オプションのデルタ
2.2 ガンマ
原資産価格の変化がもっとも重要であることは既に述べた。それだけでなく原資産価格はそれなりに大きく動くことがあるため、その変化による価格変化としてデルタのみで捉えようとすると誤差が大きくなってしまう可能性がある。そこで二次微分まで考える。
原資産価格の変化に対するデルタの変化、すなわち原資産価格の変化に対するオプション価格の二次微分としてガンマを以下で定義する:
これを展開してみよう。の対称性、すなわちに注意すれば
が得られる。
まとめよう:
- コール・オプションのガンマ
- プット・オプションのガンマ
2.3 C#での実装
コール(プット)・オプションのデルタを実装した。なお理論値と数値微分による数値解の2つを実装した。またデルタの数値微分は前回実装したオプション価格を出力するメソッド*2を数値的に二次微分している。
using System; using MathNet.Numerics; /// <summary> /// デルタの理論値を返す。 /// </summary> /// <param name="S">原資産価格</param> /// <param name="K">行使価格</param> /// <param name="r">リスクフリーレート</param> /// <param name="sigma">原資産価格のボラティリティ</param> /// <param name="T">満期までの期間</param> /// <param name="CallPutFlg">コール・プットを表すフラグ。0ならばコール・オプション、1ならばプット・オプションの価格を返す。</param> /// <returns>コール・オプションまたはプット・オプションのデルタ。</returns> public static double Delta(double S, double K, double r, double sigma, double T, int CallPutFlg) { double d = Math.Log(S/K) + (r + 0.5 * Math.Pow(sigma, 2.0)) * T; d /= (sigma * Math.Sqrt(T)); double Sign = -2.0 * (double)CallPutFlg + 1.0; double delta = Sign * MathNet.Numerics.Distributions.Normal.CDF(0.0, 1.0, Sign * d); return delta; } /// <summary> /// デルタの数値微分による値を返す。 /// </summary> /// <param name="S">原資産価格</param> /// <param name="K">行使価格</param> /// <param name="r">リスクフリーレート</param> /// <param name="sigma">原資産価格のボラティリティ</param> /// <param name="T">満期までの期間</param> /// <param name="CallPutFlg">コール・プットを表すフラグ。0ならばコール・オプション、1ならばプット・オプションの価格を返す。</param> /// <returns>コール・オプションまたはプット・オプションのデルタ。</returns> public static double DeltaByNumericalDifferential(double S, double K, double r, double sigma, double T, int CallPutFlg) { double Bin = 0.00001; double delta = OptionPricing(S + Bin,K,r,sigma,T,CallPutFlg); delta -= OptionPricing(S - Bin,K,r,sigma,T,CallPutFlg); delta /= (2.0 * Bin); return delta; } /// <summary> /// ガンマの理論値を返す。 /// </summary> /// <param name="S">原資産価格</param> /// <param name="K">行使価格</param> /// <param name="r">リスクフリーレート</param> /// <param name="sigma">原資産価格のボラティリティ</param> /// <param name="T">満期までの期間</param> /// <param name="CallPutFlg">コール・プットを表すフラグ。0ならばコール・オプション、1ならばプット・オプションの価格を返す。</param> /// <returns>コール・オプションまたはプット・オプションのガンマ。</returns> public static double Gamma(double S, double K, double r, double sigma, double T, int CallPutFlg) { double d = Math.Log(S / K) + (r + 0.5 * Math.Pow(sigma, 2.0)) * T; d /= (sigma * Math.Sqrt(T)); double Gamma = Math.Exp(-0.5 * Math.Pow(d, 2.0)); Gamma /= (S * sigma * Math.Sqrt(T) * Math.Sqrt(2 *Math.PI)); return Gamma; } /// <summary> /// ガンマの数値微分による値を返す。 /// </summary> /// <param name="S">原資産価格</param> /// <param name="K">行使価格</param> /// <param name="r">リスクフリーレート</param> /// <param name="sigma">原資産価格のボラティリティ</param> /// <param name="T">満期までの期間</param> /// <param name="CallPutFlg">コール・プットを表すフラグ。0ならばコール・オプション、1ならばプット・オプションの価格を返す。</param> /// <returns>コール・オプションまたはプット・オプションのガンマ。</returns> public static double GammaByNumericalDifferential(double S, double K, double r, double sigma, double T, int CallPutFlg) { double Bin = 0.001; double P_BinPlus = OptionPricing(S + Bin, K, r, sigma, T, CallPutFlg); double P = OptionPricing(S, K, r, sigma, T, CallPutFlg); double P_BinMinus = OptionPricing(S - Bin, K, r, sigma, T, CallPutFlg); double Gamma = P_BinPlus - 2.0 * P + P_BinMinus; Gamma /= Math.Pow(Bin, 2.0); return Gamma; }