NO brain NO money

自分がコツコツ作ってきた頭脳は、5年で1億作れるのか

加重移動平均 (WMA)をRで計算する

単純移動平均より、より現在に近いデータに重みを付けている、WMAの方がいいよね、ということで、これを採用。

引き続きシュミレータをガリガリ書いてるのですが、SMA(単純移動平均)のRパッケージはあったのに、WMAのパッケージはない!

MACDを計算する上で、移動平均線を複数書かなければいけないので、関数化。

※参考にしたサイト
http://www.oanda.jp/learn/forex-indicators/weighted-moving-average.php

データ準備。

日経先物5分足ヒストリカルデータを、date,time降順で用意。

移動平均計算で使用するのはend列の値。

> head(a3)
      date time    st    hi    lo   end
1 2014/1/6 0:00 16295 16305 16295 16300
2 2014/1/6 0:05 16300 16305 16295 16295
3 2014/1/6 0:10 16295 16300 16295 16295
4 2014/1/6 0:15 16295 16300 16295 16300
5 2014/1/6 0:20 16300 16300 16295 16295
6 2014/1/6 0:25 16295 16300 16295 16295

関数に渡す変数はこれ。

上から

WMAを入れていく列の名前

移動平均期間

WMAを挿入するオブジェクト(ここでは上記のa3を指定)

#列名と、wma期間、オブジェクトを引数として渡す
name <- "sma_s"
period <- 5
obj <- a3

はい、そして、定義する関数がこれ。

#wma関数の定義
########################
wma_func <- function(name,period,obj) {
    obj$dummy <- 0
    names(obj)[length(obj)] <- c(name)
    obj$no <- seq(1:nrow(obj))
    
    for(i in (period+1):nrow(obj)){
      #wma算出行を切り出し
      obj2 <- obj[obj$no >= i-period & obj$no <= i-1,]
      obj2$no <- seq(1:nrow(obj2))
      #三角数の自然数和計算
      seq_sum <- period*(period+1)/2
      #和挿入し、列を作る
      obj2$seq_sum <- seq_sum
      #wmaの要素を列ごとに計算
      obj2$wma_col <- obj2$end*obj2$no/seq_sum
      #wma計算&挿入
      obj[i,name] <- sum(obj2$wma_col)
    }
    return(obj)
  }
########################

実際にパラメータ突っ込んでテスト

> #wma挿入テスト
> b1 <- wma_func(name,period,obj)
> head(b1)
      date time    st    hi    lo   end    sma_s no
1 2014/1/6 0:00 16295 16305 16295 16300     0.00  1
2 2014/1/6 0:05 16300 16305 16295 16295     0.00  2
3 2014/1/6 0:10 16295 16300 16295 16295     0.00  3
4 2014/1/6 0:15 16295 16300 16295 16300     0.00  4
5 2014/1/6 0:20 16300 16300 16295 16295     0.00  5
6 2014/1/6 0:25 16295 16300 16295 16295 16296.67  6


ちゃんと、6行目(移動平均は5なので、5行目までの計算結果を6行目に反してます。
実際に相場だと、過去のデータで未来を予測しないといけないためにラグを作ってます。

問題点は、やはり、データフレームに対してfor文を使ってることで、デカいデータ使用時の処理が遅くなることでしょうか。
この辺り、list型で計算するようにして、回避したいのですが、そこまでいけてないという・・・

よろしければご活用下さい。