技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

ブラックショールズモデルを解説してみる(株価モデル編)

Black scholes equation

ブラックショールズモデルを解説してみる

金融工学の金字塔的存在であるブラックショールズ方程式。

これまで自分で勉強する中で概念的な解説というのが今までほとんどなかった。たいていの入門書は確率解析の基礎的な解説、つまり測度論、確率論、マルチンゲール……と解説が終わったころにやっとブラックショールモデルや株価モデルという概念が出てくるといった具合のものが多い。けれども「株の値動きをシミュレーションしたい」「とにかく何を言っているかを知りたい」というだけの人には実はそこまで詳しい話は不要だ。それに株価予想なんかの機械学習が流行っている昨今そういったモチベーションを持っている人は少なくないかもしれない。

そこでここでは株価のモデルについて解説した後、この方程式って何を言ってるの?という概念的な理解を目指す。
確率微分方程式を使って解析解を求めてやろう…という難しい話はしない、勉強する前の自分に向けてイメージを掴んで貰うためのつもりで書く。
思いの外記事が膨大になったので、第一回で基礎となる株価モデルの考え方について説明し、第二回でその先のブラック・ショールズ方程式について解説する。

「株価モデル」って何?

金融工学の世界では「株価モデル」が頻繁に登場する。つまりは株価の値動きを数理的にモデル化したものである。
ここでは最もベーシックなブラックモデルのベースとなる株価モデルを解説する。実務に使う厳密な計算にはSABRモデルなどもう少し複雑なモデルも使われることがある。*1
*2

株価のモデル化は大きく3つの仮定から出発する。

1. 株として資産を保有する場合の利率は期待値で見れば銀行に預金する場合の利率と同じになるはず。
2. これまでの情報をどれだけ使っても次の一瞬に関して株価が上がるか下がるかわからない。
3. 100円の株が1円分動くのと1000円の株が10円動くのは同じ価値。

1つ目の仮定でわかりやすく銀行の預金金利と表現したものは、正確には国債などの安全資産の利率*3のことで、リスクフリーレートと呼ぶ。
株価モデルはこの3つの仮定から出発する。*4

ではこの仮定を使って株価の値動きを数式で表現してみよう。
ある時点tの株価がS_tとする。この時、S_{t+dt}の株価はどうなるだろう。

まず1つ目の仮定を表現する。

株として資産を保有する場合の利率は期待値で見れば銀行に預金する場合の利率と同じになるはず。

「利率」とはつまり単位時間あたりの値上がりの割合であるから、リスクフリーレートをrとすると時間dt進んだ時資産は rS_tdtだけ増えることになる。
S_{t+dt} = S_t + rS_tdt

次に2つ目の仮定を見てみよう。

これまでの情報をどれだけ使っても次の一瞬に関して株価が上がるか下がるかわからない。

値動きは完全にランダムであり過去の値動きの形は関係ない、ということだ。
ここで時間dtの間のランダムさを考える。
値幅(標準偏差)を\sigmaとすると単位時間あたりの動きの分布が正規分布を用いてN(0,\sigma^2)になると考える。
時間dt後の確率分布に従う確率変数を\Delta XN(0,\sigma^2)に従う確率変数を Xとすると
 \Delta X + \Delta X + ... \Delta X = X
 V[\Delta X + \Delta X + ... \Delta X ] = V[X]
 (1/dt)V[\Delta X] = V[X]
 V[\Delta X] = V[X] dt = \sigma^2 dt
となる。
よって時間dtに動くランダムさは\Delta N(\mu, \sigma^2) = N(0,\sigma^2 dt) = \sigma N(0, dt)なので*5
 dW = N(0, dt)とおいて元のモデルに組み込むと
S_{t+dt} = S_t + rS_tdt + \sigma dW

※この方程式が確率微分方程式と言われ、単純な微分方程式と違うところはこのランダム項" dW"が出てくるところだ。単純和であれば正規分布の和の性質を使えばいいだけだが、実際の世界では e^{dW}などの表現が出てくるので複雑になってくる。

最後に3つ目の仮定を考慮する。

100円の株が1円分動くのと1000円の株が10円動くのは同じ価値。

ランダムな動きの値幅はその時の価格に比例する。
S_{t+dt} = S_t + rS_tdt + \sigma S_t dW

これで3つの仮定をモデルに落とし込む事ができた。
これが株価の動きを数式にしたものとなる。

式の整理

最後に式を整理する。
S_{t+dt} - S_t = S_t (rdt + \sigma dW)
ここで
dS = S_{t+dt} - S_t
とすると

 \displaystyle \frac{dS}{S} = rdt + \sigma dW
となる。
特に右辺の第一項をドリフト項、第二項をランダム項と呼ぶ

それではこの株価モデルをプログラムでシミュレーションしてみる。

実装

少しだけ解説

金融工学の世界では「単位時間」は通常1年間を指す。
そのため金利は年利が使われるし、ボラティリティも1年の値幅を N(0, \sigma^2)としたときの割合で考える。

ドリフト項

リスクフリーレートは通常年利の形で書かれている。
実務では1年以内の期間計算は単利として計算するため、1日あたりの金利はリスクフリーレートを365日で割ったものとなる。*6

ランダム項

ランダム項に関しては正規分布の性質から
 \displaystyle N(0, 1/365) = \frac{N(0,1)}{\sqrt{365}}
となる点に注意

以上に注意すると、1ステップあたりの増分は
 \displaystyle S_t(r/365 + \sigma \frac{N(0,1)} {\sqrt{365}})
となる。

import numpy as np
import matplotlib.pyplot as plt

size_t = 1200 #1200日
dw = np.random.randn(size_t)
price = np.zeros(size_t)
rf_rate = 0.01 #リスクフリーレート(年利1%)
sigma = 0.12 #ボラティリティ(12%)
price[0] = 100 #初期値
for i in range(1, size_t):
    price[i] = price[i-1] * (1 + rf_rate / 365 + sigma * dw[i] / np.sqrt(365)) 

plt.plot(price)
plt.show()

50パスまとめて可視化してみる

def generate_path(days):
    size_t = days
    dw = np.random.randn(size_t)
    price = np.zeros(size_t)
    rf_rate = 0.01
    sigma = 0.12
    price[0] = 100
    for i in range(1, size_t):
        price[i] = price[i-1] * (1 + rf_rate / 365 + sigma * dw[i] / np.sqrt(365)) 
    return price

for i in range(50):
    path = generate_path(1200)
    plt.plot(path, alpha=0.5)
plt.show()

次回はいよいよブラック・ショールズ方程式について解説しようと思う。


suzuri.jp

*1:SABR volatility model - Wikipedia

*2:実務においては株(Equity)だけでなく金利(Interest Rate)を原資産にした商品もあり、特に金利に関してはマイナス金利をモデルに入れるために改良されたHullWhiteモデルなどがある。

*3:もっと正確に言えばリスクフリーレートの指標はOIS(オーバーナイトインデックススワップ)の市中金利などが用いられるhttps://www.mof.go.jp/public_relations/finance/202112/202112e.html

*4:これらの仮定が成り立たないとすれば一方的に儲かる取引が存在することになる。これを裁定取引というが、金融の世界では一方的に儲けられる取引は存在しないと言う大前提が置かれている

*5:正規分布の再生性

*6:うるう年も関係なく365日で割る。金利の種類によっては360日で計算するものもある。そういった金融商品ごとの計算の取り決めはデイカウントコンベンションと呼ぶ。ACT/365, ACT/ACT, ACT/360など。国ごとに慣習がちがう。そのためクロスカレンシーなどでは扱いがややこしい。