SVARモデルでBitcoinの時系列分析

Bitcoinを他の通貨の動きで予測したい

PythonでSVARモデルでの分析をしている記事をあまり見ないのと、Bitcoinと他の通貨の動きの相関に興味を持ったのでやってみました。
もちろんですが、Statsmodelsを使います。(ただし、StatsmodelsではSVARモデルのクラスはメソッドも少なく使いづらいです。真面目に分析するならRを使ったほうが無難だと思います…)

SVARモデルとはStructural vector autoregressionモデルの略で、日本語だと構造ベクトル自己回帰モデルになります。複数の関係し合った時系列データを分析するときに使います。普通は"VARモデル"という、頭に"S"がついてないモデルを使うんですが、VARモデルだと同時点間の関係を分析できないので、SVARを使います。今回は日次データを使うので、同日中の動きの関連性もみたいのでSVARモデルを使ってみました。グレンジャー因果性とかその辺は今回はパス。

データとしてはQuandlからダウンロードした為替の日次データ1年分を使います。ビットコイン円、米ドル円、ユーロ円。ついでに金価格も入れてみます。

今回のコードはJupyterからそのままMarkdownで書き出しているのでレイアウト崩れているかもしれません。ご容赦ください。

# 準備
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
import statsmodels.api as sm
import quandl  # データサイトQuandlからダウンロードするためのAPIラッパー。 pip install quandlでインストールできます。
import datetime
# 分析期間
start = datetime.datetime(2015, 8, 1)
end = datetime.datetime(2016, 7, 31)
# それぞれの通貨レートの終値とその変化率をpandas.DataFrameにする
btcjpy = quandl.get("BCHARTS/COINCHECKJPY", start_date=start, end_date=end).assign(
                    BTCJPY_roc = lambda df: df["Close"].pct_change()
                )[["Close", "BTCJPY_roc"]].rename(columns={
                    "Close" : "BTCJPY"
                })
usdjpy = quandl.get("BOE/XUDLJYD", start_date=start, end_date=end).assign(
                    USDJPY_roc = lambda df: df["Value"].pct_change()
                ).rename(columns={
                    "Value" : "USDJPY"
                })
eurjpy = quandl.get("BOE/XUDLBK63", start_date=start, end_date=end).assign(
                    EURJPY_roc = lambda df: df["Value"].pct_change()
                ).rename(columns={
                    "Value" : "EURJPY"
                })
gold = quandl.get("WGC/GOLD_DAILY_JPY", start_date=start, end_date=end).assign(
                    gold_roc = lambda df: df["Value"].pct_change()
                ).rename(columns={
                    "Value" : "Gold"
                })
# 変化率の列だけを連結して一つにまとめる
df = pd.concat([btcjpy["BTCJPY_roc"], usdjpy["USDJPY_roc"], eurjpy["EURJPY_roc"], gold["gold_roc"]],
                           axis=1).rename(columns={
        "BTCJPY_roc":"BTC/JPY",
        "USDJPY_roc": "USD/JPY",
        "EURJPY_roc":"EUR/JPY",
        "gold_roc":"Gold"
    }).dropna()  # NaNは落としておく
# 記述統計量見てみる
df.describe()

BTC/JPY

USD/JPY

EUR/JPY

Gold

count

251.000000

251.000000

251.000000

251.000000

mean

0.002296

-0.000729

-0.000653

0.000060

std

0.032348

0.007603

0.007698

0.009094

min

-0.195545

-0.034245

-0.054097

-0.029910

25%

-0.008390

-0.004295

-0.004483

-0.005644

50%

0.002404

-0.000280

-0.000384

-0.000142

75%

0.012727

0.003507

0.002984

0.005614

max

0.125846

0.020587

0.024218

0.024528

# プロットしてみる。ビットコインの変化率の激しさがよく分かる
df.plot().legend(bbox_to_anchor=(1.2, 0.5))
<matplotlib.legend.Legend at 0x115f9dfd0>

png

ここまではデータ整理です。ここから下がSVARモデルの話になります。

詳しいことは省きますが、ラグ\(p\)のSVARモデルは
\[
Ay_t = A_1 y_{t-1} + \ldots + A_p y_{t-p} + B\varepsilon_t
\]
と表されます。\(A, A_1, \dots, A_p, B \)は\(n \times n\)行列、\(y_t, y_{t-1}, \dots, y_{t-p}, \varepsilon_t\)は\(n\)次元ベクトルです。

Statsmodelsではこの式中の\(n \times n\)で表される係数を求めます。
ただし、\(A\)と\(B\)については行列中のどの要素を求めたいのか指定してあげないといけません。今回は時系列データが4つなので\(n=4\)です。

%%capture
# ↑Jupyterで出力させないときのおまじない
A_mat = np.array([[1,"E","E","E"], [0,1,0,0],[0,0,1,0],[0,0,0,1]])  # 上式のAの中で求めたい要素を"E"とする
svar_model = sm.tsa.SVAR(df, svar_type="A", A=A_mat)  # Aのみを推計したいときはsvar_type="A".  AもBも求めたいときはsvar_type="AB".
svar_result =svar_model.fit(maxlags=2)  # ラグは2にしておきます
svar_result.A  # 求められたA
array([[ 1.        , -0.59146287,  0.6685895 , -0.62556778],
       [ 0.        ,  1.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  1.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ,  1.        ]])
svar_result.summary()  # 回帰結果
  Summary of Regression Results   
==================================
Model:                        SVAR
Method:                        OLS
Date:           Mon, 08, Aug, 2016
Time:                     00:40:07
--------------------------------------------------------------------
No. of Equations:         4.00000    BIC:                   -35.7620
Nobs:                     249.000    HQIC:                  -36.0659
Log likelihood:           3138.42    FPE:                1.76987e-16
AIC:                     -36.2706    Det(Omega_mle):     1.53554e-16
--------------------------------------------------------------------
Results for equation BTC/JPY
=============================================================================
                coefficient       std. error           t-stat            prob
-----------------------------------------------------------------------------
const              0.002005         0.002085            0.961           0.337
L1.BTC/JPY         0.148403         0.065807            2.255           0.025
L1.USD/JPY        -0.310475         0.362978           -0.855           0.393
L1.EUR/JPY         0.301240         0.364265            0.827           0.409
L1.Gold           -0.346476         0.241212           -1.436           0.152
L2.BTC/JPY        -0.040609         0.065891           -0.616           0.538
L2.USD/JPY        -0.074339         0.364439           -0.204           0.839
L2.EUR/JPY        -0.059074         0.364986           -0.162           0.872
L2.Gold           -0.247649         0.241379           -1.026           0.306
=============================================================================

Results for equation USD/JPY
=============================================================================
                coefficient       std. error           t-stat            prob
-----------------------------------------------------------------------------
const             -0.000886         0.000492           -1.802           0.073
L1.BTC/JPY        -0.003380         0.015512           -0.218           0.828
L1.USD/JPY        -0.018224         0.085562           -0.213           0.832
L1.EUR/JPY        -0.016705         0.085865           -0.195           0.846
L1.Gold            0.063087         0.056859            1.110           0.268
L2.BTC/JPY         0.022905         0.015532            1.475           0.142
L2.USD/JPY         0.022443         0.085906            0.261           0.794
L2.EUR/JPY        -0.095209         0.086035           -1.107           0.270
L2.Gold           -0.031452         0.056898           -0.553           0.581
=============================================================================

Results for equation EUR/JPY
=============================================================================
                coefficient       std. error           t-stat            prob
-----------------------------------------------------------------------------
const             -0.000691         0.000497           -1.391           0.165
L1.BTC/JPY        -0.009591         0.015674           -0.612           0.541
L1.USD/JPY         0.050503         0.086455            0.584           0.560
L1.EUR/JPY        -0.015944         0.086761           -0.184           0.854
L1.Gold            0.043325         0.057452            0.754           0.452
L2.BTC/JPY        -0.001656         0.015694           -0.106           0.916
L2.USD/JPY         0.032432         0.086803            0.374           0.709
L2.EUR/JPY        -0.172938         0.086933           -1.989           0.048
L2.Gold           -0.034411         0.057492           -0.599           0.550
=============================================================================

Results for equation Gold
=============================================================================
                coefficient       std. error           t-stat            prob
-----------------------------------------------------------------------------
const              0.000229         0.000582            0.393           0.695
L1.BTC/JPY        -0.019201         0.018362           -1.046           0.297
L1.USD/JPY         0.051701         0.101280            0.510           0.610
L1.EUR/JPY         0.027936         0.101639            0.275           0.784
L1.Gold           -0.046397         0.067304           -0.689           0.491
L2.BTC/JPY        -0.025403         0.018385           -1.382           0.168
L2.USD/JPY         0.210005         0.101688            2.065           0.040
L2.EUR/JPY        -0.222826         0.101840           -2.188           0.030
L2.Gold           -0.079226         0.067351           -1.176           0.241
=============================================================================

Correlation matrix of residuals
            BTC/JPY   USD/JPY   EUR/JPY      Gold
BTC/JPY    1.000000  0.103922 -0.024485  0.134834
USD/JPY    0.103922  1.000000  0.647955  0.172215
EUR/JPY   -0.024485  0.647955  1.000000  0.273616
Gold       0.134834  0.172215  0.273616  1.000000
svar_result.irf(10).plot()  # 10期までのインパルス応答関数を出力

png

考察

うーん、結果を見る限りあまり統計的には有意な関係はなさそうですね…笑
インパルス応答関数の形だけを見る限り、ビットコインはドル円とは正の関係があり、ユーロ円とは負の関係がありそうで面白いです。

ここからどのような結論を出すのかがきっとデータ分析する人の腕の見せ所なのではないかと思います。
以上、PythonでのSVARモデルの使い方でした。