Python实现Markowitz投资组合优化结果常不可行的原因排查
Markowitz投资组合优化结果不可行的常见原因
问题描述
我已完成Markowitz投资组合优化的Python实现,该实现通过最小化投资组合方差(风险),在满足目标收益率、资产权重和为1的约束下降低风险,但多数情况下优化结果显示不可行,请问可能的原因是什么?
实现代码
import pandas as pd import numpy as np from helper_functions.get_data import download_data from scipy.optimize import minimize def optimizer(tickers, start_date, end_date, required_return=0.02): df = download_data(tickers, start_date, end_date) # Calculate daily returns returns = df['Close'].pct_change() # Calculate mean returns and covariance mean_returns = returns.mean() cov_matrix = returns.cov() # Number of portfolio assets num_assets = len(mean_returns) # Initialize weights weights_initial = num_assets * [1. / num_assets,] # Constraints constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1}, {'type': 'eq', 'fun': lambda x: np.sum(x*mean_returns) - required_return}) # Bounds bounds = tuple((0,1) for asset in range(num_assets)) # Objective function def objective(weights): return np.dot(weights.T, np.dot(cov_matrix, weights)) # Optimize result = minimize(objective, weights_initial, method='SLSQP', bounds=bounds, constraints=constraints) # Return optimization results return result
不可行原因分析
- 目标收益率设置严重偏离实际:代码默认的
required_return=0.02是日收益率均值,但市场上多数资产的日平均收益率仅在0.001(0.1%)左右,0.02的日收益对应年化超500%,远超所有资产的历史表现,自然无法通过权重组合达成。 - 收益率维度不匹配:如果你的
required_return实际想设置为周/月/年化收益率,但代码中用的是日收益率均值计算组合收益,两者维度不匹配,会导致目标收益被错误放大,约束无法满足。 - 资产池收益上限不足:如果所有资产的历史平均收益率都低于目标值,哪怕全仓买入收益最高的资产也达不到要求,这种情况下约束本身就无解。
- 卖空限制锁死收益上限:代码设置了
bounds=(0,1),不允许卖空。当目标收益率超过所有资产的最大历史收益率时,无法通过做空低收益资产、加杠杆等方式拉高组合收益,导致约束不可行。 - 数据统计偏差:
- 如果数据周期过短,计算出的
mean_returns和cov_matrix统计显著性不足,可能导致可行域计算失真。 - 若资产间完全相关,协方差矩阵会出现奇异值,干扰优化算法的求解过程。
- 如果数据周期过短,计算出的
- 约束设置过于刚性:两个等式约束(权重和为1、组合收益等于目标值)加上非负权重的边界约束,在目标收益不可达时,算法找不到满足所有条件的解,直接返回不可行。
内容的提问来源于stack exchange,提问作者Lopez
相关产品推荐
相关产品推荐

