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カ月先までの予測ならもう少し精度が上がりそう。