上下文:我是PyPortfolioOpt的开发人员,PyPortfolioOpt是python产品组合优化库,并且我试图允许用户为最大Sharpe比率问题添加约束。
当前,用户可以将其约束作为lambda函数传递,例如,使所有权重大于1%:
ef = EfficientFrontier(mu, S) # mu and S are expected return and covariance
ef.add_constraint(lambda w: w >= 0.01) # example new constraint
ef.min_volatility() # optimise with constraint
在后端,我将cvxpy变量传递w = cp.Variable(n)
给约束lambda函数,以创建有效的cvxpy约束,然后将其传递给cp.Problem
并解决它。
我遇到的麻烦是,要最大化Sharpe比率,就需要进行变量替换。形式的约束Ax ~ b
(where~
表示相等或不相等)必须变为Ax ~ k * b
wherek
是非负优化变量。
我尝试的一件事是传递w / k
给lambda函数。然后,这将导致约束w / k >= 0.01
,我希望该约束等效于w >= k * 0.01
,但可悲的是,这给出了:
DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP:
0.01 <= var2817 / Promote(var2818, (20,)) , because the following subexpressions are not:
|-- var2817 / Promote(var2818, (20,))
然后,我以为我可以接受非线性约束constr = (w / k >= 0.01)
并将其乘以k
得到k * constr = (w >= 0.01 * k)
,但不能在cvxpy中乘以约束。
TL; DR:如何将表示的cvxpy约束对象(已实例化)转换为表示w / k >= 0.01
的cvxpy约束对象w >= k * 0.01
?
否则,我有什么办法可以重新设计它?我想保留lambda函数API。
也许有一些API可以分解已经实例化的约束,以便可以放入变量?
约束是设计不变的。不变性简化了CVXPY的大部分逻辑。
为什么不构造新的约束?您当然可以检查约束的左侧和右侧。现在,可以通过检查args
属性来完成(请参阅https://github.com/cvxgrp/cvxpy/blob/master/cvxpy/constraints/nonpos.py#L97)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句