常见问题
限定一个分数
假设你对每项资产都有一些“分数”,它可以是 ESG 指标,也可以是一些自定义的风险/收益指标。 指定线性约束很简单,比如“投资组合的 ESG 分数必须大于 x”:你只需创建一个分数的向量,在这些分数与投资组合权重的点乘上添加一个约束,然后优化你的目标:
esg_scores = [0.3, 0.1, 0.4, 0.1, 0.5, 0.9, 0.2]
portfolio_min_score = 0.5
ef = EfficientFrontier(mu, S)
ef.add_constraint(lambda w: esg_scores @ w >= portfolio_min_score)
ef.min_volatility()
限制资产的数量
不幸的是,cardinality 约束不是凸的,这使得它们很难实现。
然而,我们可以把它当作一个混合整数规划来解决(前提是你可以使用求解器)。
对于变量和约束少于 1000 的小问题,你可以使用社区版的 CPLEX: pip install cplex
。在下面的例子中,我们将投资组合限制为最多 10 个资产:
import cvxpy as cp
ef = EfficientFrontier(mu, S, solver=cp.CPLEX)
booleans = cp.Variable(len(ef.tickers), boolean=True)
ef.add_constraint(lambda x: x <= booleans)
ef.add_constraint(lambda x: cp.sum(booleans) <= 10)
ef.min_volatility()
这与 max_sharpe
不太适配,需要针对不同的界限进行修改。
请看 这个 Issue 的进一步讨论。
追踪误差
跟踪误差既可以作为一个目标(如 通用有效前沿 中所述),也可以作为一个约束条件。这是一个添加跟踪误差约束的例子:
from objective functions import ex_ante_tracking_error
benchmark_weights = ... # benchmark
ef = EfficientFrontier(mu, S)
ef.add_constraint(ex_ante_tracking_error, cov_matrix=ef.cov_matrix,
benchmark_weights=benchmark_weights)
ef.min_volatility()