ブレイクアウト戦略②
通貨ペア:USDJPY
期間:2003年1月1日~2013年12月6日
ルール①:前日終値が前々日における直近lookback日間で最も高い終値より上で買い、前々日における直近lookback日間で最も安い終値より下で売り。
ルール②:holdDay-1日後の終値で決済。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:遺伝的アルゴリズムにより、lookback、holdDayはともに1~250の範囲で利益を最大化するパラメータを求める。
lookback期間として使われるものに、250日、52週などがある。
期間:2003年1月1日~2013年12月6日
ルール①:前日終値が前々日における直近lookback日間で最も高い終値より上で買い、前々日における直近lookback日間で最も安い終値より下で売り。
ルール②:holdDay-1日後の終値で決済。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:遺伝的アルゴリズムにより、lookback、holdDayはともに1~250の範囲で利益を最大化するパラメータを求める。
# パッケージの呼び出し
library(GA)
library(quantmod)
# 開始日
startDate <- as.Date("2003-01-01")
# 終了日
endDate <- as.Date("2013-12-06")
# 従属変数の終値
y <- data$USDJPY.Close # 日足
#y <- apply.weekly(data$USDJPY.Close, last) # 週足
#y <- apply.monthly(data$USDJPY.Close, last) # 月足
# 独立変数の終値
x <- data$USDJPY.Close # 日足
#x <- apply.weekly(data$USDJPY.Close, last) # 週足
#x <- apply.monthly(data$USDJPY.Close, last) # 月足
# 従属変数の変化率
deltaY <- diff(y) / lag(y) * 100
# トレード関数
f <- function(x1, x2) {
# 計算期間
lookback <- x1
# 保有期間
holdDay <- x2
# 直近高値
hiX <- rollapply(x, lookback, max)
# 直近安値
loX <- rollapply(x, lookback, min)
# ポジション
long <- x >= lag(hiX)
short <- x < lag(loX)
pos <- 0
for(i in 0:(holdDay - 1)) {
pos <- pos + lag(long, k = i) - lag(short, k = i) # 売買両方
#pos <- pos + lag(long, k = i) # 買いのみ
#pos <- pos - lag(short, k = i) # 売りのみ
}
# リターン
ret <- deltaY * lag(pos) / holdDay
#ret <- ret[.indexmon(ret) == 11] # 特定の月の抽出
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
return(last(totalRet))
}
# バックテスト
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 = 3.579473
Solution =
x1 x2
[1,] 75.83898 50.03912
# 総損益
lookback <- 75
holdDay <- 50
hiX <- rollapply(x, lookback, max)
loX <- rollapply(x, lookback, min)
long <- x >= lag(hiX)
short <- x < lag(loX)
pos <- 0
for(i in 0:(holdDay - 1)) {
pos <- pos + lag(long, k = i) - lag(short, k = i) # 売買両方
#pos <- pos + lag(long, k = i) # 買いのみ
#pos <- pos - lag(short, k = i) # 売りのみ
}
ret <- deltaY * lag(pos) / holdDay
ret <- ret[.indexmon(ret) == 11] # 特定の月の抽出
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
last(totalRet)
USDJPY.Close
2013-12-06 1.05017
# R2
cor(totalRet, 1:length(totalRet)) ^ 2
[,1]
USDJPY.Close 0.0450657
# グラフ
matplot(totalRet, type = "l")
# 使用済みオブジェクトの削除
rm(GA, deltaY, endDate, hiX, holdDay, i, loX, long, lookback,
pos, ret, short, startDate, totalRet, x, y
)
rm(f)lookback期間として使われるものに、250日、52週などがある。