7. 均值回归策略设计:布林带策略、Z-score策略、卡尔曼滤波动态基差跟踪

均值回归,说白了就是「涨多了会跌,跌多了会涨」。在基差交易里,这个逻辑特别适用。基差不会无限扩大,也不会无限缩小,它总在某个合理区间内晃悠。我们要做的,就是抓住它偏离均值的那一刻,赌它回来。

今天咱们聊三种主流方法:布林带、Z-score、还有卡尔曼滤波。前两个是经典派,第三个是动态派。我个人习惯是先用布林带做快速扫描,再用卡尔曼滤波做精细入场。嗯,咱们一个一个来。

7.1 布林带策略:最直观的均值回归工具

布林带由三条线组成:中轨是移动平均线,上下轨是标准差通道。当基差触及上轨,说明偏离太大,大概率要回落;触及下轨,则可能反弹。

我在项目中遇到过一个问题:布林带参数怎么选?周期太短,信号太多,假突破频繁;周期太长,反应迟钝,错过行情。我的经验是,对于股指期货基差,20周期、2倍标准差是个不错的起点。

核心逻辑: 基差突破上轨 → 做空基差(卖期货买现货);基差跌破下轨 → 做多基差(买期货卖现货)。
import numpy as np
import pandas as pd

def bollinger_bands_strategy(basis, window=20, num_std=2):
    """
    布林带基差交易策略
    basis: 基差序列
    window: 移动平均窗口
    num_std: 标准差倍数
    """
    rolling_mean = basis.rolling(window=window).mean()
    rolling_std = basis.rolling(window=window).std()
    
    upper_band = rolling_mean + num_std * rolling_std
    lower_band = rolling_mean - num_std * rolling_std
    
    # 生成信号
    signals = pd.Series(0, index=basis.index)
    signals[basis > upper_band] = -1  # 做空基差
    signals[basis < lower_band] = 1   # 做多基差
    
    return signals, upper_band, lower_band
避坑指南: 我曾经吃过布林带的亏——趋势行情里,基差突破上轨后继续扩大,做空直接被拉爆。所以一定要配合趋势过滤,比如只在震荡市用布林带。

7.2 Z-score策略:标准化后的均值回归

Z-score说白了就是把基差变成标准分数。公式很简单:(当前基差 - 均值) / 标准差。Z-score的绝对值越大,回归的概率越高。

你想想看,Z-score=2意味着当前基差偏离均值2个标准差。根据正态分布,这种情况发生的概率只有5%左右。嗯,这时候入场,胜率确实高。

Z-score 范围 偏离程度 交易动作
Z > 2 严重偏高 做空基差
Z < -2 严重偏低 做多基差
|Z| < 0.5 正常范围 不交易
def zscore_strategy(basis, window=20, entry_threshold=2.0, exit_threshold=0.5):
    """
    Z-score基差交易策略
    """
    rolling_mean = basis.rolling(window=window).mean()
    rolling_std = basis.rolling(window=window).std()
    
    zscore = (basis - rolling_mean) / rolling_std
    
    # 入场信号
    entry_long = zscore < -entry_threshold
    entry_short = zscore > entry_threshold
    
    # 出场信号
    exit_long = zscore > -exit_threshold
    exit_short = zscore < exit_threshold
    
    return zscore, entry_long, entry_short, exit_long, exit_short
我的习惯: Z-score策略我一般用滚动窗口计算,窗口大小选60个交易日。太短了噪声多,太长了反应慢。另外,我会加一个「回归确认」条件——Z-score从极值回落0.5个标准差再入场,避免抄底摸顶。

7.3 卡尔曼滤波动态基差跟踪

布林带和Z-score有个共同问题:它们假设均值和标准差是固定的。但市场是动态的,基差的均值会漂移。比如2015年股灾期间,基差均值从-10点漂到了-50点。用固定均值去判断,肯定死得很惨。

卡尔曼滤波就是来解决这个问题的。它能动态估计基差的「真实均值」和「波动率」,实时更新。说白了,它像一个自适应滤波器,跟着市场变。

import pykalman

def kalman_basis_tracker(basis):
    """
    卡尔曼滤波动态基差跟踪
    """
    # 初始化卡尔曼滤波器
    kf = pykalman.KalmanFilter(
        transition_matrices=[1],
        observation_matrices=[1],
        initial_state_mean=basis[0],
        initial_state_covariance=1,
        observation_covariance=1,
        transition_covariance=0.01
    )
    
    # 滤波
    state_means, state_covs = kf.filter(basis.values)
    
    # 动态均值 = 滤波后的状态
    dynamic_mean = pd.Series(state_means.flatten(), index=basis.index)
    
    # 动态标准差 = 观测残差的标准差
    residuals = basis - dynamic_mean
    dynamic_std = residuals.rolling(window=20).std()
    
    # 生成信号
    zscore_dynamic = residuals / dynamic_std
    signals = pd.Series(0, index=basis.index)
    signals[zscore_dynamic > 2] = -1
    signals[zscore_dynamic < -2] = 1
    
    return signals, dynamic_mean, dynamic_std
卡尔曼滤波 vs 传统方法:
  • 传统方法:均值固定,适合平稳市场
  • 卡尔曼滤波:均值动态,适合结构变化的市场
  • 代价:卡尔曼滤波需要调参(观测噪声、过程噪声),参数敏感

我记得有一次做原油期货的基差交易,布林带和Z-score都失效了,因为基差均值在持续下移。换成卡尔曼滤波后,信号质量明显提升。嗯,这就是动态跟踪的价值。

7.4 三种策略的对比与选择

没有完美的策略,只有适合的策略。我一般这样选:

  • 布林带:适合快速扫描,直观易懂。我用来做初筛,看哪些品种的基差到了极端位置。
  • Z-score:适合标准化比较,跨品种对比时特别好用。比如同时看10个品种的基差,Z-score可以统一阈值。
  • 卡尔曼滤波:适合精细入场,尤其是市场结构发生变化时。但参数调起来比较麻烦,新手容易过拟合。
我的建议: 先用布林带或Z-score做粗筛,选出候选品种。然后用卡尔曼滤波做精细入场判断。这样既保证了效率,又提高了精度。
均值回归策略知识体系 均值回归策略 布林带策略 Z-score策略 卡尔曼滤波 移动平均 标准差 标准化 阈值 动态均值 自适应 粗筛用布林带/Z-score,精细入场用卡尔曼滤波

最后说一句:均值回归策略最怕的就是「趋势延续」。如果基差突破后不回归,反而继续扩大,那就是亏损的来源。所以一定要设止损,别硬扛。我个人的止损线是基差偏离均值3个标准差,或者亏损达到总资金的1%。

好了,这一章就到这里。记住:没有完美的策略,只有不断优化的交易系统。

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