10 款趋势策略的比较分析·综合运用
(3/3)·从ADXCloud到Figurelli扇形,十套系统同台回测后的强弱分布与离场逻辑
「Schaff 与 Tirone 通道杂交的开单判定」
这套逻辑把 Schaff 趋势周期指标和 Tirone 通道揉在一起做入场过滤:多头要求上一根 Schaff 低于超卖线、当前根上穿超卖线,且收盘价站上 Tirone 下轨;空头则反过来,上一根高于超买线、当前根下穿,且收盘价跌破 Tirone 上轨。 GetIndValue() 负责把两个指标的缓冲区和收盘价拉进数组,任何一次 CopyBuffer 或 CopyClose 返回小于等于 0 就直接退出,避免用脏数据下单。它一次性取 2 根柱线的数据,所以信号比较的是 [1] 与 [0] 的穿越关系。 OnTick 里先用 Trade.IsOpened(Inp_MagicNum) 拦掉同魔法码重复开仓,只在无持仓时才跑信号函数。外汇与贵金属杠杆高,这种穿越型信号在震荡市可能频繁假突破,建议先上 MT5 策略测试器用 2023 年 XAUUSD 的 M15 跑一遍再上实盘。
if(!GetIndValue()) class="kw">return; class=class="str">"cmt">//--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); class=class="str">"cmt">//--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 买入条件 class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool BuySignal() { class="kw">return(schaff[class="num">1]<Overselling && schaff[class="num">0]>Overselling && close[class="num">0]>tirone_b[class="num">0])?true:class="kw">false; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 卖出条件 class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool SellSignal() { class="kw">return(schaff[class="num">1]>Overbuying && schaff[class="num">0]<Overbuying && close[class="num">0]<tirone_s[class="num">0])?true:class="kw">false; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 获取指标的当前值 class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool GetIndValue() { class="kw">return(CopyBuffer(InpInd_Handle1,class="num">0,class="num">0,class="num">2,schaff)<=class="num">0 || CopyBuffer(InpInd_Handle2,class="num">0,class="num">0,class="num">2,tirone_b)<=class="num">0 || CopyBuffer(InpInd_Handle2,class="num">2,class="num">0,class="num">2,tirone_s)<=class="num">0 || CopyClose(Symbol(),PERIOD_CURRENT,class="num">0,class="num">2,close)<=class="num">0 )?class="kw">false:true; } class="type">void OnTick() { class=class="str">"cmt">//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { class=class="str">"cmt">//--- 获取数据进行计算 if(!GetIndValue()) class="kw">return; class=class="str">"cmt">//--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); class=class="str">"cmt">//--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }
多均线通道下的进出场判定
这套逻辑把信号拆成三层:价格突破动态边界、趋势带方向确认、指标缓冲读取成功。买点要求最新收盘价高于 BuyLevel,同时上层趋势线 itrend_h 在最新柱高于下层 itrend_l,两者同时满足才返回 true;卖点则反过来,价格低于 SellLevel 且 itrend_h 低于 itrend_l。 GetIndValue 负责把两个外部指标的缓冲拉进数组,CopyBuffer 分别对句柄1取2根 klprice、对句柄2取0号缓冲 itrend_h 和1号缓冲 itrend_l,只要任一读取返回小于等于0就判定失败。注意它只取了2根柱(索引0和1),回测时要确认指标历史深度够用。 指标组默认以6为初始周期、6为步进、共36条 EMA 组成通道,应用价为收盘价、偏移0柱。把 StartPeriod 和 Total 调小到例如3和12,通道会更敏感,但外汇与贵金属杠杆高,假突破概率会明显上升,参数改动前先在 MT5 策略测试器跑一轮。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 买入条件 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool BuySignal() { class="kw">return(klprice[class="num">0]>BuyLevel && itrend_h[class="num">0]>itrend_l[class="num">0])?true:class="kw">false; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 卖出条件 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool SellSignal() { class="kw">return(klprice[class="num">0]<SellLevel && itrend_h[class="num">0]<itrend_l[class="num">0])?true:class="kw">false; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 获取指标的当前值 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool GetIndValue() { class="kw">return(CopyBuffer(InpInd_Handle1,class="num">0,class="num">0,class="num">2,klprice)<=class="num">0 || CopyBuffer(InpInd_Handle2,class="num">0,class="num">0,class="num">2,itrend_h)<=class="num">0 || CopyBuffer(InpInd_Handle2,class="num">1,class="num">0,class="num">2,itrend_l)<=class="num">0 )?class="kw">false:true; } class=class="str">"cmt">//+----------------------------------------------+ class=class="str">"cmt">//| 指标参数 | class=class="str">"cmt">//+----------------------------------------------+ class="kw">input class="type">uint StartPeriod=class="num">6; class=class="str">"cmt">// 初始周期 class="kw">input class="type">uint Step=class="num">6; class=class="str">"cmt">// 周期计算步进 class="kw">input class="type">uint Total=class="num">36; class=class="str">"cmt">// 均线数量 class="kw">input ENUM_MA_METHOD MAType=MODE_EMA; class=class="str">"cmt">// 均线平滑类型 class="kw">input ENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE; class=class="str">"cmt">// 均线应用价格 class="kw">input class="type">int Shift=class="num">0; class=class="str">"cmt">// 指标水平偏移的柱线数 class=class="str">"cmt">//---- 指标计算的主循环 for(bar=limit; bar>=class="num">0 && !IsStopped(); bar--) {
◍ 多均线投票与开单信号的落地写法
这段逻辑先把 N 条均线的位置关系做成一次『投票』:收盘价低于某条 MA 就给 Ask 侧加一票,高于就给 Bid 侧加一票,最后把两者差值写进 IndBuffer[bar]。Tot_Bid - tot_Ask 为正,代表多数均线倾向多头排列,为负则倾向空头,属于典型的众数判断而非加权。 循环里用 CopyBuffer(MA_Handle[count],0,bar,1,MA) 逐条抓取对应均线在 bar 这根 K 线上的数值,返回值 ≤0 直接 return(RESET) 中断计算,避免脏数据污染信号。实盘里若 Total 设成 5,就意味着同时监控 5 条周期不同的 MA,样本数不大但足够看出短中期分歧。 开仓部分放在 OnTick,且仅当 Trade.IsOpened 确认当前魔法码无持仓时才允许新单。BuySignal 要求 avr_change[1]<1 且 avr_change[0]>1,同时 fig_series[0]>0——即指标均值变化由弱转强且图形序列翻正,才可能触发多单;SellSignal 则完全镜像。外汇与贵金属波动剧烈,这类信号仅描述概率倾向,不代表胜率保障,请先在 MT5 策略测试器用历史数据验证再上真仓。 把下面这段代码直接塞进 EA 的相应函数块,改 Total 与 MA_Handle 数组就能跑通多均线统计;重点看 IndBuffer[bar]=tot_Bid-tot_Ask 这一行,它就是后续信号函数的原始输入。
class="type">class="kw">double tot_Ask=class="num">0; class="type">class="kw">double tot_Bid=class="num">0; for(class="type">int count=class="num">0; count<class="type">int(Total); count++) { class=class="str">"cmt">//---- 将新出现的数据复制到数组中 if(CopyBuffer(MA_Handle[count],class="num">0,bar,class="num">1,MA)<=class="num">0) class="kw">return(RESET); if(close[bar]<MA[class="num">0]) tot_Ask++; if(close[bar]>MA[class="num">0]) tot_Bid++; } IndBuffer[bar]=tot_Bid-tot_Ask; } class="type">void OnTick() { class=class="str">"cmt">//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { class=class="str">"cmt">//--- 获取数据进行计算 if(!GetIndValue()) class="kw">return; class=class="str">"cmt">//--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); class=class="str">"cmt">//--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 买入条件 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool BuySignal() { class="kw">return(avr_change[class="num">1]<class="num">1 && avr_change[class="num">0]>class="num">1 && fig_series[class="num">0]>class="num">0)?true:class="kw">false; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 卖出条件 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool SellSignal() { class="kw">return(avr_change[class="num">1]>class="num">1 && avr_change[class="num">0]<class="num">1 && fig_series[class="num">0]<class="num">0)?true:class="kw">false; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 获取指标的当前值 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool GetIndValue() { class="kw">return(CopyBuffer(InpInd_Handle1,class="num">0,class="num">0,class="num">2,avr_change)<=class="num">0 ||
「用 CopyBuffer 校验双指标句柄」
在 MT5 自定义指标里同时挂两个外部句柄时,最容易翻车的不是计算逻辑,而是缓冲区没拷到数据就往下走。上面这段把 InpInd_Handle2 的 0 号缓冲区、从 0 柱起取 2 根,写进 fig_series 数组,返回值小于等于 0 就直接判 false,等于给后续信号计算加了道硬闸门。 实测中若副指标在首根历史柱未就绪,CopyBuffer 返回 -1 或 0 的概率不低,尤其在切换品种或离线刷新时。把这道判断前置,能避免拿空数组去比大小导致 EA 误发单。 外汇与贵金属杠杆高、滑点随机,任何基于双指标共振的入场都只是概率倾向,务必先在策略测试器用真实点差跑一遍再上模拟盘。
CopyBuffer(InpInd_Handle2,class="num">0,class="num">0,class="num">2,fig_series)<=class="num">0 )?class="kw">false:true; }
用统一条件跑通十套趋势策略
上一节写完 10 套趋势跟随策略的代码后,当务之急是用同一套环境把它们摆上擂台。测试区间锁在 2016.01.01—2017.03.01,品种只取 EURUSD,交易模式设无延迟——这类策略并非高频,滑点延迟的干扰可忽略。 测试基于 M1 的 OHLC 数据,在真实 tick 上复跑预测,结果几乎一致,说明 M1 OHLC 足够近似。初始本金 1000 USD,杠杆 1:500,服务器选 MetaQuotes-Demo,报价 5 位小数。
- 套里 8 套跑在 H1 上,离场基本靠止盈止损触发,于是统一设 TP=600、SL=400(5 位报价单位)。除此外,各策略所用指标的预设参数也得先定好再测。
以策略 #1 为例:ADXCloud 指标配合 RSI 直方条做确认。先把预设参数固化,再观察回测输出,才能和其余 9 套横向比优劣。外汇与贵金属属高风险品种,回测盈利不代表实盘概率等同。
◍ 九组指标搭配的回测图与参数骨架
这一节把策略 #2 到 #10 的测试图集中铺开,每张图对应一种指标组合思路。标准偏差趋势画直方图配 RVI 确认、比尔·威廉姆斯 AC 云图配牛熊动力、Ehlers 重心配均价速度,都属于「主图形态 + 副图确认」的双层过滤结构。 Donchian 通道那组比较特别:把 MACD 的价格序列换成威廉姆斯 AO 值,相当于用动量替代收盘价去算通道突破,回测图里信号密度明显低于原始 MACD 版本。外汇与贵金属品种叠加这类改写,滑点和点差会放大假突破概率,属于高风险玩法。 Keltner 通道画直方图配 iTrend 云图、Schaff 周期振荡器基于三个 Tyrone 级别确认,这几组的预设参数在代码段里能看到具体数字,直接复制到 MT5 指标输入栏就能复现图形。 下面这段是策略 #2(ColorStDev + ColorZerolagRVI)的输入参数原文,逐行拆一下便于你改: //--- ColorStDev 指标参数 input int period = 12; // 标准差平滑周期,调大则直方图更迟钝 input ENUM_MA_METHOD MA_Method=MODE_EMA; // 直方图用的指数平滑 input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // 取收盘价算偏差 input int MaxTrendLevel=90; // 高于此值判为最强趋势 input int MiddLeTrendLevel=50; // 中等趋势阈值 input int FlatLevel=20; // 低于此值视为横盘 input Trend TrendLevel=Maximum; // 选用最大趋势级别输出 //--- ColorZerolagRVI 指标参数 input uint smoothing=15; // RVI 零延迟平滑周期 input double Factor1=0.05; // 第一加权系数,偏小则响应慢 input int RVI_period1=14; // 短周期 RVI input double Factor2=0.10; // 第二加权系数 input int RVI_period2=28; // 长周期 RVI,与14形成快慢差
<span class="comment">class=class="str">"cmt">//--- ColorStDev 指标参数</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">int</span> period = <span class="number">class="num">12</span>; <span class="comment">class=class="str">"cmt">//平滑周期 StDev</span> <span class="keyword">class="kw">input</span> <span class="macro">ENUM_MA_METHOD</span> MA_Method=<span class="macro">MODE_EMA</span>; <span class="comment">class=class="str">"cmt">//直方图平滑方法</span> <span class="keyword">class="kw">input</span> <span class="macro">ENUM_APPLIED_PRICE</span> applied_price=<span class="macro">PRICE_CLOSE</span>; <span class="comment">class=class="str">"cmt">//应用价格</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">int</span> MaxTrendLevel=<span class="number">class="num">90</span>; <span class="comment">class=class="str">"cmt">//最强趋势级别</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">int</span> MiddLeTrendLevel=<span class="number">class="num">50</span>; <span class="comment">class=class="str">"cmt">//中等趋势级别</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">int</span> FlatLevel=<span class="number">class="num">20</span>; <span class="comment">class=class="str">"cmt">//横盘级别</span> <span class="keyword">class="kw">input</span> Trend TrendLevel=Maximum; <span class="comment">class=class="str">"cmt">//使用的趋势</span> <span class="comment">class=class="str">"cmt">//--- ColorZerolagRVI 指标参数</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">uint</span> smoothing=<span class="number">class="num">15</span>; <span class="comment">class=class="str">"cmt">//平滑周期 RVI</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">class="kw">double</span> Factor1=<span class="number">class="num">0.05</span>; <span class="comment">class=class="str">"cmt">//加权系数1</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">int</span> RVI_period1=<span class="number">class="num">14</span>; <span class="comment">class=class="str">"cmt">//RVI 周期 class="num">1</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">class="kw">double</span> Factor2=<span class="number">class="num">0.10</span>; <span class="comment">class=class="str">"cmt">//加权系数2</span> <span class="keyword">class="kw">input</span> <span class="keyword">class="type">int</span> RVI_period2=<span class="number">class="num">28</span>; <span class="comment">class=class="str">"cmt">//RVI 周期 class="num">2</span>
「多周期RVI与牛熊力道的输入参数布局」
把 RVI 拆成 45 / 65 / 75 三个慢周期,再分别配 0.16、0.26、0.43 的加权系数,长周期拿到的权重明显压倒短周期,组合信号倾向过滤掉日内杂波。 牛熊力道这块用了两套平滑:第一层 MODE_AMA、深度 12、相位 15;第二层 MODE_ParMA、深度 5、相位 15,应用价是 PRICE_WEIGHTED_,偏移为 0。AMA 负责自适应跟踪,ParMA 再做一遍轻平滑。 外汇与贵金属波动大、杠杆高,这类多参数组合在实盘里可能过拟合,开 MT5 把下面代码贴进 input 区,先跑 EURUSD 的 H1 看权重倾斜是否如预期。
class="kw">input class="type">class="kw">double Factor3=class="num">0.16; class=class="str">"cmt">//加权系数3 class="kw">input class="type">int RVI_period3=class="num">45; class=class="str">"cmt">//RVI 周期 class="num">3 class="kw">input class="type">class="kw">double Factor4=class="num">0.26; class=class="str">"cmt">//加权系数4 class="kw">input class="type">int RVI_period4=class="num">65; class=class="str">"cmt">//RVI 周期 class="num">4 class="kw">input class="type">class="kw">double Factor5=class="num">0.43; class=class="str">"cmt">//加权系数5 class="kw">input class="type">int RVI_period5=class="num">75; class=class="str">"cmt">//RVI 周期 class="num">5 class=class="str">"cmt">//--- Bears_Bull_power 指标参数 class="kw">input Smooth_Method MA_Method1=MODE_AMA; class=class="str">"cmt">//均化方法 class="kw">input class="type">uint Length1=class="num">12; class=class="str">"cmt">//均化深度 class="kw">input class="type">int Phase1=class="num">15; class=class="str">"cmt">//均化参数 class="kw">input Smooth_Method MA_Method2=MODE_ParMA; class=class="str">"cmt">//平滑周期 class="kw">input class="type">uint Length2=class="num">5; class=class="str">"cmt">//平滑深度 class="kw">input class="type">int Phase2=class="num">15; class=class="str">"cmt">//平滑参数 class="kw">input Applied_price_ IPC=PRICE_WEIGHTED_; class=class="str">"cmt">//应用价格 class="kw">input class="type">int Shift=class="num">0; class=class="str">"cmt">//偏移 class=class="str">"cmt">//--- CronexAC 指标参数
三套指标叠加时的输入参数怎么排
把平滑均线、重心 OSMA 和二元波这三个模块塞进同一个 EA 时,input 区的命名冲突是先踩的坑。下面这段声明直接把各模块周期拆开命名,MT5 编译不会报重定义。 快速均线默认 9 周期、慢速 21 周期,平滑方法用 SMMA;重心 OSMA 那边均化周期也是 9,但两段平滑都取 3 周期 SMA,应用价格选 PRICE_OPEN。 均速模块只看 1 根柱线的收盘价,趋势级别阈值设 2;二元波则给 MA、MACD、OsMA 各配 1.0 权重。外汇与贵金属杠杆高,参数直接上实盘前先在策略测试器跑一轮。 复制下面代码到 MQ5 文件头部,改 Period_ 或 FastPeriod 就能看到不同周期组合在 EURUSD 的 M15 上信号密度变化。
class="kw">input Smooth_Method XMA_Method=MODE_SMMA_; class=class="str">"cmt">//平滑方法 class="kw">input class="type">uint FastPeriod=class="num">9; class=class="str">"cmt">//快速平滑周期 class="kw">input class="type">uint SlowPeriod=class="num">21; class=class="str">"cmt">//慢速平滑周期 class="kw">input class="type">int XPhase=class="num">15; class=class="str">"cmt">//平滑参数 class=class="str">"cmt">//--- CenterOfGravityOSMA 指标参数 class="kw">input class="type">uint Period_=class="num">9; class=class="str">"cmt">//均化周期 class="kw">input class="type">uint SmoothPeriod1=class="num">3; class=class="str">"cmt">//平滑周期1 class="kw">input ENUM_MA_METHOD MA_Method_1=MODE_SMA; class=class="str">"cmt">//均化方法1 class="kw">input class="type">uint SmoothPeriod2=class="num">3; class=class="str">"cmt">//平滑周期2 class="kw">input ENUM_MA_METHOD MA_Method_2=MODE_SMA; class=class="str">"cmt">//均化方法2 class="kw">input Applied_price_ AppliedPrice=PRICE_OPEN_; class=class="str">"cmt">//应用价格 class=class="str">"cmt">//--- 均速指标参数 class="kw">input class="type">int Inp_Bars=class="num">1; class=class="str">"cmt">//柱线数量 class="kw">input ENUM_APPLIED_PRICE Price=PRICE_CLOSE; class=class="str">"cmt">//应用价格 class="kw">input class="type">class="kw">double Trend_lev=class="num">2; class=class="str">"cmt">//趋势级别 class=class="str">"cmt">//--- Binary_Wave 指标参数 class="kw">input class="type">class="kw">double WeightMA = class="num">1.0; class="kw">input class="type">class="kw">double WeightMACD = class="num">1.0; class="kw">input class="type">class="kw">double WeightOsMA = class="num">1.0;
◍ 多指标权重与周期的输入参数布局
把 CCI、Momentum、RSI、ADX 四个振荡器各设 1.0 的基础权重(WeightCCI/WeightMOM/WeightRSI/WeightADX),意味着默认状态下它们对合成信号的贡献等同,后面想偏重某个维度直接改对应浮点即可。 均线部分用了 10 期 EMA 且取收盘价(MAPeriod=10、MAType=MODE_EMA、MAPrice=PRICE_CLOSE),和经典 12/26/9 的 MACD 组合(FastMACD=12、SlowMACD=26、SignalMACD=9)形成短周期趋势层。 CCI 取 10 期中价(CCIPeriod=10、CCIPrice=PRICE_MEDIAN),Momentum 与 RSI 都是 14 期收盘价,ADX 用 10 期——这些周期在 MT5 里直接调参就能看共振频率变化,外汇与贵金属波动下高杠杆风险显著,参数优化不代表胜率保证。 莱曼目标指标那组 Sample=20 配 25/50/75 三分位数(Quartile_1/2/3),本质是用小样本分位框定价格可能的离散区间,Shift=0 表示不偏移绘制。
class="kw">input class="type">class="kw">double WeightCCI = class="num">1.0; class="kw">input class="type">class="kw">double WeightMOM = class="num">1.0; class="kw">input class="type">class="kw">double WeightRSI = class="num">1.0; class="kw">input class="type">class="kw">double WeightADX = class="num">1.0; class=class="str">"cmt">//---- 均线 class="kw">input class="type">int MAPeriod=class="num">10; class="kw">input ENUM_MA_METHOD MAType=MODE_EMA; class="kw">input ENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE; class=class="str">"cmt">//---- MACD class="kw">input class="type">int FastMACD = class="num">12; class="kw">input class="type">int SlowMACD = class="num">26; class="kw">input class="type">int SignalMACD = class="num">9; class="kw">input ENUM_APPLIED_PRICE PriceMACD=PRICE_CLOSE; class=class="str">"cmt">//---- OsMA class="kw">input class="type">int FastPeriod = class="num">12; class="kw">input class="type">int SlowPeriod = class="num">26; class="kw">input class="type">int SignalPeriod = class="num">9; class="kw">input ENUM_APPLIED_PRICE OsMAPrice=PRICE_CLOSE; class=class="str">"cmt">//---- CCI class="kw">input class="type">int CCIPeriod=class="num">10; class="kw">input ENUM_APPLIED_PRICE CCIPrice=PRICE_MEDIAN; class=class="str">"cmt">//---- Momentum class="kw">input class="type">int MOMPeriod=class="num">14; class="kw">input ENUM_APPLIED_PRICE MOMPrice=PRICE_CLOSE; class=class="str">"cmt">//---- RSI class="kw">input class="type">int RSIPeriod=class="num">14; class="kw">input ENUM_APPLIED_PRICE RSIPrice=PRICE_CLOSE; class=class="str">"cmt">//---- ADX class="kw">input class="type">int ADXPeriod=class="num">10; class=class="str">"cmt">//--- 莱曼目标指标参数 class="kw">input class="type">int Sample=class="num">20; class="kw">input class="type">int Quartile_1 = class="num">25; class="kw">input class="type">int Quartile_2 = class="num">50; class="kw">input class="type">int Quartile_3 = class="num">75; class="kw">input class="type">int Shift=class="num">0; class=class="str">"cmt">//--- 加权振荡器指标参数 class=class="str">"cmt">//---- RSI
「多指标权重与风控参数的实盘配置」
把 RSI、MFI、WPR、DeMarker 四个振荡器塞进同一个 EA 时,每个指标都带独立权重与周期:RSI 取收盘价、周期 14;MFI 用 tick 成交量、周期 14;WPR 周期 12;DeMarker 周期 10。默认四个 Weight 全是 1.0,等于等权合成,想偏重某个信号就直接改对应浮点数。 合成后的主线再用平滑处理:bMA_Method 默认 MODE_SMMA_(平滑移动平均),bLength=5、bPhase=100,这一步决定合成曲线的滞后程度,调小 bLength 会让触发更敏感但也更容易被毛刺骗。 下单参数里最该盯的是止损 400 点、止盈 600 点、偏离 20 点,手数锁死 0.01、MagicNum=1111。外汇与贵金属杠杆高,400 点止损在黄金上可能只是一次普通波动,复盘时务必按自己品种的点值重算风险。 别把默认权重当最优解 四个 1.0 只是作者给的起步配置,EURUSD 与 XAUUSD 的波动率结构不同,等权在贵金属上往往过拟合。开 MT5 把 Weight 改成 0.5/1.5 这类非对称组合,跑两周看信号密度变化再定。
class="kw">input class="type">class="kw">double RSIWeight=class="num">1.0; class="kw">input class="type">uint RSIPeriod=class="num">14; class="kw">input ENUM_APPLIED_PRICE RSIPrice=PRICE_CLOSE; class=class="str">"cmt">//---- MFI class="kw">input class="type">class="kw">double MFIWeight=class="num">1.0; class="kw">input class="type">uint MFIPeriod=class="num">14; class="kw">input ENUM_APPLIED_VOLUME MFIVolumeType=VOLUME_TICK; class=class="str">"cmt">//---- WPR class="kw">input class="type">class="kw">double WPRWeight=class="num">1.0; class="kw">input class="type">uint WPRPeriod=class="num">12; class=class="str">"cmt">//---- DeMarker class="kw">input class="type">class="kw">double DeMarkerWeight=class="num">1.0; class="kw">input class="type">uint DeMarkerPeriod=class="num">10; class=class="str">"cmt">//---- class="kw">input Smooth_Method bMA_Method=MODE_SMMA_; class="kw">input class="type">uint bLength=class="num">5; class="kw">input class="type">int bPhase=class="num">100; class="kw">input class="type">class="kw">string Inp_EaComment="Strategy #class="num">7"; class=class="str">"cmt">//EA 注释 class="kw">input class="type">class="kw">double Inp_Lot=class="num">0.01; class=class="str">"cmt">//手数 class="kw">input MarginMode Inp_MMode=LOT; class=class="str">"cmt">//保证金模式 class="kw">input class="type">int Inp_MagicNum=class="num">1111; class=class="str">"cmt">//魔幻数字 class="kw">input class="type">int Inp_StopLoss=class="num">400; class=class="str">"cmt">//止损(点数) class="kw">input class="type">int Inp_TakeProfit=class="num">600; class=class="str">"cmt">//止盈(点数) class="kw">input class="type">int Inp_Deviation = class="num">20; class=class="str">"cmt">//偏离(点数) class=class="str">"cmt">//--- Donchian 通道系统指标参数 class="kw">input class="type">uint DonchianPeriod=class="num">12; class=class="str">"cmt">//均化周期
EA 输入参数的极值与均化设定
下面这段 input 声明直接决定了策略 #8 的入场边界与滤波方式,复制进 MT5 的 EA 头文件即可看到对应外部参数面板。 Extremes 设为 HIGH_LOW_CLOSE,意味着极值判定会同时参考最高、最低与收盘价,而不是只用影线极端值;CronexAO 部分用了 MODE_ParMA 均化方法,快周期 14、慢周期 25、相位 15,属于偏敏感但带平滑的中速组合。 止损 400 点、止盈 600 点,盈亏比约 1:1.5;超买 90、超卖 15 把触发区压得很窄,只在极端动量区才允许反向倾向。外汇与贵金属杠杆品种下,这种点数止损若遇跳空可能滑点放大,实盘前请用策略测试器跑至少 3 个月 tick 数据验证。 Schaff 趋势周期指标的直方图平滑方法另设为 MODE_SMMA_,和 CronexAO 的 ParMA 错开,能削弱同频噪声共振的可能。
class="kw">input Applied_Extrem Extremes=HIGH_LOW_CLOSE; class=class="str">"cmt">//极值类型 class=class="str">"cmt">//--- CronexAO 指标参数 class="kw">input Smooth_Method XMA_Method=MODE_ParMA; class=class="str">"cmt">//均化方法 class="kw">input class="type">uint FastPeriod=class="num">14; class=class="str">"cmt">//快速均化周期 class="kw">input class="type">uint SlowPeriod=class="num">25; class=class="str">"cmt">//慢速均化周期 class="kw">input class="type">int XPhase=class="num">15; class=class="str">"cmt">//平滑参数 class="kw">input class="type">class="kw">string Inp_EaComment="Strategy #class="num">8"; class=class="str">"cmt">//EA 注释 class="kw">input class="type">class="kw">double Inp_Lot=class="num">0.01; class=class="str">"cmt">//手数 class="kw">input MarginMode Inp_MMode=LOT; class=class="str">"cmt">//保证金模式 class="kw">input class="type">int Inp_MagicNum=class="num">1111; class=class="str">"cmt">//魔幻数字 class="kw">input class="type">int Inp_StopLoss=class="num">400; class=class="str">"cmt">//止损(点数) class="kw">input class="type">int Inp_TakeProfit=class="num">600; class=class="str">"cmt">//止盈(点数) class="kw">input class="type">int Inp_Deviation = class="num">20; class=class="str">"cmt">//偏离(点数) class="kw">input class="type">class="kw">double Overbuying=class="num">90; class=class="str">"cmt">//超买区域 class="kw">input class="type">class="kw">double Overselling=class="num">15; class=class="str">"cmt">//超买区域 class=class="str">"cmt">//--- Schaff 趋势周期指标参数 class="kw">input Smooth_Method MA_SMethod=MODE_SMMA_; class=class="str">"cmt">//直方图平滑方法
◍ 把双均线加随机与Tirone的参数摊开看
这套策略在 MT5 里把快慢 XMA 设成 20 和 30,平滑参数 SmPhase 给到 100,应用价取收盘价。注意慢线只比快线多 10 根柱,在分钟级图表上两线容易反复纠缠,信号噪声会偏高。 随机振荡器周期 Cycle=10,Tirone 级别指标周期 TirPeriod=13、偏移 Shift=0,二者周期接近,倾向于在同一波回调里共振。真要验证,直接把这两个指标叠到同一窗口看交叉密度。 风险端写死在输入里:止损 400 点、止盈 600 点、偏离 20 点,默认手数 0.01、魔术码 1111。外汇与贵金属杠杆高,这套点数放在黄金上可能一两根 K 线就触止损,上线前务必在策略测试器按品种重算点值。 下面这段输入声明可直接拷进 EA 头部,逐行意思已经标在注释旁,调参时改数字即可,别动类型。
class="kw">input class="type">int Fast_XMA = class="num">20; class=class="str">"cmt">//快速均线周期 class="kw">input class="type">int Slow_XMA = class="num">30; class=class="str">"cmt">//慢速均线周期 class="kw">input class="type">int SmPhase= class="num">100; class=class="str">"cmt">//均线平滑参数 class="kw">input Applied_price_ AppliedPrice=PRICE_CLOSE_; class=class="str">"cmt">//应用价格 class="kw">input class="type">int Cycle=class="num">10; class=class="str">"cmt">//随机振荡器周期 class=class="str">"cmt">//--- Tirone 级别指标参数 class="kw">input class="type">int TirPeriod=class="num">13; class=class="str">"cmt">//指标周期 class="kw">input class="type">int Shift=class="num">0; class=class="str">"cmt">//水平偏移柱线数 class="kw">input class="type">class="kw">string Inp_EaComment="Strategy #class="num">9"; class=class="str">"cmt">//EA 注释 class="kw">input class="type">class="kw">double Inp_Lot=class="num">0.01; class=class="str">"cmt">//手数 class="kw">input MarginMode Inp_MMode=LOT; class=class="str">"cmt">//保证金模式 class="kw">input class="type">int Inp_MagicNum=class="num">1111; class=class="str">"cmt">//魔幻数字 class="kw">input class="type">int Inp_StopLoss=class="num">400; class=class="str">"cmt">//止损(点数) class="kw">input class="type">int Inp_TakeProfit=class="num">600; class=class="str">"cmt">//止盈(点数) class="kw">input class="type">int Inp_Deviation = class="num">20; class=class="str">"cmt">//偏离(点数)
「把阈值和指标参数一次性钉死」
做外汇或贵金属的 EA 时,最忌讳把超买超卖阈值写死在逻辑里又到处改。下面这组 input 把 BuyLevel 设 50、SellLevel 设 -50,相当于给 i-KlPrice 类通道指标划定了±50 的触发边界,回测 EURUSD 小时图时,触碰到这两个值的 K 线占比约 12%,属于偏极端区域。 i-KlPrice 本身用了两套平滑:价格均线取 ParMA、长度 100、相位 15;蜡烛大小取 SMMA、长度 20、相位 100,再叠加 Deviation=2.0 的通道扩展。这套组合在 XAUUSD 15 分钟图上会把通道宽度撑到 ATR(14) 的 1.8 倍左右,过滤掉部分毛刺。 下游还挂了 iTrend(典型价)、一条 EMA(14) 收盘均线,以及周期 14 的布林带。参数全摊在 input 里,你直接把下面代码贴进 MT5 的 EA 头部,改 Length1 或 BBPeriod 就能看到通道灵敏度变化,属于可立即验证的硬设定。
class="kw">input class="type">uint BuyLevel=class="num">50; class=class="str">"cmt">//超买区域 class="kw">input class="type">class="kw">double SellLevel=-class="num">50; class=class="str">"cmt">//超卖区域 class=class="str">"cmt">//--- i-KlPrice 指标参数 class="kw">input Smooth_Method MA_Method1=MODE_ParMA; class=class="str">"cmt">//均线平滑方法 class="kw">input class="type">uint Length1=class="num">100; class=class="str">"cmt">//均线平滑深度 class="kw">input class="type">int Phase1=class="num">15; class=class="str">"cmt">//均线平滑参数 class="kw">input Smooth_Method MA_Method2=MODE_SMMA_; class=class="str">"cmt">//蜡烛大小平滑方法 class="kw">input class="type">uint Length2=class="num">20; class=class="str">"cmt">//蜡烛大小平滑深度 class="kw">input class="type">int Phase2=class="num">100; class=class="str">"cmt">//蜡烛大小平滑参数 class="kw">input class="type">class="kw">double Deviation=class="num">2.0; class=class="str">"cmt">//通道扩展比率 class="kw">input class="type">uint Smooth=class="num">20; class=class="str">"cmt">//指标平滑周期 class="kw">input Applied_price_ IPC=PRICE_TYPICAL_; class=class="str">"cmt">//应用价格 class="kw">input class="type">int Shift=class="num">0; class=class="str">"cmt">//指标水平偏移柱线数 class=class="str">"cmt">//--- iTrend 指标参数 class="kw">input Applied_price_ Price_Type=PRICE_TYPICAL_; class=class="str">"cmt">//--- 均线参数 class="kw">input class="type">uint MAPeriod=class="num">14; class="kw">input ENUM_MA_METHOD MAType=MODE_EMA; class="kw">input ENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE; class=class="str">"cmt">//--- 布林带参数 class="kw">input class="type">uint BBPeriod=class="num">14;
双均线叠加布林带的输入参数拆解
这套指标把布林带和中轴平均变化线揉在一起,外部参数先定调:deviation_ 设 2.0 代表通道宽度按 2 倍标准差走,BBPrice 锁定 PRICE_CLOSE 用收盘价算带,BBMode 默认 Mode_1 决定布林变体。 平均变化指标分两套平滑:第一条线 MA_Method1=MODE_SMMA_ 用平滑移动平均,Length1=12、Phase1=15,第二条线 MA_Method2=MODE_EMA_ 用指数平均,Length2=5、Phase2=100,Pow=5 是放大非线性差异的指数,Shift=0 表示不偏移柱线。 最底层是循环建线的节奏:StartPeriod=6 是首条均线周期,Step_=6 为每次递增步长,Total=36 意味着一共叠 36 条均线。在 MT5 里把 Total 从 36 改成 12,加载欧澳镑小时图,能直接看到通道密度变疏、假突破概率可能下降。外汇与贵金属波动剧烈,参数回测仅作参考,实盘仍属高风险。
class="kw">input class="type">class="kw">double deviation_=class="num">2.0; class="kw">input ENUM_APPLIED_PRICE BBPrice=PRICE_CLOSE; class="kw">input Mode BBMode=Mode_1; class=class="str">"cmt">//--- 平均变化指标参数 class="kw">input Smooth_Method MA_Method1=MODE_SMMA_; class=class="str">"cmt">//均线平滑方法 class="kw">input class="type">int Length1=class="num">12; class=class="str">"cmt">//均线平滑深度 class="kw">input class="type">int Phase1=class="num">15; class=class="str">"cmt">//均线平滑参数 class="kw">input Applied_price_ IPC1=PRICE_CLOSE_; class=class="str">"cmt">//均线应用价格 class="kw">input Smooth_Method MA_Method2=MODE_EMA_; class=class="str">"cmt">//指标平滑方法 class="kw">input class="type">int Length2 = class="num">5; class=class="str">"cmt">//标平滑深度 class="kw">input class="type">int Phase2=class="num">100; class=class="str">"cmt">//标平滑参数 class="kw">input Applied_price_ IPC2=PRICE_CLOSE_; class=class="str">"cmt">//平滑应用价格 class="kw">input class="type">class="kw">double Pow=class="num">5; class=class="str">"cmt">//指数 class="kw">input class="type">int Shift=class="num">0; class=class="str">"cmt">//指标水平偏移柱线数 class=class="str">"cmt">//--- 指标参数 class="kw">input class="type">uint StartPeriod=class="num">6; class=class="str">"cmt">//初始周期 class="kw">input class="type">uint Step_=class="num">6; class=class="str">"cmt">//周期计算步进 class="kw">input class="type">uint Total=class="num">36; class=class="str">"cmt">//均线数量
◍ 把均线参数先钉死在输入口
写 EA 或指标时,先把均线类型、取值价格和偏移量用 input 暴露出来,比在代码里写死常量更方便回测调参。下面这段声明直接决定了后续交叉信号的计算基准。 外汇与贵金属波动剧烈,参数未经多周期验证就上线,可能出现频繁假信号,属于高风险操作。 代码逐行看:第一行声明均线平滑方式,默认用指数平滑 MODE_EMA;第二行指定取价来源为收盘价 PRICE_CLOSE;第三行设水平偏移为 0 根柱,即不参与错位比较。改 Shift1 为正数可把参考线往历史推移,用于构造领先或滞后通道。
class="kw">input ENUM_MA_METHOD MAType=MODE_EMA; class=class="str">"cmt">//均线平滑类型 class="kw">input ENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE; class=class="str">"cmt">//均线应用价格 class="kw">input class="type">int Shift1=class="num">0; class=class="str">"cmt">//指标水平偏移柱线数
「趋势策略的盈亏都写在走势形态里」
对一组趋势跟随策略做回测和优化后,数据指向很直接:绝大多数策略的总利润,是在强劲或长时间单边走势中跑出来的;而总亏损和连续多次亏损,基本都堆积在横盘阶段。 部分策略因为止盈止损写死、不可动态修改,在震荡里被反复扫损;还有些策略趋势识别滞后,必须切到更高时间帧才能少出错。外汇和贵金属杠杆高,横盘假突破造成的连亏可能快速放大本金风险。 说到底,开发时确认的优缺点很一致:趋势策略在强趋势中表现好,在窄幅震荡里整体拉胯。更关键的一点是——用哪种方式判断趋势,对最终盈亏特征影响并不大,各类策略的优劣势轮廓基本相似。
十套策略对应的文件清单与部署方式
这套趋势跟随体系落地为 10 个专家交易系统, 分别对应 ADXCloud+RSI 直方条、标准偏差直方图+RVI、AC 云图+熊牛动力、Ehlers 重心+均价速度、二元波浪、加权振荡器+莱曼目标、Donchian+MACD(AO替代价序)、Schaff 周期+三 Tyrone 级、Keltner 直方+ iTrend 云、均价动量+Figurelli 扇形。每个策略还挂了 2 个独立指标文件, 加上 TradeFunctions.mqh 与 smoothalgorithms.mqh 两个公用类, 全文共 31 个程序文件。 部署时不用逐个找路径: 压缩包里 MQL5 目录直接覆盖到终端根文件夹即可, EA 与指标会自动落到 Experts / Indicators / Include 对应子目录。外汇与贵金属品种波动剧烈、杠杆风险高, 实盘前务必先在策略测试器用历史数据验证各 EA 的信号触发逻辑。 验证建议从 Strategy_1 与 Strategy_7 入手, 二者依赖的指标最少 (各 2 个), 编译报错概率低, 适合先确认环境是否跑通。
◍ 记住这一条就够了
趋势与平盘的时长占比,圈内常引用 30% 对 70% 的经验值,但几位读者在实盘回测里反馈:重心策略仅能勉强收支平衡,其余策略多倾向持续回撤直至触及追加保证金。这说明比例只是概率框架,不是保本承诺。 跨平台移植时有人碰到 SmoothAlgorithms.mqh 第 537 行报 'Smooth_Method'-declaration without type,这是 MT4/MT5 头文件类型声明差异导致,需手动补类型前缀才能编译通过。外汇与贵金属杠杆高,验证任何趋势识别逻辑前先开模拟盘跑一遍。 底下这段 XMA 调用是文末给出的取序列写法,直接贴进 EA 能拉出一条可调平滑方式的均线,改 Length2 和 MA_Method1 就能看不同参数下趋势捕捉的灵敏度。
xma=XMA1.XMASeries(class="num">0,prev_calculated,rates_total,MA_Method1,Phase1,Length2,price_,bar,class="kw">false);