Oanda REST API

Oandaのデモ口座を開設し、Pythonで為替レートを取得しようと思ったものの、githubで公開されていたstreaming.py がPython3で動かなかったので、少し手を入れてみた。(既にforkされ誰かがPython3用に改良していたかもしれないが、確認はしていない。)

import requests
import json

from optparse import OptionParser

def connect_to_stream():
        """
        Environment           <Domain>
        fxTrade               stream-fxtrade.oanda.com
        fxTrade Practice      stream-fxpractice.oanda.com
        sandbox               stream-sandbox.oanda.com
        """
        # Replace the following variables with your personal ones
        domain = 'stream-fxpractice.oanda.com'
        access_token = 'アクセストークン'
        account_id = 'アカウントID'
        instruments = "GBP_USD"

        try:
                s = requests.Session()
                url = "https://" + domain + "/v1/prices"
                headers = {'Authorization' : 'Bearer ' + access_token,
                # 'X-Accept-Datetime-Format' : 'unix'
                }
                params = {'instruments' : instruments, 'accountId' : account_id}
                req = requests.Request('GET', url, headers = headers, params = params)
                pre = req.prepare()
                resp = s.send(pre, stream = True, verify = False)
                return resp
        except Exception as e:
                s.close()
                print("Caught exception when connecting to stream\n" + str(e) )

def demo(displayHeartbeat):
        response = connect_to_stream()
        if response.status_code != 200:
                print(response.text)
                return
        for line in response.iter_lines(1):
                if line:
                        try:
                                msg = json.loads(line.decode('utf8'))
                        except Exception as e:
                                print("Caught exception when converting message into json\n" + str(e))
                                return

                        if displayHeartbeat:
                                print(line)
                        else:
                                if msg.get("instrument"):
                                        print(line)
                                if msg.get("tick"):
                                        print(line)

def main():
        usage = "usage: %prog [options]"
        parser = OptionParser(usage)
        parser.add_option("-b", "--displayHeartBeat", dest = "verbose", action = "store_true", help = "Display HeartBeat in streaming data")
        displayHeartbeat = False
        (options, args) = parser.parse_args()
        if len(args) > 1:
                parser.error("incorrect number of arguments")
        if options.verbose:
                displayHeartbeat = True
        demo(displayHeartbeat)

if __name__ == "__main__":
        main()

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

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

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

データ出典:みずほ銀行

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

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

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:20160110010716p:plain

ARIMAモデルにあてはめる。

ARIMA(p,d,q)のパラメータを求める。 pは自己回帰の次数、dは差分の次数、qは移動平均の次数

min_aic <- 10000
min_param <- c()
for(p in 0:5){
  for(d in 0:5){
    for(q in 0:5){
      aic <- arima(usdjpy, order=c(p,d,q), method="ML")$aic
      print(paste0("p=",p," d=",d," q=",q," aic=",aic ))
      if( min_aic > aic ){
        min_aic <- aic
        min_param <- c(p,d,q)
      }
    }
  }
}
print(min_aic)
print(min_param)
[1] "p=0 d=0 q=0 aic=637.810845548458"
[1] "p=0 d=0 q=1 aic=547.016102157057"
[1] "p=0 d=0 q=2 aic=491.613229317161"
[1] "p=0 d=0 q=3 aic=451.731138014818"
・・・
[1] "p=5 d=5 q=2 aic=437.954908544684"
[1] "p=5 d=5 q=3 aic=439.995440790584"
[1] "p=5 d=5 q=4 aic=428.858827343577"
[1] "p=5 d=5 q=5 aic=430.767228514444"
There were 45 warnings (use warnings() to see them)
> print(min_aic)
[1] 371.2524
> print(min_param)
[1] 2 2 3

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

usdjpy.arima <- arima(usdjpy, order=c(2,2,3), method="ML")
plot(usdjpy, type="l")
points(usdjpy-usdjpy.arima$resid, col="red")

f:id:matsuy:20160110010949p:plain
当てはまりは悪くなさそうである。

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

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

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

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

予測をプロットしてみる

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

plot(forecast.Arima(arima(usdjpy, order=c(2,2,3), method="ML")), 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:20160110011059p:plain
* 全然ダメ。そもそも、12カ月先まで予測している為、急激な変動には対応できない。
* 毎月1カ月先までの予測ならもう少し精度が上がりそう。