第十六章 多品种与多策略组合:分散化投资、资金分配、相关性矩阵

各位同学,欢迎来到第十六讲。

前面我们讲了单品种的基差套利,也讲了如何构建一个策略。但说实话,在实盘里只靠一个品种、一个策略吃饭,风险太大了。我见过不少交易员,一个策略回测漂亮得不行,一上实盘就翻车。为什么?因为市场环境一变,那个策略就失效了。

所以这一章,我们来聊聊怎么把多个品种、多个策略组合起来。说白了,就是不要把鸡蛋放在一个篮子里。

16.1 为什么要做多品种多策略组合?

先问大家一个问题:你辛辛苦苦开发了一个螺纹钢的跨期套利策略,回测年化收益30%,最大回撤5%。你兴冲冲地上了实盘,结果呢?

结果可能是:螺纹钢突然来了个政策限产,价差直接崩了。你的策略瞬间失效。

这就是单一品种的风险。我个人的习惯是,至少同时跑5-8个不相关的品种。比如黑色系、能化、农产品各选几个。这样即使一个品种出问题,整体组合也不会太难看。

核心逻辑:多品种组合的核心不是增加收益,而是降低波动。收益是多个策略的平均,但风险却不是简单的相加——只要品种间相关性够低,组合的风险会显著下降。

16.2 相关性矩阵:你的组合体检报告

做组合之前,第一件事就是算相关性矩阵。我刚开始做组合时,犯过一个错误:选了螺纹钢、热卷、铁矿石三个品种。结果发现它们相关性高达0.9以上,说白了就是同一个东西。组合了个寂寞。

相关性矩阵长什么样?我们来看一个例子:

品种 螺纹钢 热卷 铁矿石 PTA 甲醇
螺纹钢 1.00 0.92 0.85 0.12 0.08
热卷 0.92 1.00 0.80 0.10 0.05
铁矿石 0.85 0.80 1.00 0.15 0.11
PTA 0.12 0.10 0.15 1.00 0.45
甲醇 0.08 0.05 0.11 0.45 1.00

你看,螺纹钢、热卷、铁矿石之间相关性极高。而它们跟PTA、甲醇的相关性就很低。这才是我们想要的组合。

计算相关性矩阵的代码很简单:

import pandas as pd
import numpy as np

# 假设df是各品种的日收益率数据
# 列名是品种名称
corr_matrix = df.corr()

# 可视化
import seaborn as sns
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('品种间相关性矩阵')
plt.show()

我的经验:选择组合品种时,我一般要求两两相关性不超过0.6。如果超过0.7,我会考虑只保留其中一个。另外,记得用滚动窗口计算相关性——静态的相关性矩阵会骗人,市场结构是会变的。

16.3 资金分配:怎么分才科学?

选好了品种,接下来就是资金分配。这里有几个常见的方法:

16.3.1 等权分配

最简单粗暴的方法:每个品种分配相同的资金。比如你有100万,选了5个品种,每个分20万。

优点:简单,容易执行。缺点:没有考虑品种的风险差异。波动大的品种会主导组合表现。

16.3.2 风险平价

这是我个人比较推崇的方法。核心思想:让每个品种对组合的风险贡献相等。

def risk_parity_weights(cov_matrix):
    """
    计算风险平价权重
    cov_matrix: 协方差矩阵
    """
    n = cov_matrix.shape[0]
    
    # 初始化权重
    w = np.ones(n) / n
    
    # 迭代求解
    for _ in range(100):
        # 计算边际风险贡献
        portfolio_var = w @ cov_matrix @ w
        marginal_contrib = cov_matrix @ w / np.sqrt(portfolio_var)
        
        # 计算风险贡献
        risk_contrib = w * marginal_contrib
        
        # 调整权重使风险贡献相等
        target_risk = np.mean(risk_contrib)
        w = w * (target_risk / risk_contrib)
        w = w / w.sum()
    
    return w

# 使用示例
cov = df.cov()
weights = risk_parity_weights(cov)
print('风险平价权重:', weights)

你想想看,风险平价的好处是什么?它自动给波动大的品种分配更少的资金,给波动小的品种分配更多资金。这样组合的整体波动会更稳定。

16.3.3 波动率倒数加权

一个更简单的变体:权重与波动率成反比。

vol = df.std()
weights = (1 / vol) / (1 / vol).sum()
print('波动率倒数权重:', weights)

注意:我曾经吃过一次亏。用历史波动率计算权重,结果市场突然变盘,波动率飙升,权重没来得及调整,组合回撤很大。所以建议用滚动窗口计算,并且设置权重调整的阈值——比如偏离超过20%就重新平衡。

16.4 多策略组合:不只是品种

除了多品种,我们还可以做多策略组合。比如同一个品种上,同时跑趋势跟踪、均值回归、基差套利三个策略。

为什么?因为不同策略在不同市场环境下表现不同。趋势跟踪在单边行情中赚钱,均值回归在震荡行情中赚钱,基差套利在期限结构稳定时赚钱。组合起来,就能适应更多市场环境。

我个人的做法是:先给每个策略分配一个基础权重,然后根据近期表现动态调整。比如过去20个交易日,哪个策略表现好,就给它多加一点权重。

def dynamic_strategy_allocation(strategy_returns, lookback=20):
    """
    动态策略权重分配
    strategy_returns: 各策略的日收益率DataFrame
    """
    # 计算滚动夏普比率
    rolling_sharpe = strategy_returns.rolling(lookback).mean() / \
                     strategy_returns.rolling(lookback).std()
    
    # 权重与夏普比率成正比
    weights = rolling_sharpe / rolling_sharpe.sum(axis=1).values.reshape(-1, 1)
    
    # 限制最大权重,防止过度集中
    weights = weights.clip(upper=0.5)
    weights = weights.div(weights.sum(axis=1), axis=0)
    
    return weights

16.5 组合的再平衡

权重不是一成不变的。需要定期再平衡。我一般每周五收盘后做一次再平衡。

再平衡的频率怎么定?

  • 太频繁:交易成本高,磨损大
  • 太少:权重偏离目标太远,风险暴露失控

我建议设置一个阈值。比如当某个品种的权重偏离目标超过20%时,触发再平衡。这样既控制了成本,又控制了风险。

避坑指南:我曾经设置过每日再平衡,结果一个月下来,手续费吃掉了一半收益。后来改成周频+阈值触发,效果好多了。记住,再平衡不是越频繁越好。

16.6 本章知识体系

下面这张图总结了多品种多策略组合的核心逻辑:

多品种多策略组合核心框架 品种选择 相关性矩阵分析 资金分配 风险平价 / 波动率倒数 策略组合 多策略动态权重 定期再平衡(周频+阈值) 持续监控与调整 关键监控指标 • 组合夏普比率 • 最大回撤 • 品种间相关性变化 • 策略表现排名 • 权重偏离度 输出:稳健的多品种多策略组合 低相关性 + 风险平价 + 动态调整 = 稳定收益

16.7 实战中的几个要点

最后,分享几个我在实战中总结的要点:

  1. 不要过度优化:组合的权重计算越复杂,越容易过拟合。有时候等权分配就挺好。
  2. 关注尾部风险:相关性在极端行情下会趋同。2008年金融危机时,所有资产的相关性都接近1。所以即使组合看起来很分散,也要留足安全边际。
  3. 交易成本不可忽视:多品种多策略意味着更多的交易。一定要把滑点和手续费算进去,否则回测漂亮,实盘亏钱。
  4. 心理准备:组合的收益曲线会比单策略平滑,但也会出现所有策略同时亏损的时候。这时候不要慌,坚持纪律。

我的一个小技巧:我会在组合里留5%的现金仓位。平时不动,遇到极端行情时用来抄底。这个现金仓位就像消防员,平时看着没用,关键时刻能救命。

好了,这一章的内容就到这里。多品种多策略组合是一个系统工程,需要不断迭代优化。希望你们能把这些方法用起来,构建属于自己的稳健组合。

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