見出し画像

第10章:ベイジアンML-ダイナミックSR 第5節: 確率的ボラティリティモデル

インポートと設定

import warnings
warnings.filterwarnings('ignore')
%matplotlib inline

from pathlib import Path

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import seaborn as sns

import pymc3 as pm
from pymc3.distributions.timeseries import GaussianRandomWalk
sns.set_style('whitegrid')
# model_path = Path('models')

モデルの仮定

資産価格は時変ボラティリティ(日ごとの収益の変動)を持っています。一部の期間では、株価は非常に変動しやすく、他の期間では非常に安定しています。確率的ボラティリティモデルは、潜在的ボラティリティ変数を使用してこれをモデル化し、確率過程としてモデル化します。

次のモデルは、No-U-Turn Samplerの論文、Hoffman(2011)p21で説明されているモデルに似ています。

σ~Exponential(50)
v~Exponential(0.1)
s_i ~ Normal(s_{i-1}, σ^{-2})
log(r_i) ~ t(v, 0, exp(-2s_i))

ただし、rは日次リターンでsは潜在的ログボラティリティ過程

価格データの取得

今回はS&P 500を使います。

prices = pd.read_hdf('../data/assets.h5', key='sp500/stooq').loc['2000':, 'close']
log_returns = np.log(prices).diff().dropna()
ax = log_returns.plot(figsize=(15, 4),
                     title='S&P 500 | Daily Log Returns',
                     rot=0)
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
sns.despine()
plt.tight_layout();

画像1

PyMC3でモデルを特定する。

with pm.Model() as model:
   step_size = pm.Exponential('sigma', 50.)
   s = GaussianRandomWalk('s', sd=step_size, 
                          shape=len(log_returns))
   nu = pm.Exponential('nu', .1)
   r = pm.StudentT('r', nu=nu, 
                   lam=pm.math.exp(-2*s), 
                   observed=log_returns)
pm.model_to_graphviz(model)

画像2

モデルのフィッティング

with model:
   trace = pm.sample(tune=2000, 
                     draws=5000,
                     chains=4,
                     cores=1,
                     target_accept=.9)

結果の評価

痕跡プロット

pm.traceplot(trace, varnames=['sigma', 'nu']);

画像3

インサンプル予測

pm.trace_to_dataframe(trace).info()
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4000 entries, 0 to 3999
Columns: 5032 entries, s__0 to nu
dtypes: float64(5032)
memory usage: 153.6 MB
'''
fig, ax = plt.subplots(figsize=(15, 5))

log_returns.plot(ax=ax, lw=.5, xlim=('2000', '2020'), rot=0, 
            title='In-Sample Fit of Stochastic Volatility Model')

ax.plot(log_returns.index, np.exp(trace[s]).T, 'r', alpha=.03, lw=.5);

ax.set(xlabel='Time', ylabel='Returns')
ax.legend(['S&P 500 (log returns)', 'Stochastic Volatility Model'])
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y))) 
sns.despine()
fig.tight_layout();

画像4





この記事が気に入ったらサポートをしてみませんか?