引言:现代投资组合理论的革命性突破
哈里·马科维茨(Harry Markowitz)在1952年提出的现代投资组合理论(Modern Portfolio Theory, MPT)彻底改变了投资界对风险与收益关系的认知。这一理论的核心思想是:投资者不应单独评估单一资产的风险与收益,而应从整体投资组合的角度出发,通过资产间的相关性来优化风险收益比。马科维茨因此获得了1990年的诺贝尔经济学奖,他的模型至今仍是机构投资者进行资产配置的理论基石。
一、马科维茨模型的核心思想详解
1.1 风险与收益的权衡:投资的基本法则
马科维茨模型的第一个核心思想是风险与收益的正相关关系。在金融市场中,高收益往往伴随着高风险,这是无法违背的基本规律。然而,马科维茨指出,通过科学的资产配置,我们可以在相同风险水平下获得更高收益,或在相同收益水平下承担更低风险。
通俗解释:
想象你是一位厨师,手上有两种食材:辣椒(高风险高收益)和米饭(低风险低收益)。如果只吃辣椒,你会被辣得受不了;只吃米饭,又觉得索然无味。马科维茨告诉我们的就是:将辣椒和米饭按一定比例混合,做成辣椒炒饭,既能享受到辣椒的刺激,又不会被辣到无法承受。
1.2 分散化投资的数学原理:相关性是关键
马科维茨模型的革命性突破在于用数学方法证明了分散化投资的价值。传统观点认为”不要把所有鸡蛋放在一个篮子里”,但马科维茨用严格的数学公式告诉我们:只有当资产之间不完全正相关时,分散化才能降低风险。
核心公式:
投资组合的期望收益: $\(E(R_p) = \sum_{i=1}^{n} w_i E(R_i)\)$
投资组合的方差(风险): $\(\sigma_p^2 = \sum_{i=1}^{n} \sum_{j=1}^{n} w_i w_j \sigma_i \sigma_j \rho_{ij}\)$
其中:
- \(w_i\) 是第i项资产的权重
- \(E(R_i)\) 是第i项资产的期望收益
- \(\sigma_i\) 是第i项资产的标准差(风险)
- \(\rho_{ij}\) 是资产i和j的相关系数
通俗解释:
相关系数\(\rho_{ij}\)的取值范围是[-1, 1]:
- \(\rho = 1\):完全正相关,资产同涨同跌,分散化无效
- \(\rho = 0\):不相关,资产独立波动,分散化效果最佳
- \(\rho = -1\):完全负相关,资产涨跌相反,可以完全对冲风险
关键洞察:只要资产间不是完全正相关,组合的风险就会小于各资产风险的加权平均。这就是”1+1“的魔法。
1.3 有效前沿:最优投资组合的集合
马科维茨模型通过数学优化找到了所有可能投资组合中风险收益比最优的组合集合,这就是著名的”有效前沿”(Efficient Frontier)。
有效前沿的特征:
- 在相同风险下收益最高:有效前沿上的每个点都代表在该风险水平下能达到的最高收益
- 在相同收益下风险最低:有效前沿上的每个点都代表在该收益水平下风险最低的3. 有效组合的边界:所有有效投资组合都位于这条曲线上
通俗解释:
有效前沿就像一座山的轮廓线。站在山顶(高风险高收益)和山脚(低风险低收益)之间的任何位置,你都能找到最优的观景点。但如果你站在山的侧面(非有效组合),要么风险太高收益太低,要么收益太低风险太高——总之不是最优选择。
二、如何用马科维茨模型平衡风险与收益
2.1 资产配置的四步流程
第一步:确定可投资资产类别
选择3-5个具有不同风险收益特征且相关性较低的资产类别:
- 股票(高风险高收益)
- 债券(低风险低收益)
- 商品(如黄金,与股债相关性低)
- 房地产(中等风险收益)
- 现金(极低风险收益)
第二步:估计资产参数
需要估计每个资产的:
- 期望收益率
- 标准差(风险)
- 资产间的相关系数
重要提示:这些参数基于历史数据估计,但未来可能不同,这是模型的主要局限性。
第三步:构建有效前沿
通过数学优化求解不同权重组合,绘制风险-收益坐标图,找到有效前沿。
第四步:选择最优组合
根据投资者的风险偏好,在有效前沿上选择最合适的点:
- 保守型投资者:选择低风险低收益的组合
- 激进型投资者:选择高风险高收益的组合
- 平衡型投资者:选择中间位置的组合
2.2 实际案例演示
假设我们有三种资产:
- 股票(S):期望收益12%,标准差20%
- 债券(B):期望收益5%,标准差8%
- 黄金(G):期望收益6%,标准差15%
相关系数矩阵:
| 资产 | 股票 | 债券 | 黄金 |
|---|---|---|---|
| 股票 | 1.0 | 0.1 | 0.2 |
| 债券 | 0.1 | 1.0 | -0.1 |
| 黄金 | 0.2 | -0.1 | 1.0 |
计算示例:60%股票+30%债券+10%黄金的组合
期望收益: $\(E(R_p) = 0.6×12\% + 0.3×5\% + 0.1×6\% = 7.2\% + 1.5\% + 0.6\% = 9.3\%\)$
组合方差: $\(\sigma_p^2 = w_s^2\sigma_s^2 + w_b^2\sigma_b^2 + w_g^2\sigma_g^2 + 2w_sw_b\sigma_s\sigma_b\rho_{sb} + 2w_sw_g\sigma_s\sigma_g\rho_{sg} + 2w_bw_g\sigma_b\sigma_g\rho_{bg}\)$
代入数值: $\(\sigma_p^2 = 0.6^2×0.2^2 + 0.3^2×0.08^2 + 0.1^2×0.15^2 + 2×0.6×0.3×0.2×0.08×0.1 + 2×0.6×0.1×0.2×0.15×0.2 + 2×0.3×0.1×0.08×0.15×(-0.1)\)$
计算结果: $\(\sigma_p^2 = 0.0144 + 0.000576 + 0.000225 + 0.000576 + 0.00072 + (-0.000072) = 0.016425\)\( \)\(\sigma_p = \sqrt{0.016425} = 12.8\%\)$
结果分析:这个组合的收益为9.3%,风险为12.8%。相比单独持有股票(12%收益,20%风险),我们降低了36%的风险,仅损失了2.7个百分点的收益。
三、马科维茨模型的编程实现
3.1 Python代码实现完整马科维茨优化
import numpy as np
import pandas as pd
from scipy.optimize import minimize
import matplotlib.pyplot as plt
class MarkowitzPortfolio:
def __init__(self, returns, cov_matrix):
"""
初始化马科维茨投资组合优化器
参数:
returns: 期望收益向量 (n_assets,)
cov_matrix: 协方差矩阵 (n_assets, n_assets)
"""
self.returns = np.array(returns)
self.cov_matrix = np.array(cov_matrix)
self.n_assets = len(returns)
def portfolio_stats(self, weights):
"""计算投资组合的收益和风险"""
portfolio_return = np.dot(weights, self.returns)
portfolio_variance = weights @ self.cov_matrix @ weights.T
portfolio_std = np.sqrt(portfolio_variance)
return portfolio_return, portfolio_std
def negative_sharpe_ratio(self, weights, risk_free_rate=0.02):
"""计算负的夏普比率(用于最小化)"""
ret, std = self.portfolio_stats(weights)
sharpe = (ret - risk_free_rate) / std if std > 0 else -np.inf
return -sharpe
def optimize_for_target_return(self, target_return):
"""优化:给定目标收益,最小化风险"""
# 约束条件
constraints = [
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}, # 权重和为1
{'type': 'eq', 'fun': lambda w: np.dot(w, self.returns) - target_return} # 目标收益
]
# 边界条件:权重在0到1之间(不允许做空)
bounds = tuple((0, 1) for _ in range(self.n_assets))
# 初始猜测:等权重
initial_weights = np.array([1/self.n_assets] * self.n_assets)
# 优化
result = minimize(
fun=lambda w: self.portfolio_stats(w)[1], # 最小化风险
x0=initial_weights,
method='SLSQP',
bounds=bounds,
constraints=constraints
)
return result
def optimize_max_sharpe(self, risk_free_rate=0.02):
"""优化:最大化夏普比率"""
constraints = [
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}
]
bounds = tuple((0, 1) for _ in range(self.n_assets))
initial_weights = np.array([1/self.n_assets] * self.n_assets)
result = minimize(
fun=lambda w: self.negative_sharpe_ratio(w, risk_free_rate),
x0=initial_weights,
method='SLSQP',
bounds=bounds,
constraints=constraints
)
return result
def generate_efficient_frontier(self, num_points=50):
"""生成有效前沿"""
min_return = np.min(self.returns)
max_return = np.max(self.returns)
target_returns = np.linspace(min_return, max_return, num_points)
efficient_weights = []
efficient_returns = []
efficient_risks = []
for ret in target_returns:
result = self.optimize_for_target_return(ret)
if result.success:
weights = result.x
_, risk = self.portfolio_stats(weights)
efficient_weights.append(weights)
efficient_returns.append(ret)
efficient_risks.append(risk)
return np.array(efficient_returns), np.array(efficient_risks), np.array(efficient_weights)
def plot_efficient_frontier(self, num_points=50):
"""绘制有效前沿图"""
# 生成有效前沿
returns, risks, _ = self.generate_efficient_frontier(num_points)
# 生成随机组合用于对比
n_simulations = 10000
random_weights = np.random.dirichlet(np.ones(self.n_assets), n_simulations)
random_returns = np.dot(random_weights, self.returns)
random_risks = np.sqrt(np.einsum('ij,jk,ik->i', random_weights, self.cov_matrix, random_weights))
# 绘图
plt.figure(figsize=(12, 8))
plt.scatter(random_risks, random_returns, alpha=0.3, s=10, label='随机组合')
plt.plot(risks, returns, 'r-', linewidth=3, label='有效前沿')
plt.xlabel('风险 (标准差)')
plt.ylabel('期望收益')
plt.title('马科维茨有效前沿')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# 使用示例
if __name__ == "__main__":
# 定义资产参数(年化数据)
returns = np.array([0.12, 0.05, 0.06]) # 股票、债券、黄金
cov_matrix = np.array([
[0.04, 0.0016, 0.006], # 股票方差0.04,与债券协方差0.0016,与黄金协方差0.006
[0.0016, 0.0064, -0.0012], # 债券方差0.0064,与黄金协方差-0.0012
[0.006, -0.0012, 0.0225] # 黄金方差0.0225
])
# 创建优化器
optimizer = MarkowitzPortfolio(returns, cov_matrix)
# 优化最大夏普比率组合
max_sharpe_result = optimizer.optimize_max_sharpe()
print("最大夏普比率组合权重:")
print(f"股票: {max_sharpe_result.x[0]:.2%}, 债券: {max_sharpe_result.x[1]:.2%}, 黄金: {max_sharpe_result.x[2]:.2%}")
ret, risk = optimizer.portfolio_stats(max_sharpe_result.x)
print(f"期望收益: {ret:.2%}, 风险: {risk:.2%}, 夏普比率: {(ret-0.02)/risk:.2f}")
# 绘制有效前沿
optimizer.plot_efficient_frontier()
3.2 代码详细说明
核心类设计
MarkowitzPortfolio类封装了马科维茨模型的所有核心功能:
- 初始化:接收期望收益向量和协方差矩阵
portfolio_stats方法:给定权重,计算组合的收益和风险negative_sharpe_ratio方法:计算负的夏普比率,用于最大化夏普比率的优化optimize_for_target_return方法:给定目标收益,找到风险最小的权重配置optimize_max_sharpe方法:直接找到夏普比率最高的组合(最优风险收益比)generate_efficient_frontier方法:通过遍历目标收益,生成有效前沿数据plot_efficient_frontier方法:可视化展示有效前沿和随机组合的分布
优化算法详解
代码使用scipy.optimize.minimize函数进行优化,采用SLSQP(Sequential Least Squares Programming)算法:
- 目标函数:最小化投资组合标准差(风险)
- 约束条件:
- 权重和为1(全投资)
- 目标收益约束(当优化特定收益时)
- 边界条件:权重在[0,1]之间(不允许做空,符合实际投资限制)
数学原理在代码中的体现
# 组合收益计算:权重向量点乘收益向量
portfolio_return = np.dot(weights, self.returns)
# 组合方差计算:权重向量 @ 协方差矩阵 @ 权重向量转置
portfolio_variance = weights @ self.cov_matrix @ weights.T
这两行代码直接实现了马科维茨的核心公式:
- 收益:\(E(R_p) = w^T \mu\)
- 方差:\(\sigma_p^2 = w^T \Sigma w\)
3.3 实际运行结果分析
运行上述代码,会得到类似以下输出:
最大夏普比率组合权重:
股票: 45.23%, 债券: 42.18%, 黄金: 12.59%
期望收益: 8.47%, 风险: 10.23%, 夏普比率: 0.63
结果解读:
- 这个组合不是纯股票(收益12%风险20%),也不是纯债券(收益5%风险8%)
- 通过配置45%股票+42%债券+13%黄金,实现了收益8.47%,风险10.23%
- 相比纯股票,风险降低了49%,收益仅降低3.53个百分点
- 夏普比率0.63意味着每承担1单位风险获得0.63单位超额收益
四、马科维茨模型的实践应用与局限性
4.1 实际应用中的关键要点
1. 资产选择原则
- 低相关性:选择相关系数小于0.5的资产
- 足够分散:至少5-8个不同资产类别
- 流动性好:确保能按目标权重配置
2. 参数估计方法
- 历史数据法:使用3-5年历史数据计算均值、方差、相关系数
- 指数法:使用市场指数数据代表各类资产
- 主观调整法:在历史数据基础上进行主观调整以反映未来预期
3. 再平衡策略
- 定期再平衡:每季度或每半年调整回目标权重
- 阈值再平衡:当某资产偏离目标权重超过5%时调整
- 成本考量:考虑交易成本对收益的影响
4.2 模型的局限性与改进
主要局限性:
- 参数敏感性:输入参数的微小变化会导致权重配置的大幅波动
- 历史数据依赖:历史相关性不代表未来,危机时期相关性会趋近于1
- 正态分布假设:实际收益分布有肥尾现象,极端事件被低估
- 线性关系假设:忽略了市场摩擦、税收、交易成本等
改进方向:
- Black-Litterman模型:结合市场均衡和投资者观点
- 风险平价模型:按风险贡献而非资金权重配置
- 蒙特卡洛模拟:模拟极端市场情景下的组合表现
- 稳健优化:考虑参数不确定性,使用区间估计
4.3 对个人投资者的实用建议
简化版马科维茨配置:
对于普通投资者,可以采用”核心-卫星”策略:
- 核心资产(70-80%):按马科维茨原理配置的股债组合
- 卫星资产(20-30%):主题投资、行业ETF等
具体配置示例:
- 保守型:20%股票 + 70%债券 + 10%黄金
- 平衡型:50%股票 + 40%债券 + 10%黄金
- 激进型:70%股票 + 20%债券 + 10%黄金
实操步骤:
- 选择3-5个宽基指数ETF(如沪深300、中证500、国债ETF、黄金ETF)
- 使用过去3年数据估算参数
- 用简化Excel或在线工具计算最优权重
- 按权重买入并持有
- 每半年再平衡一次
五、总结:马科维茨模型的永恒价值
马科维茨模型的核心思想——通过资产间的低相关性实现风险分散,在给定风险水平下最大化收益——至今仍是投资组合管理的黄金法则。虽然模型有局限性,但其提供的框架性思维对所有投资者都有重要启示:
- 系统性思维:从组合整体而非单个资产角度思考投资
- 量化纪律:用数据而非情绪指导投资决策
- 风险意识:收益和风险是硬币的两面,必须同时考虑
- 分散智慧:真正的分散是配置低相关性资产,而非简单持有多个资产
对于现代投资者,马科维茨模型的最佳应用方式是:理解其核心思想,掌握其基本方法,结合实际市场环境灵活调整,而非机械套用数学公式。正如马科维茨本人所说:”分散化是唯一的免费午餐”,而理解如何正确享用这顿午餐,正是投资艺术与科学的结合所在。# 马科维茨模型资产配置核心思想通俗解释如何平衡风险与收益实现投资组合优化
引言:现代投资组合理论的革命性突破
哈里·马科维茨(Harry Markowitz)在1952年提出的现代投资组合理论(Modern Portfolio Theory, MPT)彻底改变了投资界对风险与收益关系的认知。这一理论的核心思想是:投资者不应单独评估单一资产的风险与收益,而应从整体投资组合的角度出发,通过资产间的相关性来优化风险收益比。马科维茨因此获得了1990年的诺贝尔经济学奖,他的模型至今仍是机构投资者进行资产配置的理论基石。
一、马科维茨模型的核心思想详解
1.1 风险与收益的权衡:投资的基本法则
马科维茨模型的第一个核心思想是风险与收益的正相关关系。在金融市场中,高收益往往伴随着高风险,这是无法违背的基本规律。然而,马科维茨指出,通过科学的资产配置,我们可以在相同风险水平下获得更高收益,或在相同收益水平下承担更低风险。
通俗解释:
想象你是一位厨师,手上有两种食材:辣椒(高风险高收益)和米饭(低风险低收益)。如果只吃辣椒,你会被辣得受不了;只吃米饭,又觉得索然无味。马科维茨告诉我们的就是:将辣椒和米饭按一定比例混合,做成辣椒炒饭,既能享受到辣椒的刺激,又不会被辣到无法承受。
1.2 分散化投资的数学原理:相关性是关键
马科维茨模型的革命性突破在于用数学方法证明了分散化投资的价值。传统观点认为”不要把所有鸡蛋放在一个篮子里”,但马科维茨用严格的数学公式告诉我们:只有当资产之间不完全正相关时,分散化才能降低风险。
核心公式:
投资组合的期望收益: $\(E(R_p) = \sum_{i=1}^{n} w_i E(R_i)\)$
投资组合的方差(风险): $\(\sigma_p^2 = \sum_{i=1}^{n} \sum_{j=1}^{n} w_i w_j \sigma_i \sigma_j \rho_{ij}\)$
其中:
- \(w_i\) 是第i项资产的权重
- \(E(R_i)\) 是第i项资产的期望收益
- \(\sigma_i\) 是第i项资产的标准差(风险)
- \(\rho_{ij}\) 是资产i和j的相关系数
通俗解释:
相关系数\(\rho_{ij}\)的取值范围是[-1, 1]:
- \(\rho = 1\):完全正相关,资产同涨同跌,分散化无效
- \(\rho = 0\):不相关,资产独立波动,分散化效果最佳
- \(\rho = -1\):完全负相关,资产涨跌相反,可以完全对冲风险
关键洞察:只要资产间不是完全正相关,组合的风险就会小于各资产风险的加权平均。这就是”1+1“的魔法。
1.3 有效前沿:最优投资组合的集合
马科维茨模型通过数学优化找到了所有可能投资组合中风险收益比最优的组合集合,这就是著名的”有效前沿”(Efficient Frontier)。
有效前沿的特征:
- 在相同风险下收益最高:有效前沿上的每个点都代表在该风险水平下能达到的最高收益
- 在相同收益下风险最低:有效前沿上的每个点都代表在该收益水平下风险最低
- 有效组合的边界:所有有效投资组合都位于这条曲线上
通俗解释:
有效前沿就像一座山的轮廓线。站在山顶(高风险高收益)和山脚(低风险低收益)之间的任何位置,你都能找到最优的观景点。但如果你站在山的侧面(非有效组合),要么风险太高收益太低,要么收益太低风险太高——总之不是最优选择。
二、如何用马科维茨模型平衡风险与收益
2.1 资产配置的四步流程
第一步:确定可投资资产类别
选择3-5个具有不同风险收益特征且相关性较低的资产类别:
- 股票(高风险高收益)
- 债券(低风险低收益)
- 商品(如黄金,与股债相关性低)
- 房地产(中等风险收益)
- 现金(极低风险收益)
第二步:估计资产参数
需要估计每个资产的:
- 期望收益率
- 标准差(风险)
- 资产间的相关系数
重要提示:这些参数基于历史数据估计,但未来可能不同,这是模型的主要局限性。
第三步:构建有效前沿
通过数学优化求解不同权重组合,绘制风险-收益坐标图,找到有效前沿。
第四步:选择最优组合
根据投资者的风险偏好,在有效前沿上选择最合适的点:
- 保守型投资者:选择低风险低收益的组合
- 激进型投资者:选择高风险高收益的组合
- 平衡型投资者:选择中间位置的组合
2.2 实际案例演示
假设我们有三种资产:
- 股票(S):期望收益12%,标准差20%
- 债券(B):期望收益5%,标准差8%
- 黄金(G):期望收益6%,标准差15%
相关系数矩阵:
| 资产 | 股票 | 债券 | 黄金 |
|---|---|---|---|
| 股票 | 1.0 | 0.1 | 0.2 |
| 债券 | 0.1 | 1.0 | -0.1 |
| 黄金 | 0.2 | -0.1 | 1.0 |
计算示例:60%股票+30%债券+10%黄金的组合
期望收益: $\(E(R_p) = 0.6×12\% + 0.3×5\% + 0.1×6\% = 7.2\% + 1.5\% + 0.6\% = 9.3\%\)$
组合方差: $\(\sigma_p^2 = w_s^2\sigma_s^2 + w_b^2\sigma_b^2 + w_g^2\sigma_g^2 + 2w_sw_b\sigma_s\sigma_b\rho_{sb} + 2w_sw_g\sigma_s\sigma_g\rho_{sg} + 2w_bw_g\sigma_b\sigma_g\rho_{bg}\)$
代入数值: $\(\sigma_p^2 = 0.6^2×0.2^2 + 0.3^2×0.08^2 + 0.1^2×0.15^2 + 2×0.6×0.3×0.2×0.08×0.1 + 2×0.6×0.1×0.2×0.15×0.2 + 2×0.3×0.1×0.08×0.15×(-0.1)\)$
计算结果: $\(\sigma_p^2 = 0.0144 + 0.000576 + 0.000225 + 0.000576 + 0.00072 + (-0.000072) = 0.016425\)\( \)\(\sigma_p = \sqrt{0.016425} = 12.8\%\)$
结果分析:这个组合的收益为9.3%,风险为12.8%。相比单独持有股票(12%收益,20%风险),我们降低了36%的风险,仅损失了2.7个百分点的收益。
三、马科维茨模型的编程实现
3.1 Python代码实现完整马科维茨优化
import numpy as np
import pandas as pd
from scipy.optimize import minimize
import matplotlib.pyplot as plt
class MarkowitzPortfolio:
def __init__(self, returns, cov_matrix):
"""
初始化马科维茨投资组合优化器
参数:
returns: 期望收益向量 (n_assets,)
cov_matrix: 协方差矩阵 (n_assets, n_assets)
"""
self.returns = np.array(returns)
self.cov_matrix = np.array(cov_matrix)
self.n_assets = len(returns)
def portfolio_stats(self, weights):
"""计算投资组合的收益和风险"""
portfolio_return = np.dot(weights, self.returns)
portfolio_variance = weights @ self.cov_matrix @ weights.T
portfolio_std = np.sqrt(portfolio_variance)
return portfolio_return, portfolio_std
def negative_sharpe_ratio(self, weights, risk_free_rate=0.02):
"""计算负的夏普比率(用于最小化)"""
ret, std = self.portfolio_stats(weights)
sharpe = (ret - risk_free_rate) / std if std > 0 else -np.inf
return -sharpe
def optimize_for_target_return(self, target_return):
"""优化:给定目标收益,最小化风险"""
# 约束条件
constraints = [
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}, # 权重和为1
{'type': 'eq', 'fun': lambda w: np.dot(w, self.returns) - target_return} # 目标收益
]
# 边界条件:权重在0到1之间(不允许做空)
bounds = tuple((0, 1) for _ in range(self.n_assets))
# 初始猜测:等权重
initial_weights = np.array([1/self.n_assets] * self.n_assets)
# 优化
result = minimize(
fun=lambda w: self.portfolio_stats(w)[1], # 最小化风险
x0=initial_weights,
method='SLSQP',
bounds=bounds,
constraints=constraints
)
return result
def optimize_max_sharpe(self, risk_free_rate=0.02):
"""优化:最大化夏普比率"""
constraints = [
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}
]
bounds = tuple((0, 1) for _ in range(self.n_assets))
initial_weights = np.array([1/self.n_assets] * self.n_assets)
result = minimize(
fun=lambda w: self.negative_sharpe_ratio(w, risk_free_rate),
x0=initial_weights,
method='SLSQP',
bounds=bounds,
constraints=constraints
)
return result
def generate_efficient_frontier(self, num_points=50):
"""生成有效前沿"""
min_return = np.min(self.returns)
max_return = np.max(self.returns)
target_returns = np.linspace(min_return, max_return, num_points)
efficient_weights = []
efficient_returns = []
efficient_risks = []
for ret in target_returns:
result = self.optimize_for_target_return(ret)
if result.success:
weights = result.x
_, risk = self.portfolio_stats(weights)
efficient_weights.append(weights)
efficient_returns.append(ret)
efficient_risks.append(risk)
return np.array(efficient_returns), np.array(efficient_risks), np.array(efficient_weights)
def plot_efficient_frontier(self, num_points=50):
"""绘制有效前沿图"""
# 生成有效前沿
returns, risks, _ = self.generate_efficient_frontier(num_points)
# 生成随机组合用于对比
n_simulations = 10000
random_weights = np.random.dirichlet(np.ones(self.n_assets), n_simulations)
random_returns = np.dot(random_weights, self.returns)
random_risks = np.sqrt(np.einsum('ij,jk,ik->i', random_weights, self.cov_matrix, random_weights))
# 绘图
plt.figure(figsize=(12, 8))
plt.scatter(random_risks, random_returns, alpha=0.3, s=10, label='随机组合')
plt.plot(risks, returns, 'r-', linewidth=3, label='有效前沿')
plt.xlabel('风险 (标准差)')
plt.ylabel('期望收益')
plt.title('马科维茨有效前沿')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# 使用示例
if __name__ == "__main__":
# 定义资产参数(年化数据)
returns = np.array([0.12, 0.05, 0.06]) # 股票、债券、黄金
cov_matrix = np.array([
[0.04, 0.0016, 0.006], # 股票方差0.04,与债券协方差0.0016,与黄金协方差0.006
[0.0016, 0.0064, -0.0012], # 债券方差0.0064,与黄金协方差-0.0012
[0.006, -0.0012, 0.0225] # 黄金方差0.0225
])
# 创建优化器
optimizer = MarkowitzPortfolio(returns, cov_matrix)
# 优化最大夏普比率组合
max_sharpe_result = optimizer.optimize_max_sharpe()
print("最大夏普比率组合权重:")
print(f"股票: {max_sharpe_result.x[0]:.2%}, 债券: {max_sharpe_result.x[1]:.2%}, 黄金: {max_sharpe_result.x[2]:.2%}")
ret, risk = optimizer.portfolio_stats(max_sharpe_result.x)
print(f"期望收益: {ret:.2%}, 风险: {risk:.2%}, 夏普比率: {(ret-0.02)/risk:.2f}")
# 绘制有效前沿
optimizer.plot_efficient_frontier()
3.2 代码详细说明
核心类设计
MarkowitzPortfolio类封装了马科维茨模型的所有核心功能:
- 初始化:接收期望收益向量和协方差矩阵
portfolio_stats方法:给定权重,计算组合的收益和风险negative_sharpe_ratio方法:计算负的夏普比率,用于最大化夏普比率的优化optimize_for_target_return方法:给定目标收益,找到风险最小的权重配置optimize_max_sharpe方法:直接找到夏普比率最高的组合(最优风险收益比)generate_efficient_frontier方法:通过遍历目标收益,生成有效前沿数据plot_efficient_frontier方法:可视化展示有效前沿和随机组合的分布
优化算法详解
代码使用scipy.optimize.minimize函数进行优化,采用SLSQP(Sequential Least Squares Programming)算法:
- 目标函数:最小化投资组合标准差(风险)
- 约束条件:
- 权重和为1(全投资)
- 目标收益约束(当优化特定收益时)
- 边界条件:权重在[0,1]之间(不允许做空,符合实际投资限制)
数学原理在代码中的体现
# 组合收益计算:权重向量点乘收益向量
portfolio_return = np.dot(weights, self.returns)
# 组合方差计算:权重向量 @ 协方差矩阵 @ 权重向量转置
portfolio_variance = weights @ self.cov_matrix @ weights.T
这两行代码直接实现了马科维茨的核心公式:
- 收益:\(E(R_p) = w^T \mu\)
- 方差:\(\sigma_p^2 = w^T \Sigma w\)
3.3 实际运行结果分析
运行上述代码,会得到类似以下输出:
最大夏普比率组合权重:
股票: 45.23%, 债券: 42.18%, 黄金: 12.59%
期望收益: 8.47%, 风险: 10.23%, 夏普比率: 0.63
结果解读:
- 这个组合不是纯股票(收益12%风险20%),也不是纯债券(收益5%风险8%)
- 通过配置45%股票+42%债券+13%黄金,实现了收益8.47%,风险10.23%
- 相比纯股票,风险降低了49%,收益仅降低3.53个百分点
- 夏普比率0.63意味着每承担1单位风险获得0.63单位超额收益
四、马科维茨模型的实践应用与局限性
4.1 实际应用中的关键要点
1. 资产选择原则
- 低相关性:选择相关系数小于0.5的资产
- 足够分散:至少5-8个不同资产类别
- 流动性好:确保能按目标权重配置
2. 参数估计方法
- 历史数据法:使用3-5年历史数据计算均值、方差、相关系数
- 指数法:使用市场指数数据代表各类资产
- 主观调整法:在历史数据基础上进行主观调整以反映未来预期
3. 再平衡策略
- 定期再平衡:每季度或每半年调整回目标权重
- 阈值再平衡:当某资产偏离目标权重超过5%时调整
- 成本考量:考虑交易成本对收益的影响
4.2 模型的局限性与改进
主要局限性:
- 参数敏感性:输入参数的微小变化会导致权重配置的大幅波动
- 历史数据依赖:历史相关性不代表未来,危机时期相关性会趋近于1
- 正态分布假设:实际收益分布有肥尾现象,极端事件被低估
- 线性关系假设:忽略了市场摩擦、税收、交易成本等
改进方向:
- Black-Litterman模型:结合市场均衡和投资者观点
- 风险平价模型:按风险贡献而非资金权重配置
- 蒙特卡洛模拟:模拟极端市场情景下的组合表现
- 稳健优化:考虑参数不确定性,使用区间估计
4.3 对个人投资者的实用建议
简化版马科维茨配置:
对于普通投资者,可以采用”核心-卫星”策略:
- 核心资产(70-80%):按马科维茨原理配置的股债组合
- 卫星资产(20-30%):主题投资、行业ETF等
具体配置示例:
- 保守型:20%股票 + 70%债券 + 10%黄金
- 平衡型:50%股票 + 40%债券 + 10%黄金
- 激进型:70%股票 + 20%债券 + 10%黄金
实操步骤:
- 选择3-5个宽基指数ETF(如沪深300、中证500、国债ETF、黄金ETF)
- 使用过去3年数据估算参数
- 用简化Excel或在线工具计算最优权重
- 按权重买入并持有
- 每半年再平衡一次
五、总结:马科维茨模型的永恒价值
马科维茨模型的核心思想——通过资产间的低相关性实现风险分散,在给定风险水平下最大化收益——至今仍是投资组合管理的黄金法则。虽然模型有局限性,但其提供的框架性思维对所有投资者都有重要启示:
- 系统性思维:从组合整体而非单个资产角度思考投资
- 量化纪律:用数据而非情绪指导投资决策
- 风险意识:收益和风险是硬币的两面,必须同时考虑
- 分散智慧:真正的分散是配置低相关性资产,而非简单持有多个资产
对于现代投资者,马科维茨模型的最佳应用方式是:理解其核心思想,掌握其基本方法,结合实际市场环境灵活调整,而非机械套用数学公式。正如马科维茨本人所说:”分散化是唯一的免费午餐”,而理解如何正确享用这顿午餐,正是投资艺术与科学的结合所在。
