主题切换
5.2 双均线策略模拟
概念详解
双均线策略(Dual Moving Average Crossover)是最经典的趋势跟踪策略之一,也是许多量化交易者入门的"Hello World"。其核心思想简洁而强大:用两条不同周期的移动平均线来捕捉趋势的形成与结束。
策略逻辑:
- 金叉(买入信号):短期均线从下方上穿长期均线,意味着短期动能强于长期趋势,趋势可能向上启动。
- 死叉(卖出信号):短期均线从上方下穿长期均线,意味着短期动能弱于长期趋势,趋势可能向下反转。
名词解释:移动平均线
过去N个周期收盘价的平均值连成的线,用于平滑价格波动、识别趋势。短期均线上穿长期均线为金叉(买入信号),下穿为死叉(卖出信号)。SMA(简单移动平均)每个价格等权重,EMA(指数移动平均)近期价格权重更大,EMA = Price_t × (2/(N+1)) + EMA_{t-1} × (1 - 2/(N+1))。
名词解释:移动平均线类型
- SMA(简单移动平均):
,每个价格等权,简单直观 - EMA(指数移动平均):
, ,近期价格权重更大,反应更快 - WMA(加权移动平均):近期价格赋更高权重,通常线性递减
- AMA(自适应移动平均):根据市场效率比动态调整平滑参数(Kaufman的AMA)
数学原理
SMA与EMA的计算
交叉信号的数学表达
设
交叉点条件:
为什么均线策略能赚钱?
均线策略本质上是在做时间序列动量。当趋势形成时,短期均线会持续位于长期均线的一侧,策略持续持有顺势仓位,赚取趋势行情的大段收益。在震荡市中,均线反复交叉会导致频繁假信号和亏损——这是趋势跟踪策略必须承受的"成本"。
📊 双均线交叉策略模拟
📊 双均线交叉策略模拟
Python实战
📌 案例:基础双均线回测
此处有展示代码展开 ▼
python
import pandas as pd
import numpy as np
def dual_ma_strategy(df, short_window=20, long_window=50):
"""
双均线策略回测
Parameters:
df: DataFrame with 'Close' column
short_window: 短期均线周期(默认20日)
long_window: 长期均线周期(默认50日)
Returns:
DataFrame with added columns: SMA_short, SMA_long, signal, position, returns
"""
data = df.copy()
# 计算均线
data['SMA_short'] = data['Close'].rolling(window=short_window).mean()
data['SMA_long'] = data['Close'].rolling(window=long_window).mean()
# 生成信号:短均线在长均线之上为1(看多),之下为0(看空/空仓)
data['signal'] = np.where(data['SMA_short'] > data['SMA_long'], 1, 0)
# 仓位:用信号的变化(交叉点)来触发交易
data['position'] = data['signal'].shift(1) # 下一期才执行
# 计算收益率
data['market_returns'] = data['Close'].pct_change()
data['strategy_returns'] = data['position'] * data['market_returns']
# 累积收益
data['cumulative_market'] = (1 + data['market_returns']).cumprod()
data['cumulative_strategy'] = (1 + data['strategy_returns']).cumprod()
return data点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `dual_ma_strategy`(双均线策略回测)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。
📌 案例:三均线增强策略
此处有展示代码展开 ▼
python
def triple_ma_strategy(df, short=10, mid=30, long=60):
"""
三均线策略:用三根均线的排列关系判断趋势强度
趋势排列:short > mid > long(强多头)
反趋势排列:short < mid < long(强空头)
纠缠状态:三线交叉混乱(不交易,过滤震荡)
"""
data = df.copy()
data['MA_s'] = data['Close'].rolling(short).mean()
data['MA_m'] = data['Close'].rolling(mid).mean()
data['MA_l'] = data['Close'].rolling(long).mean()
# 信号逻辑
data['trend_up'] = (data['MA_s'] > data['MA_m']) & (data['MA_m'] > data['MA_l'])
data['trend_down'] = (data['MA_s'] < data['MA_m']) & (data['MA_m'] < data['MA_l'])
# 仅在趋势明确时持仓
data['position'] = 0
data.loc[data['trend_up'].shift(1), 'position'] = 1
data.loc[data['trend_down'].shift(1), 'position'] = -1 # 允许做空
# 计算收益和换手率
data['returns'] = data['Close'].pct_change()
data['strategy_returns'] = data['position'] * data['returns']
# 统计持仓时间比例
in_market = (data['position'].abs() > 0).mean()
print(f"持仓时间比例: {in_market:.1%}")
return data点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `triple_ma_strategy`(三均线策略:用三根均线的排列关系判断趋势强度)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。
📌 案例:参数优化与敏感性分析
此处有展示代码展开 ▼
python
import itertools
def optimize_ma_params(df, short_range=range(5, 55, 5), long_range=range(30, 210, 10)):
"""
遍历参数空间,寻找最优的均线组合
同时输出参数稳定性分析
"""
results = []
for s, l in itertools.product(short_range, long_range):
if s >= l:
continue
result = dual_ma_strategy(df, short_window=s, long_window=l)
# 计算绩效指标
rets = result['strategy_returns'].dropna()
sharpe = rets.mean() / rets.std() * np.sqrt(252)
max_dd = (result['cumulative_strategy'].cummax() -
result['cumulative_strategy']).max()
results.append({
'short': s, 'long': l,
'sharpe': sharpe,
'max_dd': max_dd,
'total_return': result['cumulative_strategy'].iloc[-1] - 1
})
results_df = pd.DataFrame(results)
# 最优组合
best = results_df.loc[results_df['sharpe'].idxmax()]
print(f"最优参数: short={int(best['short'])}, long={int(best['long'])}")
print(f"最优夏普: {best['sharpe']:.2f}")
# 参数敏感性:夏普比率的热力图
pivot = results_df.pivot_table(
values='sharpe', index='short', columns='long'
)
return results_df, pivot点击展开可浏览运行结果
📘 本段代码定义了 1 个函数/类:函数 `optimize_ma_params`(遍历参数空间,寻找最优的均线组合)。该片段为教学展示(未包含独立运行的输入数据),可在实战练习中结合真实数据调用。
常见误区
金叉/死叉信号有延迟:均线交叉信号本质上是滞后指标——当金叉发生时,涨幅已经走了一部分;当死叉发生时,跌幅也已经发生。均线策略靠的是捕捉趋势的"中段",而不是精确的转折点。
震荡市中过度交易:在横盘震荡行情中,均线频繁交叉,策略会反复进出产生大量无效交易。解决办法是引入趋势过滤器(如ADX > 25 才允许交易),或者使用三均线策略过滤震荡。
参数选择过于任意:经典的20/50/200日均线组合来自于市场惯例而非统计优化。不同市场、不同品种的最优参数差异很大,需要进行系统的参数敏感性分析。
忽略风险管理和头寸规模:双均线策略本身只产生方向信号,不考虑仓位多少。需要配合风险管理和资金管理模块:单次止损幅度、仓位大小、加仓规则等。
过分追求参数最优:对参数做穷举搜索找到的"最优"组合很可能过拟合了历史数据。应该关注的是参数空间中稳定盈利的区域,而非单一最优点。
实战练习
在你的数据集中实现双均线策略,对比:
- SMA vs EMA 的收益差异
- 不同参数组合(如10/30, 20/60, 50/200)在不同市场环境(牛市/熊市/震荡)中的表现
- 加入和去掉趋势过滤器(ADX)后的效果
参数稳定性分析:对短期/长期均线的参数空间(如5到100日,5日步长)计算每个组合的夏普比率,绘制热力图。观察是否存在稳定的盈利区域,还是只有零星的"幸运点"。
将策略应用到不同的品种(股票指数、商品期货、外汇),观察策略在不同资产类别上的表现差异。为什么均线策略在某些品种上表现更好?
延伸阅读
- Pring, M. J. (2002). Technical Analysis Explained. McGraw-Hill. 技术分析的经典教材。
- Kaufman, P. J. (2013). Trading Systems and Methods. Wiley. 第5版,系统讨论了各种均线变体和自适应方法。
- Brock, W., Lakonishok, J., & LeBaron, B. (1992). "Simple Technical Trading Rules and the Stochastic Properties of Stock Returns." Journal of Finance. 证明简单均线策略具有统计显著性的学术论文。
- Moskowitz, T. J., Ooi, Y. H., & Pedersen, L. H. (2012). "Time Series Momentum." Journal of Financial Economics. 深入分析趋势跟踪策略的全球表现。
本章要点
- 双均线策略是最经典的趋势跟踪方法,核心信号是金叉买入、死叉卖出。
- 均线有SMA(等权)、EMA(近期加权)、WMA、AMA等多种变体,EMA比SMA反应更快但噪声更多。
- 均线交叉信号的数学本质是时间序列动量——在趋势市场中持续持仓,在震荡市场中频繁止损。
- 三均线策略通过排列关系过滤震荡市场,减少假信号:只有在均线有序排列(多头排列或空头排列)时才持仓。
- 参数优化需要关注参数稳定性——盈利的参数区域是否宽广,而非单一最优点的盈利高度。
- 趋势跟踪策略的表现具有明显的周期性:在趋势行情中表现出色,在长期震荡中持续磨损——这是策略特征,不是策略失败。