為替レートの予測(ARMAモデル)

前回、気温をARモデルに当てはめてみたが、
今回は為替データを用いてARMA(自己回帰移動平均)モデルにあてはめてみる。

使用データは下記よりダウンロード

データ出典:みずほ銀行

setwd("~/R")
library("tseries")
library("forecast")

CSVは月中平均データを使用。
70行目から163行目が2008年~2015年のデータだったので、
その部分のUSD/JPYの2014年までを抽出。

tmp <- read.csv(file="http://www.mizuhobank.co.jp/rate/market/csv/m_quote.csv", skip=1)
cur <- tmp[70:163,]
usdjpy <- ts(cur[,2], start=c(2008,1), end=c(2014,12), frequency=12)
plot(usdjpy)

f:id:matsuy:20160101222015p:plain

データが定常性を持っているか確認

PP.test(usdjpy)
adf.test(usdjpy)

PP.testでもadf.testでも「単位根が存在する」という帰無仮説が棄却できない為、
データを差分データへ変換し、検定を行ってみる。

usdjpy.diff <- diff(usdjpy)
PP.test(usdjpy.diff)
adf.test(usdjpy.diff)

どちらのp-valueも小さいため、「単位根が存在する」という帰無仮説を棄却しても良さそうである。

ARMAモデルにあてはめる。

ARMA(p,q)のパラメータを求める。
pは自己回帰部分の次数、qは移動平均部分の次数。
ARMA(p,q)はARIMA(p,0,q)なのでarimaを使用する。

for(p in 0:5){
  for(q in 0:5){
    print(paste0("p=",p," q=",q," aic=",arima(usdjpy.diff, order=c(p,0,q))$aic))
  }
}
[1] "p=0 q=0 aic=390.860723715006"
[1] "p=0 q=1 aic=386.0378139517"
[1] "p=0 q=2 aic=383.499112734362"
[1] "p=0 q=3 aic=385.048958076852"
[1] "p=0 q=4 aic=386.295753421697"
[1] "p=0 q=5 aic=388.06345405141"
[1] "p=1 q=0 aic=383.677360060205"
[1] "p=1 q=1 aic=384.861652892441"
[1] "p=1 q=2 aic=385.022520591348"
[1] "p=1 q=3 aic=386.898652502025"
[1] "p=1 q=4 aic=388.25706411048"
[1] "p=1 q=5 aic=389.055923161325"
[1] "p=2 q=0 aic=384.019573200946"
[1] "p=2 q=1 aic=385.523492938253"
[1] "p=2 q=2 aic=382.385653240443"
[1] "p=2 q=3 aic=384.376541643366"
[1] "p=2 q=4 aic=385.987943070984"
[1] "p=2 q=5 aic=386.025611311805"
[1] "p=3 q=0 aic=384.845648815434"
[1] "p=3 q=1 aic=385.696233954982"
[1] "p=3 q=2 aic=384.370781665012"
[1] "p=3 q=3 aic=385.883486580717"
[1] "p=3 q=4 aic=386.306041617762"
[1] "p=3 q=5 aic=387.131812039991"
[1] "p=4 q=0 aic=385.758557382705"
[1] "p=4 q=1 aic=387.18847516223"
[1] "p=4 q=2 aic=378.57891212243"
[1] "p=4 q=3 aic=387.686538727588"
[1] "p=4 q=4 aic=388.87319422752"
[1] "p=4 q=5 aic=387.059764854582"
[1] "p=5 q=0 aic=386.694757663958"
[1] "p=5 q=1 aic=388.626695854645"
[1] "p=5 q=2 aic=385.165255667937"
[1] "p=5 q=3 aic=381.426633220362"
[1] "p=5 q=4 aic=384.4824928133"
[1] "p=5 q=5 aic=388.99810170353"

p=4、q=2でAICが最小である為、このパラメータを使用する。

usdjpy.arima <- arima(usdjpy.diff, order=c(4,0,2))
plot(usdjpy, type="l")
points(usdjpy-usdjpy.arima$resid, col="red")

f:id:matsuy:20160101221912p:plain

当てはまりは悪くなさそうである。

当てはまりの良さを確認する。

ARMAモデルの残差を確認する。

jarque.bera.test(usdjpy.arima$resid)
Box.test(usdjpy.arima$resid, lag=20)
 Jarque Bera Test

data:  usdjpy.arima$resid
X-squared = 0.6752, df = 2, p-value = 0.7135

    Box-Pierce test

data:  usdjpy.arima$resid
X-squared = 9.6587, df = 20, p-value = 0.9739

Jarque-Bera検定はp-valueが0.71と良いので、「分布は正規分布である」と言えそうである。 Ljung-Box検定はp-valueが0.97と良いので、「残差に自己相関が無い」と言える。

予測をプロットしてみる

h=12で12期先(データが月次なので12か月先)まで予測してくれる。

plot(forecast.Arima(arima(usdjpy, order=c(4,0,2))), xlim=c(2008,2016), ylim=c(77,160), main="")
par(new=T)
plot(ts(cur[,2], start=c(2008,1), end=c(2015,12), frequency=12), xlim=c(2008,2016), ylim=c(77,160), ylab="Rate", main="予測")
grid(10,10, col="black")

f:id:matsuy:20160101222459p:plain

予測精度が悪い