基于均值方差理论的组合优化
由bqldn97m创建,最终由bqldn97m 被浏览 9 用户
一、为什么需要组合优化
选出股票以后,还需要确定每只股票应该配置多少资金。
假设当前持有 10 只股票,最简单的方法是每只股票配置 10%,即等权组合。但等权没有区分不同股票的收益和风险特征。
组合优化希望解决的问题是:
在给定股票池和约束条件下,如何分配股票权重,使组合更符合预期的收益与风险目标?
本文基于 BigTrader,以创业板总市值前 10 只股票为例,重点介绍均值方差优化,并将其与等权、市值加权、最大收益、最小方差、最大夏普和风险平价进行对比。
二、均值方差优化的核心思路
均值方差理论同时考虑两个因素:
- 组合的历史平均收益;
- 组合的历史波动风险。
每只股票过去 252 个交易日的平均收益记录在 mu 中:
mu = ret.mean().values
股票自身的波动,以及不同股票之间的共同波动关系,记录在协方差矩阵 sigma 中:
sigma = (
ret.cov().values
+ 1e-8 * np.eye(n)
)
对于一组股票权重 w:
mu @ w
表示该权重对应的历史组合平均收益。
w @ sigma @ w
表示该权重对应的历史组合方差。组合方差越大,通常代表组合净值的波动越明显。
均值方差策略的目标函数为:
objective = lambda w: (
-(mu @ w)
+ context.gamma
/ 2
* (w @ sigma @ w)
)
这段代码可以拆成两部分:
负的历史组合平均收益
+
风险惩罚系数 × 历史组合方差
优化器执行最小化,因此会同时倾向于提高历史组合平均收益,并降低历史组合方差。
三、风险惩罚系数 gamma
本文设置:
context.gamma = 0.5
gamma 控制风险项在目标函数中的影响。
gamma 较小:
收益项的影响相对更大,组合通常更偏进取。
gamma 较大:
方差惩罚的影响相对更大,组合通常更偏稳健。
因此,均值方差并不是一种固定风格的组合。同一股票池使用不同的 gamma,可能得到明显不同的股票权重。
需要注意,当前代码直接使用日频平均收益和日频协方差。gamma=0.5 的作用与数据频率和目标函数的数值尺度有关,不能脱离当前代码环境,将 0.5 理解为适用于所有策略的固定风险水平。
四、权重约束与优化求解
均值方差使用 SLSQP 求解目标权重:
opt = minimize(
objective,
initial_weights,
method="SLSQP",
bounds=bounds,
constraints=constraints
)
优化初始值采用等权:
initial_weights = np.ones(n) / n
单只股票权重范围为 0% 至 20%:
bounds = [(0, 0.2)] * n
全部股票权重之和必须等于 100%:
constraints = {
"type": "eq",
"fun": lambda w: (
np.sum(w) - 1
)
}
这些约束可以概括为:
组合不使用负权重做空股票;
单只股票权重不超过 20%;
全部股票权重合计为 100%。
如果历史数据不足或优化器未成功收敛,策略退回等权,避免调仓过程被中断。
五、BigTrader 中的滚动优化
均值方差策略使用过去 252 个交易日的数据估计收益和风险:
context.lookback = 252
代码在每个调仓日之前提取历史价格,其中:
context.price_data["date"] < pd.Timestamp(current_date)
保证权重计算只使用当前调仓日之前的数据。
随后将 253 个价格观测转换为 252 个日收益率:
ret = (
price
.pct_change(fill_method=None)
.dropna()
.tail(context.lookback)
)
每 10 个交易日,策略都会使用当时能够观察到的历史数据重新计算 mu、sigma 和目标权重。
六、其他权重方法作为对照
为了判断均值方差是否真正改善了组合表现,本文同时使用 6 种方法作为对照。
1. 等权
weights = np.ones(n) / n
每只股票配置相同资金,不使用历史收益和协方差,是最基础的比较基准。
2. 市值加权
weights = (
market_cap
/ market_cap.sum()
)
按照当前总市值分配资金,市值越大的股票权重越高。
3. 最大收益
objective = lambda w: (
-(mu @ w)
)
只强调历史平均收益,不在目标函数中直接惩罚组合方差。
4. 最小方差
objective = lambda w: (
w @ sigma @ w
)
只强调降低历史组合方差,不直接使用历史平均收益。
5. 最大夏普
objective = lambda w: (
-(w @ mu)
/ np.sqrt(
w @ sigma @ w
+ 1e-12
)
)
优化过去 252 个交易日中的历史收益波动比。
6. 风险平价
risk_contribution = (
w * (sigma @ w)
/ (w @ sigma @ w + 1e-12)
)
通过调整资金权重,使各股票对组合方差的贡献尽量接近。
七、2025 年回测结果
| 方法 | 累计收益率 | 年化收益率 | 夏普比率 | 收益波动率 | 最大回撤 |
|---|---|---|---|---|---|
| 等权 | 62.89% | 65.86% | 1.64 | 32.32% | 20.75% |
| 市值加权 | 52.72% | 55.14% | 1.48 | 30.87% | 20.68% |
| 最大收益 | 77.54% | 81.35% | 1.52 | 43.58% | 25.75% |
| 最小方差 | 28.89% | 30.10% | 1.00 | 27.20% | 20.74% |
| 均值方差 | 74.66% | 78.31% | 1.48 | 43.45% | 25.70% |
| 最大夏普 | 56.98% | 59.63% | 1.29 | 40.13% | 25.82% |
| 风险平价 | 46.87% | 48.98% | 1.41 | 29.22% | 20.29% |
均值方差组合的主要指标为:
累计收益率:74.66%
年化收益率:78.31%
夏普比率:1.48
收益波动率:43.45%
最大回撤:25.70%
八、如何理解均值方差的回测表现
1. 收益水平接近最大收益
最大收益组合的年化收益率为 81.35%,均值方差组合为 78.31%。
均值方差虽然加入了方差惩罚,但仍然取得了接近最大收益组合的收益水平。
2. 风险没有明显低于最大收益
最大收益组合的收益波动率为 43.58%,均值方差组合为 43.45%,两者非常接近。
这说明在当前参数和样本中,gamma=0.5 对组合方差的惩罚作用相对有限,均值方差的权重可能仍然主要受到历史平均收益影响。
仅根据最终绩效指标,不能直接判断两种策略表现接近完全由 gamma=0.5 导致。进一步分析需要比较每个调仓日的实际权重。
3. 风险调整后收益没有超过等权
均值方差组合的夏普比率为 1.48,等权组合为 1.64。
这表明在本次 2025 年回测中,均值方差取得了较高的绝对收益,但没有在风险调整后收益指标上超过等权。
该结果也说明,复杂优化方法是否有效,不能只观察最终收益,还需要与简单基准进行比较。
九、均值方差可以如何改进
1. 测试不同的 gamma
context.gamma = 0.1
context.gamma = 0.5
context.gamma = 1.0
context.gamma = 2.0
观察风险惩罚增强后,股票权重、组合波动和收益如何变化。
2. 保存每期目标权重
建议保存每个调仓日的目标权重,进一步检查:
- 权重是否过度集中;
- 不同
gamma是否真正改变组合结构; - 权重是否在相邻调仓日频繁变化;
- 组合是否长期集中于少数股票。
3. 增加换手惩罚
均值方差目标函数可以加入新旧权重差异,用于降低频繁调仓:
新的优化目标
=
原均值方差目标
+
换手惩罚系数 × 新旧权重差异
4. 改进历史参数估计
后续可以研究:
- 收益均值收缩;
- 协方差收缩;
- 指数加权协方差;
- 不同历史窗口;
- 异常收益率处理。
5. 进行样本外验证
本次结果只来自 2025 年。在用于实际交易前,还需要完成:
- 多年度回测;
- 不同市场状态的分段检验;
- 滚动样本外测试;
- 参数敏感性分析;
- 换手率和交易成本评估。
十、总结
均值方差组合优化的核心,是在同一个目标函数中同时考虑历史平均收益和历史组合方差。
收益项:
鼓励更高的历史组合平均收益
风险项:
惩罚更高的历史组合方差
gamma:
控制收益和风险之间的侧重程度
在本次创业板 Top10 的 2025 年回测中,均值方差取得 78.31% 的年化收益率,表现仅次于最大收益组合。
但其收益波动率为 43.45%,与最大收益组合非常接近,夏普比率也没有超过等权。
因此,本次结果更适合说明:
均值方差为收益与风险提供了统一的优化框架,但最终效果仍然取决于历史参数估计、风险惩罚系数、权重约束和样本区间。
组合优化并不存在不受市场环境影响的固定最优解。均值方差是否具有稳定优势,还需要通过不同参数和样本外数据进一步验证。
风险提示
本文仅用于 BigTrader 组合优化功能展示和量化研究教学,不构成任何投资建议。
文中绩效结果只对应当前代码、当前参数、当前股票池和 2025 年回测区间。
历史回测结果不能代表未来表现。实际策略表现还可能受到样本区间、参数设置、交易成本、市场状态和历史参数估计误差等因素影响。