第26章 基差交易的绩效归因:Brinson归因、因子归因、交易成本归因、策略改进方向
做基差交易的朋友,最怕什么?
怕赚了钱不知道为啥赚,亏了钱不知道为啥亏。
我见过太多人,回测曲线漂亮得不行,实盘一跑就变形。为什么?因为绩效归因没做好。你连钱是怎么来的都不清楚,怎么敢上仓位?
这一章,我们就来拆解基差交易的绩效归因。说白了,就是给策略做「体检」——看看哪些地方做对了,哪些地方在拖后腿。
26.1 Brinson归因:拆解超额收益的来源
Brinson归因最早用在股票组合上,但用在基差交易里,一样好使。
它的核心逻辑很简单:把总收益拆成三部分——配置收益、选券收益、交互收益。
基差交易中的Brinson三因子:
- 配置收益:你选择做多哪个品种、做空哪个品种带来的收益
- 选券收益:同一品种内,你选的具体合约带来的超额
- 交互收益:配置和选券的交叉影响
举个例子。你同时做多IC主力合约、做空IF主力合约。如果IC涨得比IF多,配置收益就是正的。但如果你选的是IC次月合约而不是主力合约,次月合约涨得更多,那这部分就是选券收益。
我个人习惯用Python写一个简单的Brinson分解函数。代码不长,但很实用:
def brinson_decomposition(portfolio_returns, benchmark_returns,
portfolio_weights, benchmark_weights):
"""
基差交易的Brinson归因
portfolio_returns: 组合各品种收益率
benchmark_returns: 基准各品种收益率
"""
# 配置收益
allocation = (portfolio_weights - benchmark_weights) * benchmark_returns
# 选券收益
selection = benchmark_weights * (portfolio_returns - benchmark_returns)
# 交互收益
interaction = (portfolio_weights - benchmark_weights) * \
(portfolio_returns - benchmark_returns)
return {
'allocation': allocation.sum(),
'selection': selection.sum(),
'interaction': interaction.sum(),
'total': (allocation + selection + interaction).sum()
}
嗯,这里要注意:基准怎么选?我一般用「等权做多所有品种」作为基准。这样配置收益就能反映出你主动偏离基准的能力。
26.2 因子归因:找到驱动收益的底层逻辑
Brinson归因告诉你「赚了多少钱」,因子归因告诉你「为什么赚」。这是两个层次的问题。
基差交易的因子归因,我通常关注这几个因子:
| 因子名称 | 含义 | 计算方式 |
|---|---|---|
| 基差动量因子 | 基差趋势的延续性 | 过去N日基差变化率 |
| 基差均值回复因子 | 基差偏离历史均值的程度 | 当前基差 - 历史均值 |
| 波动率因子 | 基差波动带来的交易机会 | 基差标准差 |
| 流动性因子 | 合约流动性对滑点的影响 | 持仓量/成交量 |
我在项目中遇到过这样的情况:一个基差策略回测年化收益20%,但因子归因一做,发现80%的收益来自基差动量因子。这意味着什么?意味着策略本质上就是个趋势跟踪策略。一旦基差趋势反转,策略就会大幅回撤。
因子归因的代码实现,我习惯用线性回归:
import statsmodels.api as sm
def factor_attribution(returns, factor_data):
"""
returns: 策略日收益率序列
factor_data: 各因子暴露度 DataFrame
"""
X = sm.add_constant(factor_data)
model = sm.OLS(returns, X).fit()
# 因子贡献 = 因子暴露 * 因子收益率
factor_contribution = model.params[1:] * factor_data.mean()
return {
'factor_contribution': factor_contribution,
'r_squared': model.rsquared,
'residual': model.resid.std()
}
R方很重要。如果R方太低,说明还有重要的因子没抓到。我曾经有个策略R方只有0.3,后来发现是忽略了「交割日效应」这个因子——交割日前后的基差行为完全不同。
避坑指南:因子之间可能存在多重共线性。比如基差动量因子和基差均值回复因子,在趋势行情里相关性很高。做归因前,先算一下因子间的相关系数矩阵。我一般设阈值0.7,超过的就合并或剔除一个。
26.3 交易成本归因:别让手续费吃掉你的利润
交易成本归因,是基差交易里最容易忽略、也最致命的一环。
你想想看,基差交易的利润本来就不厚。一个跨期套利,基差从5个点回归到0,毛利也就5个点。如果双边手续费加滑点吃掉3个点,那实际利润就只剩2个点了。
交易成本归因,我把它拆成三块:
- 显性成本:手续费、印花税、过户费。这些是固定的,好算。
- 隐性成本:滑点、冲击成本。这些是变动的,难算。
- 机会成本:保证金占用、资金成本。这个容易被忽略。
我建议用「实际成交价 vs 理论成交价」的差值来估算滑点。代码实现:
def slippage_analysis(trade_records, theoretical_prices):
"""
trade_records: 实际成交记录
theoretical_prices: 理论成交价(如盘口中间价)
"""
trade_records['slippage'] = abs(
trade_records['actual_price'] - theoretical_prices
)
avg_slippage = trade_records['slippage'].mean()
total_slippage_cost = avg_slippage * trade_records['volume'].sum()
return {
'avg_slippage_per_trade': avg_slippage,
'total_slippage_cost': total_slippage_cost,
'slippage_ratio': total_slippage_cost / trade_records['pnl'].sum()
}
警告:滑点估算一定要用实盘数据,别用回测数据。回测里的滑点假设往往太乐观。我见过一个策略,回测滑点设了0.5个tick,实盘滑点平均1.8个tick——直接导致策略从盈利变成亏损。
26.4 策略改进方向:从归因结果出发
归因做完了,下一步就是改进。我总结了几条常见的改进路径:
- 如果配置收益低:说明品种选择有问题。试试加入更多品种,或者用机器学习做品种筛选。
- 如果选券收益低:说明合约选择不够精细。可以考虑加入「主力合约切换」信号,或者做跨期价差的动态调整。
- 如果因子归因R方低:说明还有重要因子没抓到。试试加入「市场情绪因子」或「资金流向因子」。
- 如果交易成本占比高:降低交易频率,或者改用限价单代替市价单。
我个人最常用的是「分层改进法」:先改成本最高的那块,再改次高的。别想着一次把所有问题都解决,那样反而容易顾此失彼。
举个例子。我有个学生做螺纹钢基差交易,归因后发现交易成本占了总利润的60%。他第一反应是优化策略参数,想提高胜率。我说别急,先把成本降下来。后来他把交易频率从每天10次降到每天3次,滑点成本直接砍了一半。策略从亏损变成了微利。
你看,有时候改进方向不在策略本身,而在执行层面。
知识体系总览
下面这张图,把基差交易绩效归因的完整框架画出来了。你可以把它当作一个检查清单——每次复盘策略时,按这个流程走一遍。
最后说一句:绩效归因不是一次性工作。我建议每季度做一次全面归因,每月做一次快速归因。市场在变,策略也在变,归因结果能帮你及时发现问题。
嗯,这一章的内容就到这里。归因做得好,策略才能走得远。
公众号:蓝海资料掘金营,微信deep3321