2

StackOverflow への貢献者からの多くの助けを借りて、シャープ レシオを最大化する 2 資産ポートフォリオの重みを導出する関数をまとめることができました。空売りは許可されず、重みの合計は 1 になります。ここでやりたいことは、資産 A がユーザー定義の重みの 10% を超えないように制限することです。例として、アセット A のウェイトを 54% 以上または 66% 以上 (つまり、60% +/- 10%) に制限したいと考えています。したがって、以下の例では、制約のない (0.243,0.7570) ではなく (0.54,0.66) の重みになります。これは bVect を微調整することで実行できると思いますが、どうすればよいかわかりません。どんな助けでも大歓迎です。

asset_A <- c(0.034320510,-0.001209628,0.031900161,0.023163947,-0.001872938,-0.010322489,0.006090395,-0.003270854,0.017778990,0.017204915) 

asset_B <- c(0.047103261,0.055175057,0.021019816,0.020602347,0.007281368,-0.006547404,0.019155238,0.005494798,0.025429958,0.014929124)

     require(quadprog)

     HR_solve   <- function(asset_A,asset_B) {
     vol_A    <-  sd(asset_A)
     vol_B   <-  sd(asset_B)
     cor_AB  <-   cor(cbind(asset_A,asset_B),method="pearson")
     ret_A_B      <- as.matrix(c(mean(asset_A),mean(asset_B)))

      vol_AB <- c(vol_A,vol_B)
      covmat <- diag(as.vector(vol_AB))%*%cor_AB%*%diag(as.vector(vol_AB))

      aMat <- cbind(rep(1,nrow(covmat)),diag(1,nrow(covmat)))
      bVec  <- c(1,0,0)
      zeros <- array(0, dim = c(nrow(covmat),1))
      minw <-  solve.QP(covmat, zeros, aMat, bVec, meq = 1 ,factorized = FALSE)$solution
      rp <- as.numeric(t(minw) %*% ret_A_B)
      sp <- sqrt(t(minw) %*% covmat %*% minw)
      wp <- t(matrix(minw))

      sret <- sort(seq(t(minw) %*% ret_A_B,max(ret_A_B),length.out=100))
      aMatt <- cbind(ret_A_B,aMat)

      for (ri in sret[-1]){
      bVect  <- c(ri,bVec)
      result <-  tryCatch({solve.QP(covmat, zeros, aMatt, bVect, meq = 2,factorized = FALSE)},
                            warning = function(w){ return(NULL) } , error = function(w){ return(NULL)}, finally = {} )
     if (!is.null(result)){
     wp <-  rbind(wp,as.vector(result$solution))
     rp <-c(rp,t(as.vector(result$solution) %*% ret_A_B))
     sp <- c(sp,sqrt(t(as.vector(result$solution)) %*% covmat %*% as.vector(result$solution))) }

     }

      HR_weights <- wp[which.max(rp/sp),]
      as.matrix(HR_weights)
    }


HR_solve(asset_A,asset_B)


          [,1]
[1,] 0.2429662
[2,] 0.7570338
4

3 に答える 3

1

わかりましたこれを行う方法を見つけました...もっとエレガントな方法があると思うなら、私に知らせてください...

 require(quadprog)

 HR_solve   <- function(asset_A,asset_B,mean_A,range_A) {
 vol_A    <-  sd(asset_A)
 vol_B   <-  sd(asset_B)
 cor_AB  <-   cor(cbind(asset_A,asset_B),method="pearson")
 ret_A_B      <- as.matrix(c(mean(asset_A),mean(asset_B)))

 vol_AB <- c(vol_A,vol_B)
 covmat <- diag(as.vector(vol_AB))%*%cor_AB%*%diag(as.vector(vol_AB))
 bVec  <-  c(1,0,0)

aMat <- cbind(rep(1,nrow(covmat)),diag(1,nrow(covmat)))

zeros <- array(0, dim = c(nrow(covmat),1))
minw <-  solve.QP(covmat, zeros, aMat, bVec, meq = 1 ,factorized = FALSE)$solution
rp <- as.numeric(t(minw) %*% ret_A_B)
sp <- sqrt(t(minw) %*% covmat %*% minw)
wp <- t(matrix(minw))

sret <- sort(seq(t(minw) %*% ret_A_B,max(ret_A_B),length.out=1000))

min_A <- mean_A * (1-range_A)
max_A <- mean_A * (1+range_A)

aMatt <- cbind(ret_A_B,aMat,-diag(2))
bVec  <- c(1,min_A,0,-max_A,-1)




for (ri in sret[-1]){
bVect  <- c(ri,bVec)


result <-  tryCatch({solve.QP(covmat, zeros, aMatt, bVect, meq = 2,factorized = FALSE)},
                        warning = function(w){ return(NULL) } , error = function(w){ return(NULL)}, finally = {} )
if (!is.null(result)){
wp <-  rbind(wp,as.vector(result$solution))
rp <-c(rp,t(as.vector(result$solution) %*% ret_A_B))
sp <- c(sp,sqrt(t(as.vector(result$solution)) %*% covmat %*% as.vector(result$solution))) }
}

HR_weights <- wp[which.max(rp/sp),]
as.matrix(HR_weights)
 }
于 2016-04-25T12:57:42.903 に答える
0

aMat と bVec を変更するだけです。

# sset A to be no less than 54% or more than 66%
  aMat <- cbind(rep(1,nrow(covmat)),diag(1,nrow(covmat)),c(1,0),c(-1,0))
  bVec  <- c(1,0,0,.54,-.66)
于 2016-04-25T13:20:21.587 に答える