Skip to main content

均值回归策略

均值回归策略假设价格会围绕其均值波动,当价格偏离均值过大时会向均值回归。


什么是均值回归?

金融资产的价格长期来看会围绕某个均值上下波动:

  • 价格远低于均值 → 超卖 → 价格有上涨回归的动力
  • 价格远高于均值 → 超买 → 价格有下跌回归的压力

均值回归策略就是在价格偏离均值时逆向交易,捕捉回归过程中的利润。


Z-Score 均值回归

最经典的量化方法:用 Z-Score 衡量价格的偏离程度。

import pandas as pd
import numpy as np

def zscore_mean_reversion(df, window=20, entry_threshold=2.0, exit_threshold=0.5):
"""
Z-Score 均值回归策略

当 Z-Score 低于 -2 → 超卖 → 买入
当 Z-Score 高于 +2 → 超买 → 卖出

参数:
window: 计算均值和标准差的时间窗口
entry_threshold: 入场阈值
exit_threshold: 出场阈值
"""
df = df.copy()

# 计算均值和标准差
df['ma'] = df['close'].rolling(window=window).mean()
df['std'] = df['close'].rolling(window=window).std()

# 计算 Z-Score(偏离度)
df['zscore'] = (df['close'] - df['ma']) / df['std']

# 生成信号
df['position'] = 0 # 0=空仓, 1=多头, -1=空头

# 入场信号
df.loc[df['zscore'] < -entry_threshold, 'position'] = 1 # 超卖 → 买入
df.loc[df['zscore'] > entry_threshold, 'position'] = -1 # 超买 → 卖空

# 出场信号:Z-Score 回归到 exit_threshold 以内
df.loc[(df['zscore'] > -exit_threshold) & (df['zscore'] < exit_threshold), 'position'] = 0

return df

布林带策略

布林带是均值回归的经典可视化工具:

def bollinger_bands_strategy(df, window=20, num_std=2):
"""
布林带策略

布林带 = 中轨(MA)± 标准差倍数

- 价格触及下轨 → 超卖 → 买入
- 价格触及上轨 → 超买 → 卖出
- 价格回到中轨 → 平仓
"""
df = df.copy()

# 计算布林带
df['bb_middle'] = df['close'].rolling(window).mean()
df['bb_std'] = df['close'].rolling(window).std()
df['bb_upper'] = df['bb_middle'] + num_std * df['bb_std']
df['bb_lower'] = df['bb_middle'] - num_std * df['bb_std']

# 计算带宽
df['bb_width'] = (df['bb_upper'] - df['bb_lower']) / df['bb_middle']

# 生成信号
df['signal'] = 0
df.loc[df['close'] <= df['bb_lower'], 'signal'] = 1 # 触及下轨 → 买入
df.loc[df['close'] >= df['bb_upper'], 'signal'] = -1 # 触及上轨 → 卖出

return df

可视化布林带

import matplotlib.pyplot as plt

def plot_bollinger_bands(df, window=20):
"""可视化布林带策略"""
df = bollinger_bands_strategy(df, window)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10),
gridspec_kw={'height_ratios': [3, 1]})

# 上图:价格和布林带
ax1.plot(df.index, df['close'], label='收盘价', color='#333')
ax1.plot(df.index, df['bb_middle'], label='中轨 (MA)', color='#faad14', linewidth=1)
ax1.plot(df.index, df['bb_upper'], label='上轨', color='#f5222d',
linewidth=1, linestyle='--', alpha=0.7)
ax1.plot(df.index, df['bb_lower'], label='下轨', color='#52c41a',
linewidth=1, linestyle='--', alpha=0.7)
ax1.fill_between(df.index, df['bb_upper'], df['bb_lower'], alpha=0.1)

# 标记交易信号
buy = df[df['signal'] == 1]
sell = df[df['signal'] == -1]
ax1.scatter(buy.index, buy['close'], color='red', marker='^',
s=100, label='买入', zorder=5)
ax1.scatter(sell.index, sell['close'], color='green', marker='v',
s=100, label='卖出', zorder=5)

ax1.set_title(f'布林带策略 (MA{window}, ±2σ)')
ax1.legend(loc='upper left')
ax1.grid(True, alpha=0.3)

# 下图:带宽(波动率)
ax2.plot(df.index, df['bb_width'], color='#722ed1')
ax2.set_ylabel('带宽')
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

均值回归 vs 趋势跟踪

维度均值回归趋势跟踪(如双均线)
核心假设价格会回归均值趋势会持续
交易方向逆向交易(跌买涨卖)顺向交易(涨买跌卖)
适合市场震荡市、整理行情趋势市、单边行情
风险点趋势市可能持续亏损震荡市频繁假信号
持仓时间较短(几天到几周)较长(几周到几月)

两类策略各有适用场景,量化交易员通常会同时运行均值回归和趋势跟踪策略,形成策略组合。


下一步回测与风险管理 →