You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cvxopt根据有效前沿给定收益率Y值求解对应风险标准差X值

实现方案

核心逻辑

原有代码是通过遍历风险厌恶系数mu求解有效前沿的离散点,再通过多项式拟合反推对应收益率的风险,精度受拟合误差、离散点密度影响。我们可以直接调整二次规划的约束条件,单次求解即可得到指定目标收益率下的最小风险:

  • 优化目标改为最小化组合方差:min 0.5 * w^T * cov_matrix * w
  • 保留原有约束:权重和为1、单资产权重≥0
  • 新增约束:组合加权收益率 = 指定目标收益率

实现代码

import numpy as np
import cvxopt.opt as opt
import cvxopt.solvers as solvers
import cvxopt.blas as blas
import matplotlib.pyplot as plt

# 原有有效前沿计算函数保持不变
def optimal_portfolio(returns_vec, cov_matrix):
    n = len(returns_vec)
    N = 1000
    mus = [10 ** (5 * t / N - 1.0) for t in range(N)]
    S = opt.matrix(cov_matrix)
    pbar = opt.matrix(returns_vec)
    G = -opt.matrix(np.eye(n))
    h = opt.matrix(0.0, (n, 1))
    A = opt.matrix(1.0, (1, n))
    b = opt.matrix(1.0)
    portfolios = [solvers.qp(mu * S, -pbar, G, h, A, b)['x'] for mu in mus]
    returns = [blas.dot(pbar, x) for x in portfolios]
    risks = [np.sqrt(blas.dot(x, S * x)) for x in portfolios]
    m1 = np.polyfit(returns, risks, 2)
    x1 = np.sqrt(m1[2] / m1[0])
    wt = solvers.qp(opt.matrix(x1 * S), -pbar, G, h, A, b)['x']
    return np.asarray(wt), returns, risks

# 新增指定收益率求风险函数
def get_risk_for_target_return(target_return, returns_vec, cov_matrix):
    n = len(returns_vec)
    # 校验目标收益率是否在可行区间内
    min_possible_return = min(returns_vec)
    max_possible_return = max(returns_vec)
    if target_return < min_possible_return or target_return > max_possible_return:
        raise ValueError(f"目标收益率需在[{min_possible_return:.6f}, {max_possible_return:.6f}]区间内")
    
    S = opt.matrix(cov_matrix)
    # 二次规划目标:min 0.5 * w^T S w,对应P=S, q=0向量
    P = S
    q = opt.matrix(0.0, (n, 1))
    
    # 非负约束:w >=0 → -w <=0
    G = -opt.matrix(np.eye(n))
    h = opt.matrix(0.0, (n, 1))
    
    # 双等式约束:1. 权重和为1;2. 组合收益率等于目标值
    A = opt.matrix(np.vstack([np.ones(n), returns_vec]))
    b = opt.matrix([1.0, target_return])
    
    # 求解二次规划
    sol = solvers.qp(P, q, G, h, A, b)
    optimal_weights = np.asarray(sol['x']).flatten()
    
    # 计算对应风险(标准差)
    risk = np.sqrt(np.dot(optimal_weights.T, np.dot(cov_matrix, optimal_weights)))
    return risk, optimal_weights

# 测试用例(原有参数)
return_vec = [0.055355, 0.010748, 0.041505, 0.074884, 0.039795, 0.065079]
cov_matrix =[[ 0.005329, -0.000572, 0.003320, 0.006792, 0.001580, 0.005316],
[-0.000572, 0.000625, 0.000606, -0.000266, -0.000107, 0.000531],
[0.003320, 0.000606, 0.006610, 0.005421, 0.000990, 0.006852],
[0.006792, -0.000266, 0.005421, 0.011385, 0.002617, 0.009786],
[0.001580, -0.000107, 0.000990, 0.002617, 0.002226, 0.002360],
[0.005316, 0.000531, 0.006852, 0.009786, 0.002360, 0.011215]]

# 原有逻辑计算有效前沿
weights, returns, risks = optimal_portfolio(return_vec, cov_matrix)

# 测试指定收益率查询
target_return = 0.05
risk, w = get_risk_for_target_return(target_return, return_vec, cov_matrix)
print(f"目标收益率{target_return:.4f}对应的最小风险为{risk:.4f}")
print(f"对应最优权重为{w.round(4)}")

# 可视化验证:把计算的点打到原有有效前沿上
fig = plt.figure()
plt.ylabel('Return')
plt.xlabel('Risk')
plt.plot(risks, returns, 'y-o', label='有效前沿')
plt.scatter(risk, target_return, c='red', s=100, label='指定目标收益率点')
plt.legend()
plt.show()

注意事项

  • 求解前会自动校验目标收益率的可行区间,避免传入超出最大/最小单个资产收益率的无效值导致求解失败
  • 如果需要允许做空,只需删除非负约束(把G和h参数设置为None传入solvers.qp即可)

内容的提问来源于stack exchange,提问作者Itachi Kurosaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 05:00:03