第十二章:基差交易的策略优化(三):多品种基差组合策略
聊完了单品种的基差策略优化,咱们得把格局打开一点。
你想想看,如果只盯着一个品种做基差,遇到这个品种的现货流动性枯竭,或者交割规则突然调整,那真是叫天天不应。我早年就吃过这个亏——2018年那会儿,我重仓押注某个化工品种的基差回归,结果交易所突然修改了仓单有效期,基差愣是两个月没回归,差点把我整破产。
从那以后,我养成了一个习惯:多品种基差组合。说白了,就是不要把鸡蛋放在一个篮子里,而且不同品种的基差波动往往存在互补性。
12.1 为什么要做多品种组合?
单品种基差策略有个致命弱点:尾部风险。比如某个品种突然出现逼仓行情,基差可以拉到离谱的程度,你的止损单根本来不及执行。
但多品种组合就不一样了。我统计过,国内商品期货市场里,黑色系、化工系、农产品系的基差驱动因素几乎不相关。螺纹钢的基差看房地产开工,PTA的基差看纺织需求,豆粕的基差看生猪存栏——这三个东西,你很难找到它们同时出幺蛾子的时刻。
12.2 组合构建的三大原则
我这些年摸索下来,多品种基差组合要想做好,得守住三条底线:
- 低相关性:品种之间的基差相关系数最好在0.3以下。我一般用过去60个交易日的滚动相关系数来筛选。
- 流动性分层:主力品种(如螺纹、铁矿)配40%,中等流动性品种(如甲醇、PP)配35%,小品种(如硅铁、锰硅)配25%。这样既保证容量,又保留弹性。
- 期限结构匹配:近月合约和远月合约的基差要分开处理。近月看现货回归,远月看预期修正。
嗯,这里要注意一点:不要为了分散而分散。我曾经把20个品种硬塞进组合里,结果发现有一半品种的基差波动根本没法解释,纯粹是噪音。后来我砍到8-10个品种,效果反而更好。
12.3 组合权重的动态调整
固定权重?那是新手干的事。真正的组合管理,权重必须是动态的。
我个人习惯用风险平价的思路来分配权重。具体来说:
- 计算每个品种基差策略的历史波动率(用ATR或者标准差都行)
- 让每个品种对组合总风险的贡献度相等
- 每周重新平衡一次
举个例子:假设螺纹钢基差策略的波动率是2%,PTA是1.5%,豆粕是1%。按照风险平价,螺纹钢的权重应该最低,豆粕最高。这样组合的整体波动率会稳定在1.2%左右,不会因为某个品种突然暴动而崩盘。
12.4 组合的再平衡与止损
再平衡频率是个老生常谈的问题。我的经验是:周频再平衡 + 日频监控。
每周一开盘前,我会重新计算一次权重。但每天收盘后,我会检查每个品种的基差是否触发了止损线。如果某个品种的基差单日波动超过3%,我会立即减仓一半,等第二天再决定是否补回来。
为什么这么设计?因为基差策略的止损不能太死板。我记得有一次,螺纹钢基差因为环保限产突然拉大,按模型应该止损,但我判断这是短期冲击,硬扛了两天,结果基差回归后赚了8%。所以,止损要设,但要有弹性。
12.5 一个简单的组合策略代码框架
下面是我常用的一个多品种基差组合策略框架,用Python写的。代码不复杂,但核心逻辑都在里面了。
import pandas as pd
import numpy as np
class MultiBasisPortfolio:
def __init__(self, symbols, lookback=60, rebalance_freq='W'):
self.symbols = symbols # 品种列表
self.lookback = lookback # 波动率计算窗口
self.rebalance_freq = rebalance_freq # 再平衡频率
def calc_volatility(self, basis_series):
"""计算基差序列的波动率"""
returns = basis_series.pct_change().dropna()
return returns.std() * np.sqrt(252) # 年化波动率
def risk_parity_weights(self, basis_df):
"""风险平价权重计算"""
vols = basis_df.apply(self.calc_volatility)
inv_vol = 1 / vols
weights = inv_vol / inv_vol.sum()
return weights
def adjust_with_confidence(self, weights, basis_df, threshold=2):
"""根据基差置信度调整权重"""
z_scores = (basis_df.iloc[-1] - basis_df.mean()) / basis_df.std()
bonus = (z_scores.abs() > threshold).astype(float) * 0.05
adjusted = weights + bonus
return adjusted / adjusted.sum()
def run_backtest(self, basis_data):
"""回测主逻辑"""
# basis_data: DataFrame, columns为品种, index为日期
portfolio_returns = []
current_weights = None
for date in basis_data.index:
if self._should_rebalance(date):
# 计算新权重
hist_data = basis_data.loc[:date].tail(self.lookback + 1)
weights = self.risk_parity_weights(hist_data)
weights = self.adjust_with_confidence(weights, hist_data)
current_weights = weights
# 计算当日组合收益
daily_ret = basis_data.loc[date].pct_change().fillna(0)
portfolio_ret = (daily_ret * current_weights).sum()
portfolio_returns.append(portfolio_ret)
return pd.Series(portfolio_returns, index=basis_data.index)
def _should_rebalance(self, date):
"""判断是否需要再平衡"""
# 这里用周频再平衡
return date.weekday() == 0 # 每周一
12.6 组合策略的绩效评估
评估多品种组合,不能只看夏普比率。我一般会关注三个指标:
| 指标 | 含义 | 我的经验阈值 |
|---|---|---|
| 最大回撤 | 组合从高点回落的最大幅度 | 控制在8%以内 |
| 收益/回撤比 | 年化收益除以最大回撤 | 大于2.0才算合格 |
| 品种集中度 | 前三大品种的权重之和 | 不超过60% |
我自己的实盘组合,过去三年年化收益在18%左右,最大回撤6.5%,收益回撤比2.77。说实话,这个成绩不算惊艳,但胜在稳定。每个月都能赚钱,虽然不多,但心里踏实。
12.7 多品种组合的知识体系
下面这张图,是我梳理的多品种基差组合策略的核心逻辑。你看一眼就能明白整个框架:
这张图把整个流程串起来了:从多品种基差数据出发,经过筛选、权重分配、执行风控,最后输出平滑的收益曲线。每一步都有具体的规则,不是拍脑袋决定的。
好了,多品种基差组合策略的核心内容就这些。说白了,就是用品种间的低相关性来平滑波动,用动态权重来捕捉机会,用严格的风控来守住底线。这套框架我用了四年,虽然每年都会根据市场环境微调,但底层逻辑从来没变过。