tidyquantによるバックテスト(パラメーター最適化)
前回の記事の続きです。 takehana13.hateblo.jp
今回はバックテストデータをパラメータの値ごとに分析することを考えます。まずストラテジー全体を関数化します。
strategy_ema <- function(data, n){ term1 <- data %>% group_by(symbol) %>% tq_mutate(select = adjusted, mutate_fun = EMA, n = n, col_rename = "ema") term2 <- term1 %>% tq_mutate(select = adjusted, mutate_fun = ROC, col_rename = "roc") term3 <- term2 %>% mutate(sig = lag(if_else(adjusted > ema, 1, -1)), ret = roc * sig) term4 <- term3 %>% drop_na %>% mutate(eq = cumsum(ret)) %>% select(symbol, date, eq) }
次に複数のパラメータをベクトル化してストラテジー関数に渡しpurrr::map()
します。
param <- seq(10, 50, by = 10) opt_ret <- param %>% map(~strategy_ema(FANG, .x)) opt_ret <- opt_ret %>% set_names(str_c("param", seq_len(5))) opt_ret <- opt_ret %>% bind_rows(.id = "param")
最後に結果をプロットします。
opt_ret %>% filter(symbol == "FB") %>% ggplot(aes(x = date, y = eq, colour = param)) + geom_line() + theme_tq() + geom_hline(yintercept = 0, colour = "darkgray") + scale_color_tq()
この結果を見るとema(10)
のリターンが極端に低いことが分かります。
また同様のコードで他の銘柄のパフォーマンスも確認できます。
グーグルのパフォーマンスはFacebookものよりもパラメータの違いによる影響が顕著ではありません。
tidyquantでバックテスト
Rでデータ操作と言えばTidyverseですが、RでQuantsと言えばQuantmodでしたが、最近の人はtidyquantなのでしょうか?
時系列操作というジャンルではtsibbleも便利なので難しいところですね。
今回はtidyquantを使って単純なストラテジーのバックテスト例を書いてみます。
ライブラリを読み込んで組み込みデータを確認します。
require(tidyquant) require(tidyverse) data(FANG) FANG %>% select(symbol, date, adjusted) %>% ggplot(aes(x = date, y = adjusted, colour = symbol)) + geom_line() + theme_tq() + scale_color_tq() + facet_wrap(.~symbol, scale = "free")
バックテストに使用するインジケータEMA(20)を計算します。
term1 <- FANG %>% group_by(symbol) %>% tq_mutate(select = adjusted, mutate_fun = EMA, n = 20, col_rename = "ema")
計算したEMAを可視化します。少し見にくいかもしれませんが、赤線がMAです。
term1 %>% ggplot(aes(date, adjusted)) + geom_line() + geom_line(aes(date, ema), color = "red") + facet_wrap(.~symbol, scale = "free") + theme_tq()
リターン計算に使うROC(Rate Of Change)をデータに追加します。
term2 <- term1 %>% tq_mutate(select = adjusted, mutate_fun = ROC, col_rename = "roc")
シグナルとリターンを計算します。ここではclose > ema
のときロングでなければショートとしています。
シグナルの発生から発注までの間に1期分ラグが発生するので注意が必要です。
EasyLanguage的に言えばbuy next bar at market;
ということです。
term3 <- term2 %>% mutate(sig = lag(if_else(adjusted > ema, 1, -1)), ret = roc * sig)
時系列収益率の推移を確認します。
term3 %>% select(symbol, date, ret) %>% drop_na %>% ggplot(aes(x = date, y = ret, colour = symbol)) + geom_point(alpha = .3) + scale_color_tq() + theme_tq()
累積リターンを可視化します。
term3 %>% drop_na %>% mutate(eq = cumsum(ret)) %>% select(symbol, date, eq) %>% ggplot(aes(x = date,y = eq, colour = symbol)) + geom_line()+ theme_tq()+ scale_color_tq()+ geom_hline(colour = "darkgray", yintercept = 0)
もっと複雑なストラテジーも簡単にテストできます。またコスト計算やポートフォリオリターンについての分析も必要です。
後日それらについても記事を書きます。