18. 多品种组合策略:分散化投资组合构建,夏普比率优化
各位同学,欢迎来到第十八讲。
前面我们一直在讲单个品种的基差套利怎么做。但说实话,只做一个品种,风险太集中了。你想想看,万一这个品种的基本面突然变了,或者流动性枯竭了,你怎么办?
所以,这一讲我们来聊聊多品种组合。说白了,就是不要把鸡蛋放在一个篮子里。但怎么放?放多少?这里面有大学问。
18.1 为什么要做多品种分散?
我刚开始做量化那会儿,也犯过傻。有一段时间,我死磕螺纹钢的基差套利,觉得这个品种我熟,波动规律摸得透。结果呢?遇到一次政策突变,螺纹钢的期现价差直接扭曲,我回撤了将近15%。
那次之后,我痛定思痛。单品种策略,无论你模型多好,都逃不过一个致命问题——尾部风险。你无法预测黑天鹅,但你可以通过分散化来对冲它。
核心逻辑:
- 不同品种的基差波动,相关性往往较低
- 一个品种亏钱时,另一个可能正在赚钱
- 组合的夏普比率,理论上可以高于任何一个单品种
18.2 组合构建的核心指标
构建多品种组合,不是简单地把资金平均分给每个品种。那样太粗糙了。我们需要用数学来优化。
我个人习惯用三个核心指标来筛选和配权:
| 指标 | 含义 | 我的经验阈值 |
|---|---|---|
| 夏普比率 | 单位风险带来的超额收益 | 大于1.5才考虑纳入 |
| 最大回撤 | 历史最差表现 | 不超过15% |
| 品种间相关性 | 两两之间的收益联动 | 低于0.5为佳 |
嗯,这里要注意。相关性不是越低越好。如果两个品种完全负相关,那组合的波动会很小,但收益也可能被抵消。我一般控制在0.2到0.5之间,既有分散效果,又不至于互相拖后腿。
18.3 夏普比率优化:数学框架
优化夏普比率,本质上是一个数学问题。我们要求解一组权重 w,使得组合的夏普比率最大。
公式很简单:
最大化: Sharpe = (E(R_p) - R_f) / σ_p
其中:
E(R_p) = w^T * μ (组合预期收益)
σ_p = sqrt(w^T * Σ * w) (组合波动率)
R_f = 无风险利率
但实际做的时候,有几个坑。我曾经踩过最大的坑就是——直接用历史数据算出来的最优权重,未来大概率失效。为什么?因为历史不会简单重复。
避坑指南:
我曾经用过去三年的数据跑出一个“完美”的权重组合,夏普高达2.8。结果实盘第一个月,夏普直接掉到0.6。后来我发现,那三年里有两个品种的相关性刚好处于历史低位,但之后迅速回归了。所以,我建议你一定要做滚动优化,而不是一次性优化。
18.4 Python实现:滚动夏普优化
下面是我常用的一个优化框架。代码不长,但很实用。
import numpy as np
import pandas as pd
from scipy.optimize import minimize
def calculate_sharpe(weights, mean_returns, cov_matrix, rf=0.02):
"""计算组合夏普比率"""
port_return = np.dot(weights, mean_returns)
port_vol = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
return (port_return - rf) / port_vol
def optimize_sharpe(mean_returns, cov_matrix, rf=0.02):
"""最大化夏普比率"""
num_assets = len(mean_returns)
args = (mean_returns, cov_matrix, rf)
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bounds = tuple((0, 0.3) for _ in range(num_assets)) # 单个品种权重不超过30%
result = minimize(
lambda w, *a: -calculate_sharpe(w, *a),
x0=np.array([1/num_assets]*num_assets),
args=args,
method='SLSQP',
bounds=bounds,
constraints=constraints
)
return result.x
# 滚动优化示例
def rolling_optimize(returns_df, window=252, rebalance=63):
"""每季度(63个交易日)重新优化一次"""
weights_history = []
for i in range(window, len(returns_df), rebalance):
train_data = returns_df.iloc[i-window:i]
mean_ret = train_data.mean() * 252 # 年化
cov_mat = train_data.cov() * 252
opt_weights = optimize_sharpe(mean_ret, cov_mat)
weights_history.append(opt_weights)
return weights_history
我的小技巧:
代码里我加了单个品种权重不超过30%的限制。为什么?因为如果不加限制,优化器往往会把所有资金押到历史表现最好的那个品种上。这违背了分散化的初衷。你想想看,如果某个品种权重到了80%,那还叫什么分散化?
18.5 知识体系流程图
下面这张图,是我自己梳理的多品种组合策略核心逻辑。你可以把它当作一个检查清单。
18.6 实盘中的再平衡策略
优化出权重只是第一步。更关键的是,你怎么执行?
我个人的做法是:每季度再平衡一次。为什么不是每天?因为频繁调仓会产生大量交易成本,吃掉你的利润。为什么不是每年?因为市场变化太快,一年不调,权重早就偏离了。
再平衡时,我遵循一个简单规则:
- 如果当前权重偏离目标权重超过5%,就调回目标
- 如果偏离在5%以内,就放着不动
- 遇到极端行情(比如某个品种单日波动超过3%),立即检查是否需要临时调仓
总结一下:
多品种组合策略,核心就三件事——选好品种、算好权重、管好再平衡。夏普比率优化是数学工具,但不是万能药。真正让你赚钱的,是对市场的理解和对纪律的坚持。
我见过太多人,模型跑得漂亮,实盘一塌糊涂。为什么?因为优化器给出的权重,他不敢执行。或者执行了,遇到回撤就慌了,手动改权重。嗯,这是人性,但也是亏损的根源。
好了,这一讲就到这里。记住,分散化是你唯一免费的午餐。好好利用它。