業務でC#を用いることになったので、最近勉強していなくて朧気になってきた知識をReviseする意味でも、以下の書籍を読みながらC#で実装してみる。今日はP.49-54まで。
3. 確率論の基礎
3.8 Markovの不等式
確率論において非常に有用な式の1つとしてMarkovの不等式がある。
任意の確率変数および非負の関数、について
が成り立つ。
(任意の事象に対して特性関数を定義する。確率変数に対してとおけば、集合に対して
が成り立つ。
両辺の期待値を取れば
これをまとめて
が得られる。
この定理により、たとえばとすれば、ある一定値よりも外れた値が得られる確率を期待値を用いて評価するなど、確率を評価することが出来る。またこの不等式において
とおくと、Markovの定理の特殊版としてChebyshevの定理が得られる:
任意の正数に対して
が成り立つ。実際、
である。
このChebyshevの不等式を用いることで、平均からの乖離が一定以上になる確率を分散(標準偏差)を用いて評価することができる。特にポイントなのは、正規分布にしか成り立たないというような分布に対する仮定を何も置いていない点である。すなわち、どのような分布にも適用できることがこの不等式の良い所である。
例:
正規分布を考えると、まずChebyshevの不等式から
すなわち、確率変数が一定値以内に収まる確率が一定値()以上ではあるという評価ができる。
また、正規分布であることに注目すれば
すなわち、確率変数が一定値以内に収まる確率は解析的に求まる。ここでは標準正規分布の分布関数である。
そこでChebyshevの不等式による不等式評価結果と解析的に計算した確率値を比較してみると下表のようになる:
1.不等式 2.解析値 0.5 -3.0000 0.3829 1 0.0000 0.6827 1.5 0.5556 0.8664 2 0.7500 0.9545 2.5 0.8400 0.9876 3 0.8889 0.9973 3.5 0.9184 0.9995 4 0.9375 0.9999 4.5 0.9506 1.0000 5 0.9600 1.0000 5.5 0.9669 1.0000 6 0.9722 1.0000
このように、
- 確率の評価範囲がよりも大きくないと評価自体ができない(確率は以上であるのが自明なので)。
- 評価範囲が程度にはならないと評価が粗すぎる(無論、正規分布だから言えること)。
3.9 C#での実装
using System; using MathNet.Numerics; /// <summary> /// 株式を原資産とするオプションの期待利得を数値積分により返す /// </summary> /// <param name="S"></param> /// <param name="K"></param> /// <param name="T"></param> /// <param name="Mean"></param> /// <param name="Std"></param> /// <param name="CallPutFlg"></param> /// <returns>株式を原資産とするオプションの期待利得</returns> public static double OptionPayOffNumericalIntegration(double S, double K, int T, double Mean, double Std, int CallPutFlg) { if (CallPutFlg == 0 | CallPutFlg == 1) { double h = Math.Pow(10.0, -4.0); double ret = 0.0; double PO; double x_max; double x_min; if (CallPutFlg == 0) { x_max = 5.0; x_min = Math.Log(K / S); } else { x_max = Math.Log(K / S); x_min = -5.0; } int n = (int)((x_max - x_min) / h); if (CallPutFlg == 0) { for (int i = 1; i < n; i++) { double x0 = (i - 1) * h + x_min; double x1 = i * h + x_min; PO = 0.0; PO += (S * Math.Exp(x0) - K) * Math.Exp(-0.5 * Math.Pow((x0 - Mean) / Std, 2.0)); PO += (S * Math.Exp(x1) - K) * Math.Exp(-0.5 * Math.Pow((x1 - Mean) / Std, 2.0)); PO *= 0.5; PO *= h; ret += PO; } } else { for (int i = 1; i < n; i++) { double x0 = (i - 1) * h + x_min; double x1 = i * h + x_min; PO = 0.0; PO += (K - S * Math.Exp(x0)) * Math.Exp(-0.5 * Math.Pow((x0 - Mean) / Std, 2.0)); PO += (K - S * Math.Exp(x1)) * Math.Exp(-0.5 * Math.Pow((x1 - Mean) / Std, 2.0)); PO *= 0.5; PO *= h; ret += PO; } } return ret; } else { return -999999; } }