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)
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")
当てはまりは悪くなさそうである。
当てはまりの良さを確認する。
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")
* 全然ダメ。そもそも、12カ月先まで予測している為、急激な変動には対応できない。
* 毎月1カ月先までの予測ならもう少し精度が上がりそう。