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 知识体系流程图

下面这张图,是我自己梳理的多品种组合策略核心逻辑。你可以把它当作一个检查清单。

多品种组合策略核心流程 1. 品种筛选 2. 相关性分析 3. 权重优化 夏普 > 1.5 最大回撤 < 15% 流动性充足 两两相关性 < 0.5 避免同板块扎堆 考虑跨品种对冲 滚动优化 权重上限约束 再平衡周期 4. 回测验证 5. 实盘监控 ⚠️ 关键提醒 不要过度优化 避免过拟合 关注交易成本 定期再平衡 警惕相关性突变

18.6 实盘中的再平衡策略

优化出权重只是第一步。更关键的是,你怎么执行?

我个人的做法是:每季度再平衡一次。为什么不是每天?因为频繁调仓会产生大量交易成本,吃掉你的利润。为什么不是每年?因为市场变化太快,一年不调,权重早就偏离了。

再平衡时,我遵循一个简单规则:

  • 如果当前权重偏离目标权重超过5%,就调回目标
  • 如果偏离在5%以内,就放着不动
  • 遇到极端行情(比如某个品种单日波动超过3%),立即检查是否需要临时调仓

总结一下:

多品种组合策略,核心就三件事——选好品种、算好权重、管好再平衡。夏普比率优化是数学工具,但不是万能药。真正让你赚钱的,是对市场的理解和对纪律的坚持。

我见过太多人,模型跑得漂亮,实盘一塌糊涂。为什么?因为优化器给出的权重,他不敢执行。或者执行了,遇到回撤就慌了,手动改权重。嗯,这是人性,但也是亏损的根源。

好了,这一讲就到这里。记住,分散化是你唯一免费的午餐。好好利用它。


公众号:蓝海资料掘金营,微信deep3321