MT4のヒストリカルデータをRでxts形式に変換する。(複数通貨ペア編)


予告どおり複数通貨ペアを一気にまとめて1つの xts データに格納する R の関数です。

ちなみに、MetaTrader4 が標準エクスポートで書き出す csv ファイルは下図のとおりです。

ではコードです。

R

fun.xts.multi <- function(pairnames, timeframe,
                          Open=FALSE, High=FALSE, Low=FALSE, Close=TRUE, Volume=FALSE){

   reads <- c(FALSE, FALSE, Open, High, Low, Close, Volume)
   count <- length(pairnames)
   m.xts <- xts()

   for(i in 1:count){
      x.df <- read.csv(paste(pairnames[i], timeframe, ".csv", sep=""), header=FALSE,
                       col.names = c("Date", "Time", "Open", "High", "Low", "Close", 
                                     "Volume"),
                       colClasses = c("character", "character", "numeric", "numeric", 
                                      "numeric", "numeric", "integer"))
      x.df$Datetime <- paste(chartr(".", "-", x.df$Date), x.df$Time)

      s.xts <- as.xts(zoo(x.df[,reads], as.POSIXct(x.df$Datetime, "EET")))
      colnames(s.xts) <- paste(pairnames[i], names(x.df)[reads], sep=".")

      m.xts <- merge(m.xts, s.xts, tzone="EET")
   }

   return(m.xts)
}

基本的には単一通貨版のやり方を踏襲しており、csv -> データフレーム -> 単一ペア xts -> 複数ペア xts と回りくどいですし、データ列の指定や命名にしてももっと良い書き方があるんじゃないかなぁとは思ってます。

csv ファイルをあらかじめ R のワーキングディレクトリに入れておくのは単一通貨版と同じです。
さらに下準備として私は読み込みたい通貨ペア名を、

R
pairnames <- c("EURUSD", "GBPUSD", "USDJPY")

のようにベクトルに格納して使っています。
ここに書いた順番に読み込まれます。
読み込みたいデータ列を TRUE or FALSE で指定しますが、初期値を設定してありますので終値だけでよければ、

R
fx.multi.xts <- fun.xts.multi(pairnames, "60")

とするだけで、

                    EURUSD.Close GBPUSD.Close USDJPY.Close
2011-12-12 07:00:00      1.32386      1.56098       77.967
2011-12-12 08:00:00      1.32449      1.56013       77.921
2011-12-12 09:00:00      1.32157      1.56182       77.791
2011-12-12 10:00:00      1.31868      1.55940       77.863
2011-12-12 11:00:00      1.32028      1.55896       77.863
2011-12-12 12:00:00      1.31839      1.55961       77.904

こんな感じに出来上がります。
大量のデータを変換する場合は少し待たされます。

下記のようにデータ長が揃っていないものや欠損値を含むものを結合させる場合でも、

                    AUDUSD.Close
2012-09-06 17:00:00      1.02811
2012-09-06 18:00:00           NA   # 18:00 が欠損
2012-09-06 19:00:00      1.02909

                    AUDNZD.Close
2012-09-06 19:00:00      1.28189   # これよりも前のデータがない
2012-09-06 20:00:00      1.28179
2012-09-06 21:00:00      1.28253

# これらを欠損値のない他のデータと結合すると・・・

                    AUDJPY.Close AUDNZD.Close AUDUSD.Close
2012-09-06 17:00:00       81.191           NA      1.02811
2012-09-06 18:00:00       81.211           NA           NA
2012-09-06 19:00:00       81.235      1.28189      1.02909
2012-09-06 20:00:00       81.231      1.28179      1.02919
2012-09-06 21:00:00       81.160      1.28253      1.02909

と勝手にタイミングを揃えてくれるのでうれしいです。
xts 形式では欠損値を簡易的に補完する na.spline 等の zoo 関数も使えるようになります。

ところで、

R
USDJPY.60min.xts <- fun.xts.multi("USDJPY", "60", TRUE, TRUE, TRUE, TRUE)

とかすれば前回の関数は必要なかったんじゃない?と思われるかもしれません。

はい、その通りです。

                    USDJPY.Open USDJPY.High USDJPY.Low USDJPY.Close
2011-12-12 07:00:00      77.794      77.992     77.777       77.967
2011-12-12 08:00:00      77.965      77.977     77.848       77.921

だって今回、投稿するにあたって清書してたら気が変わっちゃったんだもん・・・。
当初は読み込むデータ列を指定できる仕様はなく、終値だけを読み込むもっとシンプルなものだったのでした。