ブレイクアウト戦略①
ドンチャンシステム
通貨ペア:USDCAD
期間:2003年1月1日~2013年12月6日
ルール①:前日終値が前々日における直近lookback2日間最高値より上で買い、前々日における直近lookback2日間最安値より下で売り。
ルール②:買いポジションは当日終値が前日における直近lookback1日間最安値以下であった場合、売りポジションは当日終値が前日における直近lookback1日間最高値以上であった場合、当日終値で決済。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:遺伝的アルゴリズムにより、lookback1、lookback2はともに1~250の範囲で利益を最大化するパラメータを求める。
通貨ペア:USDCAD
期間:2003年1月1日~2013年12月6日
ルール①:前日終値が前々日における直近lookback2日間最高値より上で買い、前々日における直近lookback2日間最安値より下で売り。
ルール②:買いポジションは当日終値が前日における直近lookback1日間最安値以下であった場合、売りポジションは当日終値が前日における直近lookback1日間最高値以上であった場合、当日終値で決済。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:遺伝的アルゴリズムにより、lookback1、lookback2はともに1~250の範囲で利益を最大化するパラメータを求める。
# パッケージの呼び出し
library(GA)
library(quantmod)
# 開始日
startDate <- as.Date("2003-01-01")
# 終了日
endDate <- as.Date("2013-12-06")
# 高値
hi <- data$USDCAD.High
# 安値
lo <- data$USDCAD.Low
# 終値
cl <- data$USDCAD.Close
# 変化率
deltaCl <- diff(cl) / lag(cl) * 100
# トレード関数
f <- function(x1, x2) {
# エグジットの計算期間1
lookback1 <- x1
# エントリーの計算期間2
lookback2 <- x1 + x2
# エントリー用高値
entryHi <- rollapply(hi, lookback2, max)
# エグジット用高値
exitHi <- rollapply(hi, lookback1, max)
# エントリー用安値
entryLo <- rollapply(lo, lookback2, min)
# エグジット用安値
exitLo <- rollapply(lo, lookback1, min)
# ポジション
longEntry <- cl > lag(entryHi)
longExit <- cl <= lag(exitLo)
shortEntry <- cl < lag(entryLo)
shortExit <- cl >= lag(exitHi)
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 <- deltaCl * lag(pos)
# 累積リターン
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
# 相関係数
correl <- cor(totalRet, 1:length(totalRet))
# 戻り値
return(last(totalRet))
#return(last(correl))
}
# バックテスト
GA <- ga(type = "real-valued", fitness = function(x) + f(x[1], x[2]),
min = c(1, 1), max = c(250, 250))
# 要約
summary(GA)
+-----------------------------------+
| Genetic Algorithm |
+-----------------------------------+
GA settings:
Type = real-valued
Population size = 50
Number of generations = 100
Elitism =
Crossover probability = 0.8
Mutation probability = 0.1
Search domain
x1 x2
Min 1 1
Max 250 250
GA results:
Iterations = 100
Fitness function value = 65.39468
Solutions =
x1 x2
[1,] 59.29904 6.089905
[2,] 59.39371 6.562053
> f(59,6)
USDCAD.Close
2013-12-06 65.39468
# 総損益
lookback1 <- 59
lookback2 <- lookback1 + 6
entryHi <- rollapply(hi, lookback2, max)
exitHi <- rollapply(hi, lookback1, max)
entryLo <- rollapply(lo, lookback2, min)
exitLo <- rollapply(lo, lookback1, min)
longEntry <- cl > lag(entryHi)
longExit <- cl <= lag(exitLo)
shortEntry <- cl < lag(entryLo)
shortExit <- cl >= lag(exitHi)
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 <- deltaCl * lag(pos)
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
last(totalRet)
USDCAD.Close
2013-12-06 65.39468
# R2
cor(totalRet, 1:length(totalRet)) ^ 2
[,1]
USDCAD.Close 0.9060582
# グラフ
matplot(totalRet, type = "l")
# 使用済みオブジェクトの削除
rm(cl, deltaCl, endDate, entryHi, entryLo, exitHi, exitLo, f, GA,
hi, lo, long, longEntry, longExit, lookback1, lookback2, pos,
ret, short, shortEntry, shortExit, startDate, totalRet)
# メモリの解放
gc()
gc()