具有CVXPY约束的投资组合优化具有DCP错误

问题描述 投票:0回答:1

我正在优化投资组合,以最大程度地提高积极回报。我还有四个约束条件:权重之和必须等于1,所有权重必须小于或等于0.05,所有权重必须大于或等于0.0005,活动风险必须小于或等于7% 。

我有99只股票。这意味着我在计算中使用了3个矩阵。 alphas(预期收益)是形状为(99,1)的矩阵。 W_bench是基准中每种股票的权重,并且具有与alpha相同的形状。 V是形状为(99,99)的协方差矩阵。从下面的代码中可以看出,Active_Risk是某些人称为跟踪错误的东西。下面的代码是我设置优化的方式:

weights = cp.Variable((99,1))
Active_Return = weights.T @ alphas
Active_Risk = cp.sqrt((weights - W_bench).T @ V @ (weights - W_bench))
constraints = [cp.sum(weights) == 1, 0.07 >= Active_Risk, 0.0005 <= weights, weights <= 0.05]
prob = cp.Problem(cp.Maximize(Active_Return), constraints)

我可以使用excel的求解器成功解决此问题,尽管需要花费很长时间。但是,我似乎无法在Python上使用CVXPY使其工作。我很乐意上传数据,以便其他人可以帮助我解决问题,但我不知道该怎么做。我也考虑使用随机数据对这个问题进行较小的设计,但是我担心最佳解决方案可能不可行。

[当我运行代码result = prob.solve()时,出现以下错误:

---------------------------------------------------------------------------
DCPError                                  Traceback (most recent call last)
<ipython-input-15-e01c2b878783> in <module>
      1 # The optimal objective value is returned by `prob.solve()`.
----> 2 result = prob.solve()

/opt/anaconda3/lib/python3.7/site-packages/cvxpy/problems/problem.py in solve(self, *args, **kwargs)
    287         else:
    288             solve_func = Problem._solve
--> 289         return solve_func(self, *args, **kwargs)
    290 
    291     @classmethod

/opt/anaconda3/lib/python3.7/site-packages/cvxpy/problems/problem.py in _solve(self, solver, warm_start, verbose, parallel, gp, qcp, **kwargs)
    565                     solver, warm_start, verbose, **kwargs)
    566 
--> 567         self._construct_chains(solver=solver, gp=gp)
    568         data, solving_inverse_data = self._solving_chain.apply(
    569             self._intermediate_problem)

/opt/anaconda3/lib/python3.7/site-packages/cvxpy/problems/problem.py in _construct_chains(self, solver, gp)
    508 
    509             except Exception as e:
--> 510                 raise e
    511 
    512     def _solve(self,

/opt/anaconda3/lib/python3.7/site-packages/cvxpy/problems/problem.py in _construct_chains(self, solver, gp)
    497 
    498                 self._intermediate_chain = \
--> 499                     construct_intermediate_chain(self, candidate_solvers, gp=gp)
    500                 self._intermediate_problem, self._intermediate_inverse_data = \
    501                     self._intermediate_chain.apply(self)

/opt/anaconda3/lib/python3.7/site-packages/cvxpy/reductions/solvers/intermediate_chain.py in construct_intermediate_chain(problem, candidates, gp)
     68             append += ("\nHowever, the problem does follow DQCP rules. "
     69                        "Consider calling solve() with `qcp=True`.")
---> 70         raise DCPError("Problem does not follow DCP rules. Specifically:\n" + append)
     71 
     72     elif gp and not problem.is_dgp():

DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP:
power(var58 + -[[5.39791975e-03]
 [1.26209297e-03]
 [8.00351893e-05]
 [5.26548876e-02]
 [7.59655721e-03]
 [2.57535232e-03]
 [5.03372951e-04]
 [1.47480336e-03]
 [1.38599909e-04]
 [5.74108704e-03]
 [2.17434475e-03]
 [2.60441630e-04]
 [2.15412708e-04]
 [7.40692609e-03]
 [1.87030133e-04]
 [1.99318918e-04]
 [4.49890561e-04]
 [5.54053889e-04]
 [2.40066410e-04]
 [3.25109445e-05]
 [6.29530293e-02]
 [9.26141788e-03]
 [9.06847951e-02]
 [3.82569606e-04]
 [3.28101977e-04]
 [9.46531949e-04]
 [3.65845535e-02]
 [6.64869333e-04]
 [1.82867338e-03]
 [1.16324940e-04]
 [9.39765398e-04]
 [3.12166211e-03]
 [5.94047522e-04]
 [2.93656014e-04]
 [8.15666860e-04]
 [1.53355187e-04]
 [5.43259663e-04]
 [2.11729826e-04]
 [1.25169822e-04]
 [7.45171899e-04]
 [3.65823985e-04]
 [5.55365318e-04]
 [7.91907415e-05]
 [5.30872851e-03]
 [8.73601572e-04]
 [9.36948807e-04]
 [1.03941556e-02]
 [2.95556711e-04]
 [7.67666485e-03]
 [2.14996147e-04]
 [3.91275909e-04]
 [2.27743262e-04]
 [2.31689803e-04]
 [6.84002188e-03]
 [7.09758365e-02]
 [2.27532699e-04]
 [8.05783401e-04]
 [4.63372193e-04]
 [1.91341960e-03]
 [3.45573641e-04]
 [2.30427458e-02]
 [8.18612558e-04]
 [1.43341614e-03]
 [1.53359342e-04]
 [1.72991720e-04]
 [3.30942207e-04]
 [2.12224011e-02]
 [2.93271371e-04]
 [5.22032722e-02]
 [2.96349926e-03]
 [6.83703630e-04]
 [3.92175651e-04]
 [1.55757896e-03]
 [2.73614114e-04]
 [7.23199807e-03]
 [1.06194086e-02]
 [1.89837834e-04]
 [3.06087369e-03]
 [2.11597860e-04]
 [2.87620087e-04]
 [3.61744658e-04]
 [4.09530072e-04]
 [3.72525152e-04]
 [2.96987842e-02]
 [3.82775868e-01]
 [1.09826720e-03]
 [1.49363231e-03]
 [2.34448326e-04]
 [6.51708448e-03]
 [3.43523667e-03]
 [2.72356446e-03]
 [1.01445242e-03]
 [3.21249033e-04]
 [1.73042944e-02]
 [2.56326349e-03]
 [1.53653802e-03]
 [2.31159852e-04]
 [1.11857284e-03]
 [1.00845275e-02]].T * [[ 1.88468032  0.08627036 -0.81308165 ... -2.0625901  -0.64064643
  -1.12708076]
 [ 0.08627036  0.33892061  0.07628398 ...  0.19302222  0.14115192
  -0.02078213]
 [-0.81308165  0.07628398  0.58311836 ...  1.07460175  0.38954524
   0.53023314]
 ...
 [-2.0625901   0.19302222  1.07460175 ...  2.86645017  0.95771264
   1.34641816]
 [-0.64064643  0.14115192  0.38954524 ...  0.95771264  0.47074258
   0.43406168]
 [-1.12708076 -0.02078213  0.53023314 ...  1.34641816  0.43406168
   0.7897458 ]] * (var58 + -[[5.39791975e-03]
 [1.26209297e-03]
 [8.00351893e-05]
 [5.26548876e-02]
 [7.59655721e-03]
 [2.57535232e-03]
 [5.03372951e-04]
 [1.47480336e-03]
 [1.38599909e-04]
 [5.74108704e-03]
 [2.17434475e-03]
 [2.60441630e-04]
 [2.15412708e-04]
 [7.40692609e-03]
 [1.87030133e-04]
 [1.99318918e-04]
 [4.49890561e-04]
 [5.54053889e-04]
 [2.40066410e-04]
 [3.25109445e-05]
 [6.29530293e-02]
 [9.26141788e-03]
 [9.06847951e-02]
 [3.82569606e-04]
 [3.28101977e-04]
 [9.46531949e-04]
 [3.65845535e-02]
 [6.64869333e-04]
 [1.82867338e-03]
 [1.16324940e-04]
 [9.39765398e-04]
 [3.12166211e-03]
 [5.94047522e-04]
 [2.93656014e-04]
 [8.15666860e-04]
 [1.53355187e-04]
 [5.43259663e-04]
 [2.11729826e-04]
 [1.25169822e-04]
 [7.45171899e-04]
 [3.65823985e-04]
 [5.55365318e-04]
 [7.91907415e-05]
 [5.30872851e-03]
 [8.73601572e-04]
 [9.36948807e-04]
 [1.03941556e-02]
 [2.95556711e-04]
 [7.67666485e-03]
 [2.14996147e-04]
 [3.91275909e-04]
 [2.27743262e-04]
 [2.31689803e-04]
 [6.84002188e-03]
 [7.09758365e-02]
 [2.27532699e-04]
 [8.05783401e-04]
 [4.63372193e-04]
 [1.91341960e-03]
 [3.45573641e-04]
 [2.30427458e-02]
 [8.18612558e-04]
 [1.43341614e-03]
 [1.53359342e-04]
 [1.72991720e-04]
 [3.30942207e-04]
 [2.12224011e-02]
 [2.93271371e-04]
 [5.22032722e-02]
 [2.96349926e-03]
 [6.83703630e-04]
 [3.92175651e-04]
 [1.55757896e-03]
 [2.73614114e-04]
 [7.23199807e-03]
 [1.06194086e-02]
 [1.89837834e-04]
 [3.06087369e-03]
 [2.11597860e-04]
 [2.87620087e-04]
 [3.61744658e-04]
 [4.09530072e-04]
 [3.72525152e-04]
 [2.96987842e-02]
 [3.82775868e-01]
 [1.09826720e-03]
 [1.49363231e-03]
 [2.34448326e-04]
 [6.51708448e-03]
 [3.43523667e-03]
 [2.72356446e-03]
 [1.01445242e-03]
 [3.21249033e-04]
 [1.73042944e-02]
 [2.56326349e-03]
 [1.53653802e-03]
 [2.31159852e-04]
 [1.11857284e-03]
 [1.00845275e-02]]), 1/2) <= 0.07 , because the following subexpressions are not:
|--  var58 + -[[5.39791975e-03]
 [1.26209297e-03]
 [8.00351893e-05]
 [5.26548876e-02]
 [7.59655721e-03]
 [2.57535232e-03]
 [5.03372951e-04]
 [1.47480336e-03]
 [1.38599909e-04]
 [5.74108704e-03]
 [2.17434475e-03]
 [2.60441630e-04]
 [2.15412708e-04]
 [7.40692609e-03]
 [1.87030133e-04]
 [1.99318918e-04]
 [4.49890561e-04]
 [5.54053889e-04]
 [2.40066410e-04]
 [3.25109445e-05]
 [6.29530293e-02]
 [9.26141788e-03]
 [9.06847951e-02]
 [3.82569606e-04]
 [3.28101977e-04]
 [9.46531949e-04]
 [3.65845535e-02]
 [6.64869333e-04]
 [1.82867338e-03]
 [1.16324940e-04]
 [9.39765398e-04]
 [3.12166211e-03]
 [5.94047522e-04]
 [2.93656014e-04]
 [8.15666860e-04]
 [1.53355187e-04]
 [5.43259663e-04]
 [2.11729826e-04]
 [1.25169822e-04]
 [7.45171899e-04]
 [3.65823985e-04]
 [5.55365318e-04]
 [7.91907415e-05]
 [5.30872851e-03]
 [8.73601572e-04]
 [9.36948807e-04]
 [1.03941556e-02]
 [2.95556711e-04]
 [7.67666485e-03]
 [2.14996147e-04]
 [3.91275909e-04]
 [2.27743262e-04]
 [2.31689803e-04]
 [6.84002188e-03]
 [7.09758365e-02]
 [2.27532699e-04]
 [8.05783401e-04]
 [4.63372193e-04]
 [1.91341960e-03]
 [3.45573641e-04]
 [2.30427458e-02]
 [8.18612558e-04]
 [1.43341614e-03]
 [1.53359342e-04]
 [1.72991720e-04]
 [3.30942207e-04]
 [2.12224011e-02]
 [2.93271371e-04]
 [5.22032722e-02]
 [2.96349926e-03]
 [6.83703630e-04]
 [3.92175651e-04]
 [1.55757896e-03]
 [2.73614114e-04]
 [7.23199807e-03]
 [1.06194086e-02]
 [1.89837834e-04]
 [3.06087369e-03]
 [2.11597860e-04]
 [2.87620087e-04]
 [3.61744658e-04]
 [4.09530072e-04]
 [3.72525152e-04]
 [2.96987842e-02]
 [3.82775868e-01]
 [1.09826720e-03]
 [1.49363231e-03]
 [2.34448326e-04]
 [6.51708448e-03]
 [3.43523667e-03]
 [2.72356446e-03]
 [1.01445242e-03]
 [3.21249033e-04]
 [1.73042944e-02]
 [2.56326349e-03]
 [1.53653802e-03]
 [2.31159852e-04]
 [1.11857284e-03]
 [1.00845275e-02]].T * [[ 1.88468032  0.08627036 -0.81308165 ... -2.0625901  -0.64064643
  -1.12708076]
 [ 0.08627036  0.33892061  0.07628398 ...  0.19302222  0.14115192
  -0.02078213]
 [-0.81308165  0.07628398  0.58311836 ...  1.07460175  0.38954524
   0.53023314]
 ...
 [-2.0625901   0.19302222  1.07460175 ...  2.86645017  0.95771264
   1.34641816]
 [-0.64064643  0.14115192  0.38954524 ...  0.95771264  0.47074258
   0.43406168]
 [-1.12708076 -0.02078213  0.53023314 ...  1.34641816  0.43406168
   0.7897458 ]] * (var58 + -[[5.39791975e-03]
 [1.26209297e-03]
 [8.00351893e-05]
 [5.26548876e-02]
 [7.59655721e-03]
 [2.57535232e-03]
 [5.03372951e-04]
 [1.47480336e-03]
 [1.38599909e-04]
 [5.74108704e-03]
 [2.17434475e-03]
 [2.60441630e-04]
 [2.15412708e-04]
 [7.40692609e-03]
 [1.87030133e-04]
 [1.99318918e-04]
 [4.49890561e-04]
 [5.54053889e-04]
 [2.40066410e-04]
 [3.25109445e-05]
 [6.29530293e-02]
 [9.26141788e-03]
 [9.06847951e-02]
 [3.82569606e-04]
 [3.28101977e-04]
 [9.46531949e-04]
 [3.65845535e-02]
 [6.64869333e-04]
 [1.82867338e-03]
 [1.16324940e-04]
 [9.39765398e-04]
 [3.12166211e-03]
 [5.94047522e-04]
 [2.93656014e-04]
 [8.15666860e-04]
 [1.53355187e-04]
 [5.43259663e-04]
 [2.11729826e-04]
 [1.25169822e-04]
 [7.45171899e-04]
 [3.65823985e-04]
 [5.55365318e-04]
 [7.91907415e-05]
 [5.30872851e-03]
 [8.73601572e-04]
 [9.36948807e-04]
 [1.03941556e-02]
 [2.95556711e-04]
 [7.67666485e-03]
 [2.14996147e-04]
 [3.91275909e-04]
 [2.27743262e-04]
 [2.31689803e-04]
 [6.84002188e-03]
 [7.09758365e-02]
 [2.27532699e-04]
 [8.05783401e-04]
 [4.63372193e-04]
 [1.91341960e-03]
 [3.45573641e-04]
 [2.30427458e-02]
 [8.18612558e-04]
 [1.43341614e-03]
 [1.53359342e-04]
 [1.72991720e-04]
 [3.30942207e-04]
 [2.12224011e-02]
 [2.93271371e-04]
 [5.22032722e-02]
 [2.96349926e-03]
 [6.83703630e-04]
 [3.92175651e-04]
 [1.55757896e-03]
 [2.73614114e-04]
 [7.23199807e-03]
 [1.06194086e-02]
 [1.89837834e-04]
 [3.06087369e-03]
 [2.11597860e-04]
 [2.87620087e-04]
 [3.61744658e-04]
 [4.09530072e-04]
 [3.72525152e-04]
 [2.96987842e-02]
 [3.82775868e-01]
 [1.09826720e-03]
 [1.49363231e-03]
 [2.34448326e-04]
 [6.51708448e-03]
 [3.43523667e-03]
 [2.72356446e-03]
 [1.01445242e-03]
 [3.21249033e-04]
 [1.73042944e-02]
 [2.56326349e-03]
 [1.53653802e-03]
 [2.31159852e-04]
 [1.11857284e-03]
 [1.00845275e-02]])

我是CVXPY的新手,并不完全了解DCP规则。任何帮助,将不胜感激。谢谢。

编辑:

我已经添加了数据,以便那些对我有帮助的人更容易解决该问题。 Matrix V很大,对于滚动,我深表歉意。以下链接指向Google驱动器,其中包含Jupyter笔记本:Jupyter Notebook

python optimization constraints portfolio cvxpy
1个回答
0
投票

这个问题的形式很糟糕,每个试图使它运行的人都需要通过一些独立的示例来避免的工作(是的:即使您对一些最初的失败尝试发表评论,我认为这样做也更容易而不是要求我们自己这样做。

还有因素上下文。 DCP是基于规则的框架,能够表达很多凸问题,但不是全部凸问题。有迹象表明,这个问题与DCP兼容,但对此的确定的回答将再次导致我们这方面的工作更多。

这全都导致我方对以下内容提供有限保证:

您的问题在以下位置:

Active_Risk = cp.sqrt((weights - W_bench).T @ V @ (weights - W_bench))
  • 这是变量的乘积,通常是非凸的,因此,在没有进一步假设的情况下处理一般情况不能在DCP中表示
  • 您有其他假设,例如V是PSD(因为它是协方差矩阵),但是cvxpy在这种形式下无法推断出这一点
  • 您将需要更清楚地向cvxpy表达此附加结构/假设

代替使用:

cp.sqrt((weights - W_bench).T @ V @ (weights - W_bench))

您将需要使用:

cp.quad_form((weights - W_bench), V)

我对上面一行中丢失的外部cp.sqrt感到不好,但是您可以尝试一下。

但是很重要的一点是,可以通过更改其他模型组件(缩放参数)来更正使用此非sqd Quad_form。

所以代替:

0.07 >= Active_Risk

您将拥有:

0.07^2 >= Active_Risk

您无需触摸物镜(无论是否平方;物镜都会变化,但解矢量不会)。

© www.soinside.com 2019 - 2024. All rights reserved.