平均回帰戦略②

ボリンジャーバンド

通貨ペア:AUDUSD*USDCAD(=AUDCAD)
期間:2002年1月1日~2013年12月6日
ルール①:前日終値が前日の移動平均-標準偏差より下ならAUDUSD*USDCADを買い、前日の移動平均+標準偏差より上ならAUDUSD*USDCADを売り、それ以外は様子見。
ルール②:買いポジションを保有しているとき、前日終値が前日の移動平均以上であれば決済、さもなければ継続。
ルール③:売りポジションを保有しているとき、前日終値が前日の移動平均以下であれば決済、さもなければ継続。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:平均、標準偏差の計算期間は5~250まで5刻みとし、計50回のバックテストを行う。

# パッケージの呼び出し
library(quantmod)
# 開始日
startDate <- as.Date("2002-01-01")
# 終了日
endDate <- as.Date("2013-12-06")
# 従属変数の終値
y <- data$AUDUSD.Close * data$USDCAD.Close
# 独立変数の終値
x <- data$AUDUSD.Close * data$USDCAD.Close
# 従属変数の変化率
deltaY <- diff(y) / lag(y) * 100
# 結果を格納するオブジェクト
result <- matrix(0, nrow = 50, ncol = 3)
colnames(result) <- c("lookback", "totalRet", "r2")
# バックテスト
for(i in 1:50) {
# 計算期間
lookback <- 5 * i
# 平均
avg <- rollapply(x, lookback, mean)
# 標準偏差
std <- rollapply(x, lookback, sd)
# zスコア
zScore <- (x - avg) / std
# ポジション
longEntry <- zScore <= -1
longExit <- zScore >= 0
shortEntry <- zScore >= 1
shortExit <- zScore <= 0
long <- longEntry
long <- long / long
long[longExit] <- 0
long <- na.locf(long)
short <- shortEntry
short <- shortEntry / shortEntry
short[shortExit] <- 0
short <- na.locf(short)
pos <- long - short
# 損益
ret <- deltaY * lag(pos)
# 累積損益
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
# R2
r2 <- cor(totalRet, 1:length(totalRet)) ^ 2
# 結果の記録
result[i,1] <- lookback
result[i,2] <- last(totalRet)
result[i,3] <- r2
}
# 結果
result

lookback totalRet r2
[1,] 5 64.83597806 0.908471191
[2,] 10 51.99184844 0.865841330
[3,] 15 35.39744170 0.603904946
[4,] 20 -8.93744633 0.121439771
[5,] 25 -4.94535533 0.011444538
[6,] 30 -13.20878837 0.459607972
[7,] 35 -23.82674382 0.630654030
[8,] 40 -25.65792131 0.693333155
[9,] 45 -16.35124227 0.589728266
[10,] 50 -19.24174020 0.667795603
[11,] 55 -14.96638665 0.556889777
[12,] 60 -16.44079248 0.647068211
[13,] 65 -11.62250334 0.576565712
[14,] 70 -0.77922676 0.284785922
[15,] 75 6.87334388 0.002321960
[16,] 80 -2.66490316 0.223129968
[17,] 85 -9.19444632 0.467291116
[18,] 90 2.10187711 0.157336085
[19,] 95 -2.14838132 0.346443771
[20,] 100 -8.71277123 0.593322656
[21,] 105 -13.87266518 0.657126159
[22,] 110 -10.62674740 0.584009890
[23,] 115 -13.16279645 0.624766761
[24,] 120 -9.53775697 0.595056747
[25,] 125 -11.36959322 0.615455782
[26,] 130 -15.79280176 0.646889526
[27,] 135 -18.62058082 0.632808886
[28,] 140 -14.23975739 0.581669361
[29,] 145 -12.88752043 0.584425215
[30,] 150 -10.47405784 0.521904261
[31,] 155 -14.81793969 0.607090953
[32,] 160 -17.68733670 0.679416236
[33,] 165 -15.43699003 0.652634171
[34,] 170 -11.79633640 0.546142130
[35,] 175 -11.48511047 0.452794881
[36,] 180 -7.73890131 0.242185278
[37,] 185 -8.35840993 0.247233711
[38,] 190 -5.08825248 0.034470466
[39,] 195 -0.01347161 0.041184577
[40,] 200 -1.26293854 0.003356085
[41,] 205 -6.63983938 0.115704973
[42,] 210 -3.58036475 0.003353007
[43,] 215 -11.58239634 0.163819030
[44,] 220 -8.85188707 0.022274177
[45,] 225 -2.31183545 0.255068721
[46,] 230 -2.39244510 0.176377260
[47,] 235 -0.71385838 0.271367843
[48,] 240 1.76956938 0.386721544
[49,] 245 7.73687138 0.601628446
[50,] 250 10.27658142 0.683346773
# グラフ
lookback <- 5
avg <- rollapply(x, lookback, mean)
std <- rollapply(x, lookback, sd)
zScore <- (x - avg) / std
longEntry <- zScore <= -1
longExit <- zScore >= 0
shortEntry <- zScore >= 1
shortExit <- zScore <= 0
long <- longEntry
long <- long / long
long[longExit] <- 0
long <- na.locf(long)
short <- shortEntry
short <- shortEntry / shortEntry
short[shortExit] <- 0
short <- na.locf(short)
pos <- long - short
ret <- deltaY * lag(pos)
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
matplot(totalRet,type="l")
# 使用済みオブジェクトの削除
rm(avg, deltaY, endDate, long, longEntry, longExit, lookback, pos,
r2, result, ret, short, shortEntry, shortExit, startDate, std,
totalRet, x, y, zScore)
# メモリの解放
gc()
gc()

コメントの投稿

非公開コメント

プロフィール

Author:fxst24
自分用のノートとして作っていますが、同学の方々の参考になれば幸いです。
記事はことわりなく修正、削除、非公開にすることがあります。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
QRコード
QR