R上的二次约束和对数函数优化

时间:2017-10-27 13:25:28

标签: r optimization quantitative-finance

我正在尝试在R中解决这个优化问题:

Optimization problem

要明确ω向量是要优化的变量。 σ和Σ矩阵是常数

我不知道如何修改问题以便使用一个R求解器,我的所有尝试都失败了......

这来自这篇量化财务文章:

https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2673124

感谢您的帮助,

亚瑟

这是我尝试使用R和nloptr包

  #Compute the covariance matrix with asset returns
  Cov<-cov(Asset)

  #fonction to optimize
  D <- function(P) {
    -sum(log(abs(P)))
  }

  #gradient of the objective function
  D_g <- function(P) {
    -1/P
    }

  #inequality function with the Jacobian
  ineq <- function(P) {
    cont<-rep(0,length(P))
    for(i in 1: length(P)){
      cont[i]<-sum(P[-i]*Cov[i,-i])
    }
    return(list(
      "constraints" = sqrt(t(P) %*% Cov %*% P) - target,
      "jacobian" = (P * diag(Cov)+cont) / sqrt(t(P) %*% Cov %*% P)
    ))

  }

  # Optimisation under constraints
  # Poids is the initial weight: 1/vol
  # D is the function to optimize
  # D_g is the gradient of this function
  # ineq is a function with constraint and jacobian of it
  Poids=Pos*1/sqrt(diag(Cov))/sum(1/sqrt(diag(Cov)))

  par0 <-
    nloptr(
      Poids,
      D,
      eval_grad_f = D_g,
      lb = NULL,
      ub = NULL,
      eval_g_ineq = ineq,
      opts = list("algorithm" = "NLOPT_LD_LBFGS",
                  "xtol_rel" = 1.0e-8)
    )

1 个答案:

答案 0 :(得分:0)

这是有效的代码。经过一番研究,我发现nlopr包的COBYLA算法可以解决这类问题。很抱歉我对高级优化的误解以及在R中的方法。

以下是来自金融行业的人需要快速完成的代码:

  #Asset is simply returns from financial asset 
  target=0.1/sqrt(252)
  #Compute the covariance matrix
  Cov<-cov(Asset)

  #fonction to optimize
  D <- function(P) {
    -sum(log(abs(P)))
  }

  #gradient of the objective function
  D_g <- function(P) {
    -1/P
    }

  #inequality function with the Jacobian
  ineq <- function(P) {
    return(sqrt(t(P) %*% Cov %*% P) - target
    )
  }

  LoB=rep(0,length(Pos))
  UpB=rep(0,length(Pos))
  for(i in 1:length(Pos)){
    if(Pos[i]>0){
      LoB[i]<-0.00001
      UpB[i]<-10
    }else{
      LoB[i]<- -10
      UpB[i]<- -0.00001
    }
  }

  # Optimisation under constraints
  # Poids is the initial weight: 1/vol
  # D is the function to optimize
  # ineq is a function with constraints

  Poids=Pos*1/sqrt(diag(Cov))/sum(1/sqrt(diag(Cov)))

  par0 <-
    nloptr(
      Poids,
      D,
      eval_grad_f = NULL,#D_g,
      lb = LoB,
      ub = UpB,
      eval_g_ineq = ineq,
      opts = list("algorithm" = "NLOPT_LN_COBYLA",
                  "xtol_rel" = 1.0e-12,
                  "maxeval"=10000,
                  "xtol_abs"=1.0e-12)
    )

我完全理解,对于某些人来说问题很大,理论上的问题还没有解决。再一次,我对高级优化没有足够的了解......