ドンチャンルールのバックテスト
Rで簡単なバックテストです。
(* 以下のURLを参考にしました http://d.hatena.ne.jp/teramonagi/20110329/1301352620) (ただ、ここでの間違いがあれば、それは私です。)
1.定数を設定
ここでは、120日高値抜けでLONG、30日安値抜けでCLOSE POSを-1にすれば、SHORT
D1 <- 120
D2 <- 30
POS <- 1
2.データをload。ここでは日経225の現物を使う.indicatorとpostionをcbind(column bind)する
suppressPackageStartupMessages(library(quantmod))
org.data <- getSymbols("^N225", from = "2000-01-01", auto.assign = F)
data <- adjustOHLC(org.data, use.Adjusted = T)[, 1:4]
n1 <- ifelse(POS > 0, 1, 3)
n2 <- ifelse(POS > 0, 3, 1)
data <- cbind(data, DonchianChannel(data[, 4], D1)[, n1])
data <- cbind(data, DonchianChannel(data[, 4], D2)[, n2])
data <- cbind(data, data[, 4] == data[, 5])
data <- cbind(data, data[, 4] == data[, 6])
names(data)[5:8] <- c("ind1", "ind2", "sigEntry", "sigClose")
data$pos <- 0
data <- na.omit(data)
3.for-loopで、前日までのpositionを見ながら、当日のpositionを設定
これで、トレードした(positionをとった)ことになる。
## library(foreach) for-loopが順番依存なので、parallelは使えない??
for (i in 1:(nrow(data) - 1)) {
data$pos[i + 1] <- if (data$sigEntry[i] == 1) {
POS
} else if (data$sigClose[i] == 1) {
0
} else {
data$pos[i]
}
}
4.損益をグラフかする。ROCでreturnを計算。,returnを一個lagする。
suppressPackageStartupMessages(library(PerformanceAnalytics))
chart.CumReturns(cbind(ROC(data[, 4]) * (POS), ROC(data[, 4]) * lag(data$pos)),
wealth.index = TRUE, main = paste(ifelse(POS > 0, "BuyHold", "SellHold"),
"=RED, TAAproach=BLUE", sep = ""))
5.月別returnを見てみる
cat("monthly return\n")
## monthly return
ret.yearmon <- aggregate(coredata(ROC(data[, 4])) * lag(data$pos) * POS, as.Date(as.yearmon(index(data))),
function(x) exp(cumsum(x[1])))
hist(coredata(ret.yearmon), breaks = 50)
これは、未実現損益含む。ほとんどの場合、ちょい負け。
じゃなくて、ポジションもたないとき(return=0)がでてるだけか、、、
なんか、プラスがおおい、、どこかおかしいかも、、
6.関連数値(サンプル期間、エントリー数、個別トレード期間、損益、対象物のreturn)
PerformanceAnalyticsの関数を使ったほうがいいが、勉強不足
cat("total return\n")
## total return
rl <- rle(as.vector(coredata(data$pos)))
cat(paste(paste("date range", paste(range(index(data)), collapse = "-"), sep = ":"),
paste("number entries:", sum(rl$values), " position-day/all-day:", sum(rl$length[rl$values ==
1]), "/", (nrow(data) - 1), sep = ""), paste("trade periods", paste(sort(rl$length[rl$values ==
1], decreasing = T), collapse = " "), sep = ":"), paste("return", round(exp(sum(na.omit(coredata(ROC(data[,
4])) * lag(data$pos)) * POS)), 3), sep = ":"), paste("B&H return", round(exp(sum(na.omit(ROC(data[,
4]) * POS))), 3), sep = ":"), sep = "\n"), "\n")
## date range:2000-06-26-2013-01-22
## number entries:14 position-day/all-day:816/3084
## trade periods:189 106 69 65 62 51 46 43 39 37 37 25 24 23
## return:1.133
## B&H return:0.607
0 件のコメント:
コメントを投稿