3

「勝率」がトレーディング戦略のリターンにどのように影響するかを調べています。

S&P の価格をダウンロードし、毎日のリターンを計算します。次に、これらのリターンの x% をランダムに選択し、その方向を正しく予測したと言うので、リターンは正です。残りの 1-x% については、私は間違っていると言い、リターンはマイナスです。私はこのプロセスを 1000 回繰り返して、年間の幾何学的リターンを収集します。

0.01 の増分間隔で x を 0.5 から 0.6 まで変化させます。

これが私のコードです:

library(quantmod)
library(multicore)

getSymbols("^GSPC", from = "1950-1-1")
ret <- ROC(GSPC)[-1,4]

set.seed(123)

winpct <- seq(0.5, 0.6, 0.01)
ret <- coredata(ret)

system.time(res <- simplify2array(mclapply(winpct, function(x) replicate(1000, drawsample(ret, x)))))

drawsample <- function(ret, winpct){
  len = length(ret)
  ret = abs(ret)

  win = sample(1:len, round(winpct * len))
  a = c(ret[win], -ret[-win])
  return(prod(1 + a) ^ (252 / length(a)) - 1)
}

所要時間:

   user  system elapsed 
 18.904   0.842   5.580 

速度を上げるためにできる最適化はありますか?

4

2 に答える 2

4

次の 2 つの調整を行いました。

1/使用exp(sum(a))ではなくprod(1+a)。でログリターンシリーズを作成したので、とにかくこれが必要だと思いますROC(GSPC)[-1,6]。これによるとrbenchmark、約7%のスピードアップが得られました。

c(-1,-1)2/ シリーズの長さについてfrom をサンプリングretし、ret シリーズで乗算して、符号付きのリターンのシリーズを取得します。これでさらに30%増えました。

私のコードでは、あなたの名前をaasに変更したことに注意してくださいbin

drawsample2 <- function(ret, winpct){
  len = length(ret)
  win = sample(c(-1,1), len, replace=TRUE, prob = c((1-winpct), winpct))
  ret <- abs(ret)
  bin <- ret*win
  return(exp(sum(bin))^(252/length(ret)) - 1)
}

あなたの i に対してベンチマークすると、最大drawsample()37% のスピードアップが得られます。

bb <- benchmark(simplify2array(mclapply(winpct, function(x) replicate(1000, drawsample(ret, x)))), 
          simplify2array(mclapply(winpct, function(x) replicate(1000, drawsample2(ret, x)))),
          columns =c('test', 'elapsed', 'relative'),
          replications = 10,
          order = 'elapsed')

私のMBPでのベンチマークは次のとおりです。

> bb

  elapsed relative
2  17.254    1.000
1  27.734    1.607
于 2012-12-17T10:31:43.390 に答える
2

これは、より大きなオブジェクトに対してより高速なricardo の関数の微調整です。mclapplyマルチコア処理に必要なネットワーク オーバーヘッドを回避して関数のパフォーマンスを分離するために、 の呼び出しを削除しました。

drawsample_r <- function(ret, winpct){
  len = length(ret)
  win = sample(c(-1,1), len, replace=TRUE, prob = c((1-winpct), winpct))
  ret <- abs(ret)
  bin <- ret*win
  return(exp(sum(bin))^(252/length(ret)) - 1)
}
drawsample_j <- function(ret, winpct){
  len <- length(ret)
  win <- c(-1L,1L)[sample.int(2L,len,TRUE,c(1-winpct,winpct))]
  exp(sum(abs(ret)*win))^(252L/len)-1L
}
library(rbenchmark)
set.seed(123)
ret <- rnorm(1e6)/100  # 1 million observations
winpct <- seq(0.5, 0.6, 0.01)
benchmark(sapply(winpct, drawsample_r, ret=ret),
          sapply(winpct, drawsample_j, ret=ret),
  replications=10, order='elapsed')[,1:5]
#                                    test replications elapsed relative user.self
# 2 sapply(winpct, drawsample_j, ret=ret)           10   6.963    1.000     6.956
# 1 sapply(winpct, drawsample_r, ret=ret)           10  10.852    1.559    10.689
于 2012-12-22T20:41:30.957 に答える