季節性を利用した戦略①
年の季節性
通貨ペア:USDJPY
期間:2002年1月1日~2012年12月31日
ルール①:年の谷の日の翌日に買い、山の日の翌日に売り。
ルール②:買いポジションは山の日の、売りポジションは谷の日の当日終値で決済。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:遺伝的アルゴリズムにより、年の山の日と谷の日を求める。
買いだけ、または売りだけというのもありうる。

山の日は95日目で4月上旬、谷の日は329日目で11月下旬。
通貨ペア:USDJPY
期間:2002年1月1日~2012年12月31日
ルール①:年の谷の日の翌日に買い、山の日の翌日に売り。
ルール②:買いポジションは山の日の、売りポジションは谷の日の当日終値で決済。
備考①:約定価格は前日終値。
備考②:損益の単位は%。
備考③:コストは考慮していない。
備考④:遺伝的アルゴリズムにより、年の山の日と谷の日を求める。
買いだけ、または売りだけというのもありうる。
# パッケージの呼び出し
library(GA)
library(quantmod)
# 開始日
startDate <- as.Date("2002-01-01")
# 終了日
endDate <- as.Date("2012-12-31")
# 終値
y <- data$USDJPY.Close
# 変化率
deltaY <- diff(y) / lag(y) * 100
# 山の日を求める関数
f <- function(x) {
# 山の日
xDay <- x
# リターン
ret <- deltaY[.indexyday(y) <= xDay]
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
# 戻り値
return(last(totalRet))
}
# バックテスト
GA <- ga(type = "real-valued", fitness = f, min = 1, max = 366)
# 要約
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
Min 1
Max 366
GA results:
Iterations = 100
Fitness function value = 20.94837
Solutions =
x1
[1,] 95.64730
[2,] 95.92568
[3,] 95.01541
# 谷の日を求める関数
f <- function(x) {
# 谷の日
xDay <- x
ret <- -deltaY[.indexyday(y) <= xDay]
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
return(last(totalRet))
}
GA <- ga(type = "real-valued", fitness = f, min = 1, max = 366)
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
Min 1
Max 366
GA results:
Iterations = 100
Fitness function value = 40.02663
Solutions =
x1
[1,] 329.5234
[2,] 329.0579
[3,] 329.4478
[4,] 329.1073
[5,] 329.0677
# 総損益
retLong <- deltaY[.indexyday(y) <= 95 | .indexyday(y) > 329] # 山先谷後
retShort <- -deltaY[.indexyday(y) > 95 & .indexyday(y) <= 329] # 山先谷後
#retLong <- deltaY[.indexyday(y) > 95 & .indexyday(y) <= 329] # 谷先山後
#retShort <- -deltaY[.indexyday(y) <= 95 | .indexyday(y) > 329] # 谷先山後
ret <- rbind(retLong, retShort)
totalRet <- cumsum(window(ret, start = startDate, end = endDate))
last(totalRet)
USDJPY.Close
2012-12-31 85.88084
# R2
cor(totalRet, 1:length(totalRet)) ^ 2
[,1]
USDJPY.Close 0.7854238
# グラフ
matplot(totalRet, type = "l")
# 使用済みオブジェクトの削除
rm(deltaY, endDate, f, GA, ret, retLong, retShort, startDate, totalRet, y)
山の日は95日目で4月上旬、谷の日は329日目で11月下旬。