均线交叉:从金叉死叉到 Hull 均线的 69 副面孔¶
量化策略图鉴 · 第 01 篇 · 分类
trend_following(均线交叉子族约 69 个策略)· 2026-09-02
如果量化策略有一部族谱,第一页一定写着移动平均线交叉。它是绝大多数人接触的第一种"技术分析":快线上穿慢线买入,下穿卖出。正因为太简单,它也是最容易被低估的策略族——在本仓库 trend_following 分类约 340 个策略里,均线交叉及其近亲占了约 69 席,是这个分类中最大的子族。
一个反直觉的事实:在黄金 2008-2025 这轮大牛市上,最朴素的 50/200 金叉系统 18 年只做了 13 笔交易,胜率不到 31%,却把 100 万做到 357 万。胜率和收益无关,这是趋势跟踪的第一课。
本篇解读这个子族的代表成员:金叉/死叉的统计学含义、价格穿越与均线交叉两种范式之争、以及 SMA/EMA/HMA 这一族"低延迟均线"的演化。
分类速览¶
策略 |
数据 |
核心思想 |
源码 |
|---|---|---|---|
SMA 趋势跟随 |
XAUUSD 日线 2008-2025 |
收盘价站上 200SMA 持多,跌回空仓 |
|
金叉策略 |
XAUUSD 日线 2008-2025 |
50SMA 上穿 200SMA 入场,死叉离场 |
|
死叉反向 |
XAUUSD 日线 2008-2025 |
死叉抄底博超卖反弹,金叉离场 |
|
双均线交叉 EA |
XAUUSD M15 |
2/5 SMA 之差突破 45 点死区才入场 |
|
YY Cross 2MA |
XAUUSD M15 |
72/150 双均线交叉反手 + 300 点止盈 |
|
通用 MACross EA |
XAUUSD M15 |
可配置周期/反转/风险管理的交叉模板 |
|
Sunrise EMA |
ORCL 日线 2010-2014 |
EMA14/24 交叉 + 四阶段回调确认状态机 |
|
HMA 交叉 |
ORCL 日线 2010-2014 |
Hull 均线 60/90 交叉,低延迟多空反手 |
|
DEMA 交叉 |
ORCL 日线 |
双重 EMA 去滞后,减少交叉迟滞 |
|
EMA+LWMA+RSI |
XAUUSD M15 |
线性加权均线交叉 + RSI 过滤 |
|
Two iMA Cross |
XAUUSD M15 |
MT5 iMA 双线交叉的最小实现 |
|
20/200 Ants |
XAUUSD M15 |
机构级 20/200 均线组合的多空版本 |
|
深读一:金叉策略——18 年 13 笔交易的耐心¶
金叉的统计学本质是双样本均值的穿越检验:50 日均值是近期价格的样本均值,200 日均值是长期均值的代理,快线上穿慢线,等价于"近端动量显著高于长期基准"的一次朴素检验。信号稀疏、滞后、但噪音极低。
仓库实现(test_0175_golden_cross.py)在 pandas 侧预计算信号,策略侧只做下单:
out['ma_fast'] = out['close'].rolling(window=fast_period).mean() # fast=50
out['ma_slow'] = out['close'].rolling(window=slow_period).mean() # slow=200
out['golden_cross'] = ((out['ma_fast'].shift(1) <= out['ma_slow'].shift(1)) &
(out['ma_fast'] > out['ma_slow'])).astype(float)
out['death_cross'] = ((out['ma_fast'].shift(1) >= out['ma_slow'].shift(1)) &
(out['ma_fast'] < out['ma_slow'])).astype(float)
def next(self):
golden_cross = float(self.data.golden_cross[0]) > 0.5
death_cross = float(self.data.death_cross[0]) > 0.5
if not self.position:
if golden_cross:
self.pending_order = self.buy(size=self._get_position_size(
target_notional_pct=float(self.p.lot_size)))
return
if death_cross:
self.pending_order = self.close()
注意 shift(1):交叉的"前一根"必须严格用前一根的均线值比较,防止信号在当根被"事后修正"。
钉死的基线。XAUUSD 日线 2008-2025、初始 100 万、0.02% 佣金:13 笔交易,4 胜 8 负(1 笔未平),胜率 30.77%,终值 3,571,828.03(+257.18%),盈利因子 2.04,最大回撤 37.54%。测试用 abs(final_value - 3571828.03) < 3.6 级别的容差把每个数字钉进断言——31% 的胜率靠盈亏比 2:1 赚钱,这就是趋势跟踪"截断亏损、让利润奔跑"的活样本。
深读二:SMA 趋势跟随——同一根均线,另一种用法¶
同一个目录里藏着最好的对照组(test_0001_sma_trend_following.py):同样 200 日 SMA、同一份数据,但不等交叉,价格本身站上均线就持有,跌回就空仓:
out['sma'] = out['close'].rolling(sma_period).mean() # sma_period=200
out['trend_signal'] = (out['close'] > out['sma']).astype(float)
def next(self):
trend_signal = float(self.data.trend_signal[0])
if self.position:
if trend_signal < 0.5:
self.pending_order = self.close()
else:
if trend_signal > 0.5:
self.pending_order = self.buy(size=self._get_position_size(
target_notional_pct=float(self.p.lot_size)))
结果对比很有意思:价格穿越版交易 65 笔(11 胜 53 负,胜率 16.92%),终值 3,686,124.79(+268.61%),最大回撤 32.83%。收益略胜金叉版,但交易次数是 5 倍。价格穿越信号更灵敏、进出场更早;均线交叉信号更钝、换手更低。同一根 200 均线,机构用它当"牛熊分界线"(价格在上下决定风险敞口),散户用它找交叉点——两种范式在这里各回各位。顺带一提,隔壁的死叉反向策略(test_0174_death_cross_reverse.py)专做"死叉后博反弹":12 笔、9 胜 3 负(75% 胜率)、+28.41%——同一个信号,趋势用法和反转用法都能自洽。
深读三:双均线交叉 EA——45 点死区救不了 M15¶
把镜头切到分钟级,画风突变。test_0051_0631_doublema_crossover.py 是 MT5 移植的双均线 EA:2/5 超短周期 SMA,但加了一个工程上很聪明的死区(dead band)——两线之差必须超过 breakout_level 个点才认信号,拒绝在均线粘合处反复开仓:
sc = int(self.p.signal_candle) # signal_candle=1:只用已收 K 线
fma = float(self.ma_fast[-sc])
sma = float(self.ma_slow[-sc])
breakout = float(self.p.breakout_level) * self._point() # 45 × 0.01 = 0.45 美元
price = float(self.data.close[0])
if fma - sma > breakout:
self._set_risk('buy', price) # 止损 25 点,固定手数 0.1 手
self.order = self.buy(size=self.p.lots)
elif sma - fma > breakout:
self._set_risk('sell', price)
self.order = self.sell(size=self.p.lots)
结果依旧诚实:3 个月 XAUUSD M15 上 2,678 笔交易,胜率 47.31%,终值 997,462.90(-0.25%)。2/5 均线在 M15 上接近随机游走的噪音探测器,45 点死区已经是很努力的过滤,仍然填不平磨损。这组数字的价值在于划出边界:均线周期越短、周期越贴近噪音尺度,交叉系统越接近抛硬币——它是你优化参数时的"下限对照组"。
其余策略,快速点将¶
HMA 交叉(
test_87):Hull 均线用 WMA(2·WMA(n/2)−WMA(n)) 的组合把滞后压到最低,60/90 双 HMA 在 ORCL 上终值 100,081.45——均线族谱里"降延迟"路线的代表,和 DEMA(test_98)互为参照。Sunrise EMA(
test_86):交叉只当"预选",还要经过回调确认、窗口打开、突破监控四阶段状态机——把一次交叉拆成一次完整入场流程的教科书。YY Cross 2MA(
test_0014):72/150 慢交叉反手 + 300 点止盈,MT4 时代论坛流传的经典参数。通用 MACross EA(
test_0033):周期、反转开关、止损止盈、追踪止损全部参数化的交叉模板,适合当自己的第一个改造对象。20/200 Ants(
test_0244):20/200 这对"机构参数"的 M15 多空版,本子族里被复用最多的参数组合。
一条命令跑起来¶
# 整个 trend_following 分类(300+ 个策略,runonce/runnext 双模式自动对拍)
pytest tests/functional/strategies/trend_following/ -v
# 只跑金叉策略
pytest tests/functional/strategies/trend_following/test_0175_golden_cross.py -v
每个测试都在向量化(runonce=True)与事件驱动(runonce=False)两种引擎下各跑一遍并比对指标——你在改均线周期做实验之前,先确认引擎本身没有数值漂移。
为什么在这个项目上研究均线交叉¶
均线交叉是参数实验最密集的策略族:周期组合、均线类型、死区宽度、信号 K 线偏移,每个旋钮都值得一轮扫描。这正是 cloudQuant/backtrader 的用武之地:纯 Python 引擎比原版快 46%,1,152 个策略回归测试几分钟跑完;装上 C++ 后端(pip install back-trader-cpp)可获得中位 128 倍加速,69 个均线变体的网格搜索从"过夜任务"变成"喝口咖啡"。而每个策略钉死的指标断言基线,保证你比较的是策略优劣,而不是引擎实现的偏差。
觉得有用,去 GitHub 给个 Star;想系统学习,从系列总览开始。
风险提示:本篇仅供教育与研究目的。以上回测均基于历史数据,不构成投资建议;算法交易存在重大亏损风险。