量化策略开发02:海龟三重EMA趋势策略 - 从设计思路到回测验证
本文是《量化策略开发》系列的第2篇。上一篇让AI全权做交易决策,这篇回到传统策略的设计基本功。从三重EMA排列为什么用三条不用两条,到严格入场和宽松入场到底差在哪,再到ATR动态止损止盈怎么设计,最后用7个品种的回测数据说话。看完你会理解,传统策略的设计思路一点都不"传统"。
写在前面
上一篇我们聊了AI全权做交易决策的完整链路——从提示词设计到决策执行。说实话,那套东西跑起来之后我挺兴奋的,AI确实能处理很多传统策略覆盖不了的场景。
但我们依然要回过头来研究:如何开发一个传统量化策略。
为什么?因为AI策略再花哨,它的判断基础还是技术指标。你得先理解这些指标组合在一起"为什么能赚钱",才能告诉AI什么是有价值的信号,什么是噪音。
这就好比做菜。AI是那个帮你看火候、调调料的助手,但如果你连"大火爆炒"和"小火慢炖"的区别都不知道,助手再聪明也帮不了你。
所以这篇文章,我想老老实实讲一个传统趋势策略的设计思路。不依赖AI,纯靠指标组合和规则逻辑。这个策略叫"海龟三重EMA趋势策略"——用三条EMA判断趋势方向,用ADX过滤假信号,用ATR动态设止损止盈。
这篇专注在策略的设计逻辑上——为什么这样设计,为什么不那样设计。
三重EMA排列:为什么是三条不是两条
先从单条EMA说起
EMA(指数移动平均线)大家都不陌生。它比SMA更重视最近的价格,反应更快。一条EMA能告诉你大方向——价格在EMA上方偏多,下方偏空。
但单条EMA的问题是:**太平滑了。**价格在EMA附近反复穿越,你不知道哪次是真的突破,哪次只是噪音。
两条EMA呢?经典的金叉死叉
双EMA交叉是最经典的趋势策略之一——快线上穿慢线做多(金叉),快线下穿慢线做空(死叉)。
效果有,但问题也很明显:**震荡市里反复打脸。**快线和慢线频繁交叉,每次交叉都触发一次交易,结果就是来回止损。
三条EMA的排列逻辑
加一条中线试试?
快线(EMA9)、中线(EMA20)、慢线(EMA60)。
多头趋势的判断条件变成了:快线 > 中线 > 慢线,三条线按顺序排列,像楼梯一样。
这跟双EMA有什么区别?区别在于——排列是一个状态,不是一次穿越。
金叉是一个"事件",发生在某根K线上,下一根K线可能就又叉回来了。但三线排列是一个"状态",要打破这个状态需要快线先穿过中线,这本身就比单次穿越更有韧性。
换句话说,三条EMA排列给了趋势一个"缓冲带"。快线可能短暂回落,但只要中线还在慢线上方,排列状态就没被破坏。
# 三重EMA排列判断(严格模式)long_alignment=(ema_fast>ema_midandema_mid>ema_slow)short_alignment=(ema_fast<ema_midandema_mid<ema_slow)不过,光排列还不够。还得加一个确认条件:收盘价必须站在快线的正确方向。
什么意思?做多的时候,不仅要三线多头排列,收盘价还得高于快线。这保证了价格确实在趋势方向上运行,而不是排列形成了但价格已经开始掉头。
# 完整做多条件:排列 + 收盘价确认long_condition=(ema_fast>ema_mid>ema_slow# 三线排列andclose>ema_fast# 收盘价在快线上方)这一层确认看起来简单,但在实战中能有效过滤掉很多假信号。
说到这里,有人会问:为什么不用MACD金叉做入场,非要用EMA排列?其实两个思路本质是一样的——都是用快慢线的相对位置判断趋势。但MACD看的是DIF和DEA两条衍生线的交叉,而EMA排列直接看价格和均线的关系。我个人觉得后者更直观,而且三线排列的"状态感"比MACD交叉的"事件感"更适合趋势跟踪。当然这只是我的偏好,不代表MACD不好。
不过话说回来,EMA排列只是第一步。接下来要解决的问题是:排列形成了,怎么入场?
多入场模式:严格、宽松和ADX过滤
策略设计到这一步,我遇到一个选择:入场条件到底该严格还是宽松?
严格条件信号少但准,宽松条件信号多但杂。两种各有道理,所以我干脆把两种都实现了,让策略自己选。
你可能会问:为什么不直接选一种?因为不同品种、不同行情阶段,适合的入场严格程度不一样。有些品种趋势性很强(比如棕榈油),严格模式就能抓住足够的信号;有些品种趋势比较弱(比如尿素),严格模式下几乎没信号,需要宽松模式才能捕捉到趋势早期的机会。把两种模式做成参数,回测的时候可以对比,看哪个品种更适合哪种。
严格模式
就是上面说的三线完全排列。三条线必须严格按顺序排列,一条都不能错位。
这种模式下,入场机会比较少。但每次入场,趋势确立的把握更大。为什么?因为三线完全排列意味着短、中、长三个时间维度的趋势方向完全一致——这不是"可能"在趋势里,而是"确定性很高"地在趋势里。代价是你会错过趋势早期的入场机会,等到三线排好队的时候,趋势可能已经走了一半。
宽松模式
放宽一点。不要求三条线完全排列,只要求快线在中线的正确方向上,同时慢线在上升(或下降)。
# 宽松模式:快线方向 + 慢线趋势long_condition=(ema_fast>ema_mid# 快线在中线上方andema_slow_rising# 慢线在上升(斜率确认)andclose>ema_fast# 收盘价确认)注意这里用了一个"慢线斜率"的概念。不要求慢线在中线的下方(三线排列),而是看慢线是不是在往上走。如果慢线在上升,说明长期趋势在转好,即使三线还没完全排列也可以考虑入场。
宽松模式的信号更多,能捕捉趋势早期的机会,但也更容易被假突破骗进去。这就是设计上的取舍——用信号质量换信号数量。在趋势明确的品种上不值得,但在趋势较弱的品种上,可能这是唯一能参与的方式。
ADX过滤:不管严格还是宽松,趋势得够强
不管是严格模式还是宽松模式,我都加了一层ADX过滤。
ADX(平均趋向指数)衡量的是趋势的强度,不区分方向。ADX越高,趋势越明确。默认阈值设为20-30之间(不同品种不一样),只有ADX高于阈值时才允许入场。
**为什么需要ADX?**因为EMA排列可能出现在两种场景:一种是真正的趋势行情,另一种是震荡市里EMA偶然排好队了。没有ADX过滤,后者会反复触发假信号。
# ADX趋势强度过滤ifadx_enabledandadx_value<adx_threshold:return# 趋势不够强,放弃这次入场机会三种机制组合起来——EMA排列看方向、收盘价确认看强度、ADX过滤看质量——构成了一个分层的入场信号体系。每一层都在过滤噪音,留下来的信号质量就相对高了。
等等,这里有个细节要注意。三种过滤不是独立的,而是叠加的。也就是说,ADX过滤在严格模式和宽松模式前面都会执行。所以实际的入场门槛是:先过ADX(趋势够不够强),再过EMA排列(方向对不对),最后收盘价确认(价格真的在动吗)。三道门都过了才入场。这就是为什么最后真正触发的信号不多,但每一个的可靠性都比较高。
止损止盈设计:让波动率来决定
入场说完了,接下来是出场。说实话,出场比入场重要得多。
ATR倍数 vs 固定百分比
止损止盈有两种主流做法:固定百分比和ATR倍数。
固定百分比就是"入场价上下2%止损、3%止盈"。简单直接,但问题是——不同品种的波动率差异很大。棕榈油日内波动可能就1%,铁矿日内波动可能3%。用同样的2%止损,对棕榈油来说可能太宽了,对铁矿来说可能太紧了。
ATR倍数解决了这个问题。ATR(真实波动幅度)衡量的是品种自身的波动水平。用ATR的倍数来设止损止盈,等于让止损距离自适应品种的波动特征。
ifsl_tp_mode=="atr"andatr_value>0:sl_dist=sl_atr_mult*atr_value# 止损距离 = 1.8倍ATRtp_dist=tp_atr_mult*atr_value# 止盈距离 = 3.3倍ATRelse:sl_dist=sl_pct/100*close# 备用:固定百分比tp_dist=tp_pct/100*close默认用的止损ATR倍数是1.8,止盈是3.3。止盈大约是止损的1.8倍,保证了盈亏比大于1。这个数字不是拍脑袋的——回测下来,1.5-2.0倍ATR的止损距离在大多数品种上效果最好,太小了容易被正常波动扫出去,太大了单笔亏损承受不了。
移动止损:利润跑了就别回头
还有一个可选功能:移动止损。入场之后,跟踪持仓期间的最高价(多头)或最低价(空头),止损线只往有利方向移动,不往回退。
# 移动止损:跟踪最高价,止损只上不下ifclose>highest_since_entry:highest_since_entry=close trail_stop=highest_since_entry*(1-trailing_pct/100)iftrail_stop>stop_loss_price:stop_loss_price=trail_stop这个功能适合趋势行情——价格不断新高,止损跟着上移,锁定已有利润。但在震荡市里容易过早被扫出去。所以默认是关闭的,只有趋势特别明确的品种才考虑开启。
EMA排列破坏出场
最后一个出场机制:如果持仓期间,快线下穿中线(多头)或上穿中线(空头),直接平仓。不管止损止盈有没有触发。
逻辑是:当初因为EMA排列入场,排列被破坏了,入场的理由就不存在了,该走就走。这个也是可选功能,默认关闭。
四种出场机制——固定止损、固定止盈、移动止损、EMA排列破坏——不是全都要用,而是根据品种特性灵活组合。
7个品种回测:用数据说话
策略设计得再漂亮,跑不出正收益都是白搭。
我在7个期货品种上做了回测,每个品种用优化后的参数,跨多个历史合约验证稳定性。说白了就是看看这个策略到底是"看着好听"还是"真的能用"。
回测参数
所有品种统一使用EMA 9/20/60,ADX周期14。不同的是止损止盈参数、ADX阈值和K线周期——这些是按品种特性分别调的。
回测结果
| 品种 | Sharpe | 平均收益率 | 胜率 | 盈利合约覆盖 | K线周期 |
|---|---|---|---|---|---|
| P 棕榈油 | 2.27 | 1.16% | 69.4% | 3/3 (100%) | 30分钟 |
| M 豆粕 | 1.04 | 0.12% | 60.6% | 8/8 (100%) | 30分钟 |
| L 塑料 | 0.97 | 0.30% | - | 8/8 (100%) | 15分钟 |
| I 铁矿 | 0.85 | 0.18% | - | 6/7 (86%) | 15分钟 |
| EB 苯乙烯 | 0.75 | 0.15% | - | 7/8 (88%) | 15分钟 |
| A 豆一 | 0.65 | 0.08% | - | 5/7 (71%) | 30分钟 |
| UR 尿素 | 0.55 | 0.05% | - | 5/7 (71%) | 15分钟 |
几个有意思的发现
棕榈油遥遥领先。Sharpe 2.27,胜率接近70%,合约覆盖率100%。棕榈油的趋势性比较强,波幅适中,三重EMA策略在这种品种上天然有优势。不过只有3个历史合约的数据,样本量偏小,这个结果还得继续观察。
看下棕榈油的回测K线图,三重EMA排列和入场信号一目了然:
棕榈油30分钟K线,EMA 9/20/60排列清晰,ADX阈值30,止损3%/止盈3%。多头排列形成后入场信号明确,假信号少。
豆粕很稳。Sharpe超过1,胜率60%以上,8个合约全部盈利。豆粕也是趋势性不错的品种,而且流动性好,滑点影响小。
塑料和铁矿居中。Sharpe在0.85-0.97之间,合约覆盖率也不错。铁矿的趋势性强但波动大,所以止损需要设得宽一点。
尿素垫底。Sharpe只有0.55,合约覆盖率71%。尿素这个品种波动规律性不太好把握,三重EMA这种趋势策略在它身上不太占优势。这其实也说明了一件事:没有万能策略,策略跟品种之间存在适配关系。
从周期来看也有规律:表现好的品种(P、M、A)适合30分钟周期,波动大的品种(L、I、EB、UR)适合15分钟周期。周期越短信号越灵敏,但也更容易被噪音干扰。
对了,有人可能会问:为什么EMA周期都是9/20/60,不按品种单独调?说实话,我一开始也想每个品种用不同的EMA周期。但回测下来发现,9/20/60这个组合在所有品种上都能用,差异主要在止损止盈和ADX阈值上。EMA周期的通用性比我想象的要好。可能是因为这三条线的作用是定方向(快中慢排列),而不是精确找入场点,所以对参数不像MACD那么敏感。
实战经验与避坑指南
说几个实际用的时候遇到的坑。
第一,ADX阈值不是越高越好。一开始我把ADX阈值设到了40,觉得趋势越强越好。结果发现信号少得可怜,好多明明不错的趋势行情因为ADX差一点就没入场。后来降到20-30之间,信号质量没降多少,但机会多了不少。不同品种的合适阈值也不一样——波动大的品种(铁矿)用20就够了,波动小的品种(棕榈油)可以设到30。
第二,止损止盈的比例比绝对值重要。回测下来,盈亏比(止盈距离/止损距离)控制在1.5-2.0之间效果最好。不是止盈越大越好——止盈设得太远,价格根本到不了,最后变成了"永远持仓"。
第三,多合约验证比单合约高分重要。一个合约上Sharpe到3.0不说明任何问题。8个历史合约中有7-8个盈利,才说明策略的稳定性不错。这也是为什么表格里列了"合约覆盖率"这一列。
就这几个。不多,但都是实打实踩过的坑。
写在最后
回到开头那个问题:为什么回到传统策略?
因为传统策略的设计过程本身,就是理解市场的过程。三重EMA为什么用三条、ADX为什么过滤、ATR为什么动态——每一个"为什么"背后都是对市场规律的认知。
AI策略可以帮你做决策,但它不能帮你建立这种认知。这种认知只能从"自己设计、自己验证、自己踩坑"的过程中长出来。
三重EMA策略的核心思路就一句话:**用多层过滤对抗噪音,用自适应参数对抗差异,用多合约验证对抗运气。**这不是什么高深的东西,但确实管用。
后面我会继续分享参数优化的方法论——7个品种的参数是怎么一步步调出来的,以及为什么同样的策略在不同品种上参数差异这么大。
先写到这,有问题欢迎留言交流。
本文基于ATMQuant量化交易系统,框架代码已开源至GitHub:https://github.com/seasonstar/atmquant
海龟三重EMA策略为付费会员专享,完整源码和参数配置教程已发布至知识星球「量策堂」。
本文内容仅供学习交流,不构成任何投资建议。交易有风险,投资需谨慎。
往期文章回顾
《量化策略开发》系列
- 量化策略开发01:我让AI全权做交易决策:从提示词设计到决策执行
《以AI量化为生》系列
- 以AI量化为生:24.回测结果存储与策略参数管理
- 以AI量化为生:23.打造AI全驱动量化策略引擎
- 以AI量化为生:22.指标计算引擎重构 - 让策略直接复用图表指标
- 以AI量化为生:21.交易图表AI分析功能集成
- 以AI量化为生:20.实时图表交易系统开发
- 以AI量化为生:19.半小时K线合成与多周期系统优化
《量化指标解码》系列
- 量化指标解码20:谐波形态识别 - 用斐波那契找到精准反转点
- 量化指标解码19:K线形态识别 - 价格行为不会说谎
- 量化指标解码18:SMC市场结构与流动性
- 量化指标解码17:SMC聪明钱概念之公允价值缺口
- 量化指标解码16:SMC聪明钱概念之订单块
- 量化指标解码15:Adaptive MACD Deluxe - 会自己调参的智能MACD
