均值回归策略
均值回归策略假设价格会围绕其均值波动,当价格偏离均值过大时会向均值回归。
什么是均值回归?
金融资产的价格长期来看会围绕某个均值上下波动:
- 价格远低于均值 → 超卖 → 价格有上涨回归的动力
- 价格远高于均值 → 超买 → 价格有下跌回归的压力
均值回归策略就是在价格偏离均值时逆向交易,捕捉回归过程中的利润。
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 趋势跟踪
| 维度 | 均值回归 | 趋势跟踪(如双均线) |
|---|---|---|
| 核心假设 | 价格会回归均值 | 趋势会持续 |
| 交易方向 | 逆向交易(跌买涨卖) | 顺向交易(涨买跌卖) |
| 适合市场 | 震荡市、整理行情 | 趋势市、单边行情 |
| 风险点 | 趋势市可能持续亏损 | 震荡市频繁假信号 |
| 持仓时间 | 较短(几天到几周) | 较长(几周到几月) |
两类策略各有适用场景,量化交易员通常会同时运行均值回归和趋势跟踪策略,形成策略组合。
下一步:回测与风险管理 →