シグナルの生成と検証
前回「スプレッドの構築」の続き。
とりあえず、写経したところまでメモ。
各種設定値およびデータの作成。
# ローリング期間 > window_length <- 10 # データ開始日・終了日 > start_date<-"2013-01-01" > end_date<-"2013-12-31" # データ範囲文字列の作成 > range<-paste(start_date, "::", end_date, sep="") > range [1] "2013-01-01::2013-12-31" # 株価データ取得 > x<-TOPIX[range, 4] > y<-UFJ[range,6] > dF<-cbind(x,y) > head(dF) YJ998405.Close YJ8306.Adjusted 2013-01-04 888.51 484 2013-01-07 881.06 476 2013-01-08 871.88 462 2013-01-09 879.05 469 2013-01-10 889.02 474 2013-01-11 898.69 479 > names(dF)<-c("TOPIX","UFJ")
次に線形回帰の回帰係数を取得する関数の定義と、ローリング関数を定義する。
# β計算用関数 > run_regression<-function(dF){ + return(coef(lm(y ~ x-1, data=as.data.frame(dF)))) + } # ローリング関数 # rollapplyのzはデータ、widthはローリング期間、FUNは適用関数、by.columnはTRUEの場合は適用関数(FUN)が各カラムに適用される > rolling_beta<-function(z, width){ + rollapply(z, width=width, FUN=run_regression, by.column=FALSE, align="right") + } # βの計算 > betas<-rolling_beta(diff(dF), window_length) > betas <- rolling_beta(diff(dF), window_length) > head(betas) [,1] 2013-01-04 NA 2013-01-07 NA 2013-01-08 NA 2013-01-09 NA 2013-01-10 NA 2013-01-11 NA > data<-merge(betas, dF) > head(data) betas TOPIX UFJ 2013-01-04 NA 888.51 484 2013-01-07 NA 881.06 476 2013-01-08 NA 871.88 462 2013-01-09 NA 879.05 469 2013-01-10 NA 889.02 474 2013-01-11 NA 898.69 479 > data$spread<-data$UFJ-lag(betas,1)*data$TOPIX > returns<-diff(dF)/dF > return_beta<-rolling_beta(returns, window_length) > data$spreadR<-diff(data$UFJ)/data$UFJ-return_beta*diff(data$TOPIX)/data$TOPIX > tail(data) betas TOPIX UFJ spread spreadR 2013-12-20 0.5370756 1261.64 654 -23.596105 -0.0085655660 2013-12-24 0.5370756 1257.55 654 -21.399465 0.0017467610 2013-12-25 0.5370756 1258.18 654 -21.737823 -0.0002689263 2013-12-26 0.5370756 1279.34 669 -18.102343 0.0135384127 2013-12-27 0.5370756 1290.07 677 -15.865165 0.0073497779 2013-12-30 0.5370756 1302.29 694 -5.428229 0.0194560438 >
プロットする。
> par(mfrow=c(2,1)) > plot(data$spread) > plot(data$spreadR)
さて、次に価格差スプレッドを可視化する。
> threshold<-sd(data$spread, na.rm=TRUE) > threshold [1] 19.12683 # 可視化 > plot(data$spread, main="UFJ vs TOPIX In-Sample", cex.main=0.8, cex.lab=0.8, cex.axis=0.8) > abline(h=threshold, lty=2) > abline(h=-threshold, lty=2)
次はここまで計算したスプレッドを元に、買いシグナルと売りシグナルを生成させ、それをグラフにプロットする。
# スプレッドの描画 > plot(data$spread, main="UFJ vs TOPIX In-Sample", cex.main=0.8, cex.lab=0.8, cex.axis=0.8) > abline(h=threshold, lty=2) > abline(h=-threshold, lty=2) # 買いシグナルと売りシグナルの生成 # 単純に標準偏差(1σ)より大きいスプレッドの場合は買い、-1σより小さい場合は売りとする。 > buy_signal_count<-ifelse(data$spread > threshold, 1, 0) > sell_signal_count<-ifelse(data$spread < -threshold, -1, 0) > data$signalCount<-buy_signal_count+sell_signal_count # シグナル結果をスプレッドのグラフ上に描画 > point_type<-rep(NA, nrow(data)) > buy_index<-which(data$signalCount == 1) > sell_index<-which(data$signalCount == -1) > point_type[buy_index] <- 21 #丸印 > point_type[sell_index] <- 24 #上三角印(△) > points(data$spread, pch=point_type)
シグナル数は下記で計算可能。
> num_of_buy_signals<-sum(buy_signal_count, na.rm=TRUE) > num_of_sell_signals<-sum(abs(sell_signal_count), na.rm=TRUE) > num_of_buy_signals [1] 34 > num_of_sell_signals [1] 27 >