数値計算において解析解が存在しない場合は、収束計算により近似解を求めることができる。
収束計算の方法として、二分法、はさみうち法、ニュートン・ラフソン法、ブロイデン法等がある。
本稿では、Excel VBAを用いて、二分法とニュートン・ラフソン法による収束計算法について説明する。題材として、オプション取引に用いられるボラティリティの計算を取り上げた。
二分法
二分法とは、\(f(x)=0\)となる未知の\(x\)の両側に適当に\(x_1\)と\(x_2\)を置き、中点\(x_3=\dfrac{x_1+x_2}{2}\)を求める。その後、\(f(x_1)・f(x_3)<0\)であれば、\(x_2\)の値を\(x_3\)に置き換える。\(f(x_1)・f(x_3)>0\)であれば、\(x_1\)の値を\(x_3\)に置き換える。これらの操作を繰り返し行い、関数\(f(x)\)が0となる\(x\)を求める方法である。

ボラティリティを\(x\)、オプション価格の公式を\(g(x)\)、オプション価格を\(OV\)とした時に、
\(f(x)=g(x)-OV=0\)となる\(x\)を求めることを行っていく。
以下はオプションのボラティリティを求めるFunction関数F_Volatility_BのExcel VBAのコードである。第1~7パラメーターは、それぞれオプションタイプ(コール又はプット)、原資産価格、権利行使価格、無リスク金利、配当利回り、オプション価格、満期までの時間である。
\(myV_1\)、\(myV_2\)および\(myV_3\)は、上のグラフの\(x_1\)、\(x_2\)および\(x_3\)に対応する。また、\(myOV_1\)、\(myOV_2\)および\(myOV_3\)は、上のグラフの\(f(x_1)\)、\(f(x_2)\)および\(f(x_3)\)に対応する。コードでは、7~11行目で、\(x_1\)、\(x_2\)の初期値からそれぞれ\(f(x_1)\)、\(f(x_2)\)を計算している。13~24行目で、\(x_3\)を求めた後、\(f(x_1)・f(x_2)\)の符号により、\(x_1\)または\(x_2\)の値を\(x_3\)に置き換えることを、\(f(x)\)が\(10^{-6}\)未満になるまで繰り返し行い、\(x\)すなわちボラティリティを求めている。
なお、コード中にオプション価格を求めるFunction関数F_OptionValueを組み込んでいる。第1~7パラメーターは、オプションタイプ(コール又はプット)、原資産価格、権利行使価格、無リスク金利、配当利回り、ボラティリティ、満期までの時間である。このコードも下に示している。
(Function関数F_Volatility_Bのコード)
Function F_Volatility_B(myType As String, myS As Double, myK As Double, myR As Double, _
myQ As Double, myOV As Double, myT As Double) As Double
Dim myV1 As Double, myV2 As Double, myV3 As Double, myOV1 As Double, myOV2 As Double, _
myOV3 As Double
myV1 = 0.001
myV2 = 10
myOV1 = F_OptionValue(myType, myS, myK, myR, myQ, myV1, myT) - myOV
myOV2 = F_OptionValue(myType, myS, myK, myR, myQ, myV2, myT) - myOV
Do
myV3 = (myV1 + myV2) / 2
myOV3 = F_OptionValue(myType, myS, myK, myR, myQ, myV3, myT) - myOV
If myOV1 * myOV3 < 0 Then
myV2 = myV3
Else
myV1 = myV3
End If
Loop While Abs(myOV3) > 0.000001
F_Volatility_B = myV1
End Function(Function関数F_OptionValueのコード)
Function F_OptionValue(myType As String, myS As Double, myK As Double, myR As Double, myQ As Double, _
myV As Double, myT As Double) As Double
Dim myD1 As Double, myD2 As Double
If myT = 0 Then
myT = 0.000001
End If
myD1 = (Log(myS / myK) + (myR - myQ + ((myV) ^ 2) / 2) * myT) / (myV * Sqr(myT))
myD2 = (Log(myS / myK) + (myR - myQ - ((myV) ^ 2) / 2) * myT) / (myV * Sqr(myT))
Select Case myType
Case Is = "Call"
F_OptionValue = Exp(-myQ * myT) * myS * WorksheetFunction.Norm_S_Dist(myD1, True) _
- Exp(-myR * myT) * myK * WorksheetFunction.Norm_S_Dist(myD2, True)
Case Is = "Put"
F_OptionValue = -Exp(-myQ * myT) * myS * WorksheetFunction.Norm_S_Dist(-myD1, True) _
+ Exp(-myR * myT) * myK * WorksheetFunction.Norm_S_Dist(-myD2, True)
End Select
End Function
ニュートン・ラフソン法
過去の掲載記事「オプション取引シミュレーターを作る」でも取り上げたが、再度解説する。
ニュートン・ラフソン法とは、適当においた\(x_1\)での\(f(x)\)の接線\(f'(x_1)\)と\(x\)軸との交点\(x_2\)を先ず求める。次に\(x_2\)での\(f(x)\)の接線\(f'(x_2)\)と\(x\)軸との交点\(x_3\)を求める。この操作を繰り返し行い、\(x_4\)、\(x_5\)、・・・と順番に求め、関数\(f(x)\)が0となる\(x\)を求める方法である。

前章と同様に、ボラティリティを\(x\)、オプション価格の公式を\(g(x)\)、オプション価格を\(OV\)とした時に、\(f(x)=g(x)-OV=0\)となる\(x\)を求めることを行っていく。
以下はオプションのボラティリティを求めるFunction関数F_Volatility_NのExcel VBAのコードである。第1~7パラメーターは、それぞれオプションタイプ(コール又はプット)、原資産価格、権利行使価格、無リスク金利、配当利回り、オプション価格、満期までの時間である。
\(myV_1\)と\(myV_2\)は、上のグラフの\(x_1\)と\(x_2\)にそれぞれ対応する。また、\(myOV_1\)は\(f(x_1)\)に、\(myDV_1\)は\(x_1\)での\(f(x)\)の接線\(f'(x1)\)の傾きに対応する。コードでは、6行目で\(x_1\)を指定する。その後、8~15行目で\(x_1\)での\(f(x)\)の接線\(f'(x_1)\)とx軸との交点\(x_2\)を求める。同様の操作を、\(f(x)\)が\(10^{-6}\)未満になるまで繰り返し行い、\(x\)すなわちボラティリティを求めている。
なお、コード中にオプション価格を求めるFunction関数F_OptionValueとオプションのグリークス「ベガ」を求めるFunction関数F_Vegaを組み込んでいる。Function関数F_OptionValueのコードは前章で示した。Function関数F_Vegaの第1~7パラメーターは、それぞれオプションタイプ(コール又はプット)、原資産価格、権利行使価格、無リスク金利、配当利回り、ボラティリティ、満期までの時間である。このコードも下に示している。
(Function関数F_Volatility_Nのコード)
Function F_Volatility_N(myType As String, myS As Double, myK As Double, myR As Double, _
myQ As Double, myOV As Double, myT As Double) As Double
Dim myV1 As Double, myV2 As Double, myOV1 As Double, myDV1 As Double
myV1 = 10
Do
myOV1 = F_OptionValue(myType, myS, myK, myR, myQ, myV1, myT) - myOV
myDV1 = F_Vega(myType, myS, myK, myR, myQ, myV1, myT) * 100
myV2 = myV1 - myOV1 / myDV1
myV1 = myV2
Loop While myOV1 > 0.000001
F_Volatility_N = myV1
End Function(Function関数F_Vegaのコード)
Function F_Vega(myType As String, myS As Double, myK As Double, myR As Double, myQ As Double, _
myV As Double, myT As Double) As Double
Dim myD1 As Double, myD2 As Double
If myT = 0 Then
myT = 0.001
End If
myD1 = (Log(myS / myK) + (myR - myQ + ((myV) ^ 2) / 2) * myT) / (myV * Sqr(myT))
myD2 = (Log(myS / myK) + (myR - myQ - ((myV) ^ 2) / 2) * myT) / (myV * Sqr(myT))
F_Vega = Exp(-myQ * myT) * myS * WorksheetFunction.Norm_S_Dist(myD1, False) * myT
End Function計算した事例を、日経225オプションを例に示す。8月22日の取引終了後の2026年9月限のコールオプション価格より、各権利行使価格のボラティリティを計算したので、データと共にグラフに示した。
なお、各パラメーターはセルD2~D9、権利行使価格𝐾はC列12行目以降、コールオプション価格𝐶はD列12行目以降、二分法により計算したボラティリティ𝜎はE列12行目以降に、ニュートン・ラフソン法により計算したボラティリティ𝜎はF列12行目以降に記載した。二分法とニュートン・ラフソン法による計算結果は一致した。グラフからは、権利行使価格によりボラティリティが変化する様子が、ボラティリテイスマイルとして示されている。


