趋势跟随策略在外汇市场上非常流行。该思路是检测出一个强劲单边走势, 找到最佳入场点, 以及 — 也是同样非常重要的 — 正确检测出离场点。为了本文所概括的目的, 我选择了一些能够直接或间接地检测趋势的技术工具。基于这些工具, 以 MetaTrader 5 专家交易系统的形式实现了 10 个交易策略。根据这些专家交易系统的结果, 我分析了每个交易策略的优缺点, 并对其绩效进行了比较。本文的目的是为读者提供有关趋势跟随交易的强劲/弱势的最全面信息。
初见时, 好似开发一款趋势跟随策略并非一件艰巨的任务。您只需要使用技术分析检测趋势, 打仓并等待进一步的走势, 同时尽可能地加仓。在理论上, 这种做法是无可指责的。不过, 在实践中出现了一些重要的问题。
图例.1 趋势和横盘检测区域。
任务 1. 识别趋势的存在
通常, 趋势定义和确认需要时间。所以, 在趋势伊始不会有理想的、和极为可靠的入场点。参见图例. 1. 不可能在图表上将入场位置确定为一个点。我们只能看到 入场的有利区域。依照事实解释所定义的区域, 这是由于在分析过程中信号可能会延迟, 因而需要时间来确认趋势。一个交易系统的例子, 其中一个指标为趋势信号, 另一个指标在一段时间后确认其与否。这种方法需要时间。然而时间就是金钱。在我们的案例中, 时间意味着错失盈利。
任务 2. 一笔开仓的目标。
我们已检测到这波趋势并确认了这一点。现在我们需要入场。然而, 在行动之前, 我们需要定义盈利目标。我们可以按照点数设定盈利目标, 或者根据趋势强度预测使用动态目标。此处, 可以使用支撑和阻力级别。不过, 在入场之前应当清楚地知道何时离场。下一个任务与当前任务密切相关。
任务 3. 检测趋势结束。
我们再次参考图例. 1。它显示了以下状况: 我们在绿色区域入场, 且之后趋势延续, 直到 横盘区域。这里我们需要判断, 此为暂时状态, 亦或我们需要离场。在此案例中, 横盘周期很短暂, 且趋势延续。请注意, 在固定盈利目标的策略中, 预测走势区间的持续时间是基于每次任务 2 确认的趋势评估。
这里是一般情况。在此趋势策略评测中, 我决定不使用太大和太小的时间帧, 因为在较低的时间帧上可能会产生太多的假信号, 而在较大的时间帧上入场机会太少, 这也许不足以客观地分析策略的效率。因此, 在测试期间将使用 M30 和 H4 之间的时间帧。
策略 #1: ADXCloud 指标配合 RSI 直方条进行确认。
首先分析的策略基于 ADX 指标 — ADXCloud。信号将由具有超买/超卖级别的 RSI 振荡器确认。它被绘制为直方图, 其中 RSI 值的绿色柱线是参考的超买区域, 红色示意超卖区域。
参数 | 描述 |
---|---|
使用的指标 | ADXCloud |
使用的指标 | RSIColor |
时间帧 | H1 |
买入条件 | 云图颜色从红色变为绿色, RSIColor 直方图为绿色。 |
卖出条件 | 云图颜色从绿色变为红色, RSIColor 直方图为红色。 |
离场条件 | 止盈/止损 |
策略示意图呈现在图例. 2。在 H1 时间帧上, 作为趋势的定义区域仅持续几根柱线, 因此在离场条件中不会使用较大的数值作为止盈和止损级别。
图例. 2. 趋势策略 #1 的入场条件
此处是基于此策略实现的专家交易系统代码:
策略 #2: 标准偏差趋势指标绘制为直方图, 配合 RVI 进行确认。
该策略基于改编的标准偏差趋势指标和 RVI 振荡器。要了解这些指标如何工作的更多信息, 请参见表格中的链接。
参数 | 描述 |
---|---|
使用的指标 | ColorStdDev |
使用的指标 | ColorZerolagRVI |
时间帧 | H1 |
买入条件 | ColorStdDev 直方图为红色 (强劲趋势), ColorZerolagRVI 云图为绿色。 |
卖出条件 | ColorStdDev 直方图为红色 (强劲趋势), ColorZerolagRVI 云图为红色。 |
离场条件 | 止盈/止损 |
策略示意图呈现在图例. 3。强劲走势区域是使用标准偏差来判断的。趋势由改编的 RVI 振荡器来确认, 该振荡器基于四个具有不同周期和加权的标准 RVI。
图例. 3. 趋势策略 #2 的入场条件
请注意, 在该策略的软件实现中, ColorStDev 设置中的强劲趋势、中等趋势和横盘数值应根据经验判定。我们将使用省缺值, 但出于方便起见, 我们来添加 使用趋势选项, 它可选择趋势类型进行交易 — 中等或是强劲。这样, 我们不需要每次重新定义以下三个值, 而只需要选择一个。使用强劲趋势信号更适合当前的策略, 因为我们在 H4 时间帧上使用它。中等趋势选项更适合于在较高时间帧内进行测试。与此同时, 请记住, 在中等趋势时将有更多的入场信号。因此, 有必要考虑盈利目标和当前时间帧, 以便过滤掉假信号并得到正面结果。
//--- ColorStDev 指标参数inputint period = 12; //平滑周期 StDevinputENUM_MA_METHOD MA_Method=MODE_EMA; //直方图平滑方法inputENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; //应用价格inputint MaxTrendLevel=100; //最大趋势级别inputint MiddLeTrendLevel=40; //中等趋势级别inputint FlatLevel=10; //横盘级别input Trend TrendLevel=Maximum; //使用的趋势在代码中体现了该策略的思路:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(stdev[0]>trend && rvi_fast[0]>rvi_slow[0])?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(stdev[0]>trend && rvi_fast[0]<rvi_slow[0])?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,stdev)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,rvi_fast)<=0 || CopyBuffer(InpInd_Handle2,1,0,2,rvi_slow)<=0 )?false:true; }
策略 #3: 比尔·威廉姆斯的 AC 云图, 与熊市动力 + 牛市动力指标的组合。
在下一个策略中, 我决定尝试比尔·威廉姆斯的加速振荡器 (AC) 云图, 以及与熊市动力 + 牛市动力振荡器的组合。
参数 | 描述 |
---|---|
使用的指标 | Bear_Bulls_Power |
使用的指标 | CronexAC |
时间帧 | H1 |
买入条件 | 直方图显示增长 (其颜色从粉红色变为蓝色, 且指标值小于零), CroneAC 云图为蓝色。 |
卖出条件 | 直方图显示下跌 (其颜色从蓝色变为粉红色, 且指标值大于零), CroneAC 云图为橙色。 |
离场条件 | 止盈/止损 |
策略示意图呈现在图例. 4。当搜索信号时, 必须监视早期的直方图成长。换言之, 我们需要找到牛市被熊市替代的时刻, 反之亦然, 然后需要来自振荡器的确认信号。
图例.4 趋势策略 #3 的入场条件
该策略允许使用不同的入场条件: 替代搜索直方图的 "早期" 增长, 我们可以使用稍后的信号: 例如, 当指标越过零值, 或其值的符号发生变化时。也许, 即使直方图的颜色变化也可能产生结果。根据最初描述的条件实现的策略在下面的列表中提供:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(ac_fast[0]>ac_slow[0] && bb_power[0]>bb_power[1] && (bb_power[0]<0 && bb_power[1]<0))?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(ac_fast[0]<ac_slow[0] && bb_power[0]<bb_power[1] && (bb_power[0]>0 && bb_power[1]>0))?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,bb_power)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,ac_fast)<=0 || CopyBuffer(InpInd_Handle2,1,0,2,ac_slow)<=0 )?false:true; }策略 #4: Ehlers 的重心配合平均价格速度指标进行确认。
该策略使用由彩色 OSMA 直方图呈现的 J. F. Ehlers 重心指标 — CenterOfGravityOSMA。其信号由计算平均价格速度的指标进行确认。
参数 | 描述 |
---|---|
使用的指标 | CenterOfGravityOSMA |
使用的指标 | 平均速度 |
时间帧 | H1 |
买入条件 | 重力中心的直方图显示增长 (指标值小于零), 且平均速度值高于阈值 (预设在参数中) |
卖出条件 | 重力中心的直方图显示下跌 (指标值大于零), 且平均速度值高于阈值 (预设在参数中) |
离场条件 | 止盈/止损 |
策略示意图呈现在图例. 5。就像之前的策略一样, 我们监控直方图的早期变化, 并等待来自价格变化速度的确认。
图例. 5. 趋势策略 #4 的入场条件
策略实现:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(avr_speed[0]>Trend_lev && cog[1]<cog[0] &&(cog[1]<0 && cog[0]<0))?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(avr_speed[0]>Trend_lev && cog[1]>cog[0] &&(cog[1]>0 && cog[0]>0))?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,cog)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,avr_speed)<=0 )?false:true; }
策略 #5. 复杂的二元波浪指标。
前四种策略是基于选择显示趋势的主要指标的组合模型, 并附加确认信号。在这个策略中, 我决定使用另一个方案仅基于一个指标: 二元波浪。它看起来像一款振荡器, 但实际上它将七个指标生成的信号结果可视化, 包括 MA, MACD, OsM, CCI, Momentum, RSI 和 ADX。这是一个全功能的交易策略, 带有灵活的参数系统。除了所选指标的标准参数集之外, 此处还要使用附加的加权来显示特定组件的效果。
参数 | 描述 |
---|---|
使用的指标 | Binary_Wave |
时间帧 | H1 |
买入条件 | 穿越零值向上 |
卖出条件 | 穿越零值向下 |
离场条件 | 止盈/止损 |
基于该策略的入场示例在图例. 6 中提供。注意: 为了针对 H1 优化策略, 软件实现中的 MA_Period, CCIPeriod, MOMPeriod, RSIPeriod 和 ADX_Period 周期的省缺值从 14 更改为 10 (更快)。如果您需要测试经典周期, 您可以使用时间帧 H3 或 H4。
图例.6 趋势策略 #5 的入场条件
实现结果:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(wave[0]>0 && wave[1]<0)?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(wave[0]<0 && wave[1]>0)?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle,0,0,2,wave)<=0)?false:true; }策略 #6: 复杂的加权振荡器, 与莱曼目标的组合。
它结合了前五个例子中使用的策略原理。然后我们组合为完备的系统并向其添加一个信号进行确认。我们将使用加权振荡器, 表现四个指标的加权平滑和: RSI, MFI, WPR 和 DeMarker。信号将由莱曼目标确认, 其计算 开盘价到最高价和最低价的距离, 并显示偏差的四分之一。在给定数量的柱线上, 指标还提供了 75%, 50%, 25%处的价格变化汇总统计的移动平均值, 并显示最大偏差。 我们将监控加权振荡器直方图的增长情况用于买入; 价格突破了偏离四分位数值的 75%用于确认。
参数 | 描述 |
---|---|
使用的指标 | 加权振荡器 |
使用的指标 | 莱曼目标 |
时间帧 | H1 |
买入条件 | 加权振荡器正在增长, 价格突破了偏离四分位数值的 75% 的上限。 |
卖出条件 | 加权振荡器正在下跌, 价格突破了偏离四分位数值的 75% 的下限。 |
离场条件 | 止盈/止损 |
入场点显示在图例. 7。75% 的级别显示为一条实线。收盘价格突破这些级别, 加权振荡器增长/下降的条件得以满足。
图例. 7. 趋势策略 #6 的入场条件
莱曼目标指标使用 8 个指标缓存区用于绘制级别:
四分位数 1 是相关价格下降的平均值对应于所有样本情况的 25%。
四分位数 2 是相关价格下降的平均值对应于所有样本情况的 50%。
四分位数 3 是相关价格下降的平均值对应于所有样本情况的 75%。我们的策略中将会用到它。
四分位数 4 对应于平均价格值的最大偏差。
四分位数 5 是相关价格上升的平均值对应于所有样本情况的 25%。
四分位数 6 是相关价格上升的平均值对应于所有样本情况的 50%。
四分位数 7 是相关价格上升的平均值对应于所有样本情况的 75%。我们的策略中将会用到它。
四分位数 8 对应于平均价格值的最大偏差。
在实现中, 除了加权振荡器和收盘价之外, 我们需要 缓存区 2 和 6。
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(wo[0]>wo[1] && close[0]>obj_q3_b[0])?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(wo[0]<wo[1] && close[0]<obj_q3_s[0])?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,6,0,2,obj_q3_b)<=0 || CopyBuffer(InpInd_Handle1,2,0,2,obj_q3_s)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,wo)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; }
策略 #7: Donchian 通道与 MACD 的组合, 其价格序列由威廉姆斯的 AO 值代替。
Donchian 通道用于判断强劲的单边走势。通道突破将被用作趋势的标志。若要确认趋势, 我们使用一款改编的 MACD, 其中价格系列由比尔·威廉姆斯的 AO 值代替。
参数 | 描述 |
---|---|
使用的指标 | Donchian 通道系统 |
使用的指标 | CronexAO |
时间帧 | H1 |
买入条件 | Donchian 通道上边界的突破和 CronexAO 云图的蓝色 |
卖出条件 | Donchian 通道下边界的突破和 CronexAO 云图的粉红色 |
离场条件 | 止盈/止损 |
在图例 8 中, 这种趋势策略以图形方式显示。为了更便利地显示且明晰, 我们使用具有变色颜色的指标判断蜡烛条突破 Donchian 通道的上部或下部边界。CronexAO 颜色与突破通道边界的蜡烛条颜色相匹配。
图例. 8. 趋势策略 #7 的入场条件
当实现此策略时, 请注意要点, 蜡烛条的最高价和最低价数值用作极值。然而, 如果品种价格经常在一个方向或其它 (蜡烛条长影线) 上跳转, 然后返回到平均值, 则最好使用蜡烛条的开盘价或收盘价数值, 或 开盘价+最高价/开盘价+最低价 的组合。这将减少长影线的影响。
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(cao_fast[0]>cao_slow[0] && close[0]>dcs_up[0])?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(cao_fast[0]<cao_slow[0] && close[0]<dcs_low[0])?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,dcs_up)<=0 || CopyBuffer(InpInd_Handle1,1,0,2,dcs_low)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,cao_fast)<=0 || CopyBuffer(InpInd_Handle2,1,0,2,cao_slow)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; }
策略 #8: Schaff 周期振荡器, 基于三个 Tyrone 级别进行确认。
此策略基于 Schaff 周期振荡器, 利用它的从超买/超卖区域退出。三个 Tirone 级别用于检查。在较高的基本时间帧上获得了有趣的结果。选择 H4 进行测试。
参数 | 描述 |
---|---|
使用的指标 | Schaff 趋势周期 |
使用的指标 | 三个 Tirone 级别 |
时间帧 | H4 |
买入条件 | 退出超卖区域, 而当前的价格应该高于 Titone 级别。 |
卖出条件 | 退出超买区域, 而当前的价格应该低于 Titone 级别。 |
离场条件 | 止盈/止损 |
这种趋势跟随策略的图形表示显示在图例.9 中。
图例. 9 趋势策略 #8 的入场条件
在此策略的实现中, 除了两个指标的主要参数之外, 必须添加超买/超卖级别的数值。 我并未修改它们, 而是使用省缺值 20 和 80。但是我修改了平滑参数和周期 (在图例中, 它显示在 Schaff 指标的左上角)。这些设置是可选的, 您可以使用省缺设置或自行设置数值。
//+------------------------------------------------------------------+//| 专家交易系统输入参数 |//+------------------------------------------------------------------+inputstring Inp_EaComment="Strategy #8"; //EA 注释inputdouble Inp_Lot=0.01; //手数input MarginMode Inp_MMode=LOT; //保证金模式inputint Inp_MagicNum=1111; //魔幻数字inputint Inp_StopLoss=400; //止损(点数)inputint Inp_TakeProfit=600; //止盈(点数)inputint Inp_Deviation = 20; //偏离(点数)inputdouble Overbuying=80; //超买区域inputdouble Overselling=20; //超卖区域//--- Schaff 趋势周期指标参数input Smooth_Method MA_SMethod=MODE_SMMA_; //直方图平滑方法inputint Fast_XMA = 20; //快速均线周期inputint Slow_XMA = 30; //慢速均线周期inputint SmPhase= 100; //均线平滑参数input Applied_price_ AppliedPrice=PRICE_CLOSE_; //应用价格inputint Cycle=10; //随机振荡器周期策略的原理如下:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(schaff[1]<Overselling && schaff[0]>Overselling && close[0]>tirone_b[0])?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(schaff[1]>Overbuying && schaff[0]<Overbuying && close[0]<tirone_s[0])?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,schaff)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,tirone_b)<=0 || CopyBuffer(InpInd_Handle2,2,0,2,tirone_s)<=0 || CopyClose(Symbol(),PERIOD_CURRENT,0,2,close)<=0 )?false:true; }
策略 #9: Keltner 通道绘制为直方图, 且 iTrend 指标绘制为云图。
使用绘制为直方图的基于 Keltner 通道的 i-KlPrice 来识别趋势。对于趋势确认, 我们将使用云图形式的 iTrend 指标, 其云图颜色和宽度表征当前趋势。就像之前的策略一样, 当与某些级别交叉时这里会生成信号。这些 i-K1Price 的级别省缺值为 50 和 -50。因此, 添加 BuyLevel 和 SellLevel 参数也是有意义的: 穿越这些级别将表示买入或卖出信号。
信号将由 iTrend 确认。在此指标中, 我们将观察由两条线的数值确定的云图颜色。上边线是平滑价格值与参数中选择的布林带之一之间的差值。下边线是 (最高价+最低价) 和当前蜡烛条的均值乘以 -1 之间的差值。
参数 | 描述 |
---|---|
使用的指标 | i-KlPrice |
使用的指标 | iTrend |
时间帧 | H1 |
买入条件 | i-KlPrice 直方图的值大于 BuyLevel, 且 iTrend 云图为绿色。 |
卖出条件 | i-KlPrice 直方图的值低于 SellLevel, 且 iTrend 云图为粉红色。 |
离场条件 | 止盈/止损 |
图例. 10 趋势跟随策略的入场点示例。
图例. 10. 趋势策略 #9 的入场条件
这是我实现的此策略代码:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(klprice[0]>BuyLevel && itrend_h[0]>itrend_l[0])?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(klprice[0]<SellLevel && itrend_h[0]<itrend_l[0])?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,klprice)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,itrend_h)<=0 || CopyBuffer(InpInd_Handle2,1,0,2,itrend_l)<=0 )?false:true; }
策略 #10: 平均价格变化动量和 MA FigurelliSeries 扇形。
最后一个版本使用平均变化指标分析趋势。FigurelliSeries 作为直方图将用于动量确认。平均变化的基准值等于 1。基于此数值, 价格动量信号向上或向下。此策略的入场条件为正在穿越数值 1 。为了理解 FigurelliSeries 指标数值的含义为何, 您需要研究其算法和输入:
//+----------------------------------------------+//| 指标参数 |//+----------------------------------------------+inputuint StartPeriod=6; // 初始周期inputuint Step=6; // 周期计算步进inputuint Total=36; // 均线数量input ENUM_MA_METHOD MAType=MODE_EMA; // 均线平滑类型inputENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE; // 均线应用价格inputint Shift=0; // 指标水平偏移的柱线数首先设置 StartPeriod (均线的起始周期), 之后的其它 36 条均线周期等于起始值并逐级加上指定的 Step。然后我们选择进行计算的均线类型和适用价格。这实际上是 MA 扇形, 其数值与当前的收盘价进行比较。直方图的数值表示 位于收盘价之上和之下的均线数量差值:
//---- 指标计算的主循环 for(bar=limit; bar>=0 && !IsStopped(); bar--) { double tot_Ask=0; double tot_Bid=0; for(int count=0; count<int(Total); count++) { //---- 将新出现的数据复制到数组中 if(CopyBuffer(MA_Handle[count],0,bar,1,MA)<=0) return(RESET); if(close[bar]<MA[0]) tot_Ask++; if(close[bar]>MA[0]) tot_Bid++; } IndBuffer[bar]=tot_Bid-tot_Ask; }通过总结两个指标的操作原理, 我们制定了策略的入场规则:
参数 | 描述 |
---|---|
使用的指标 | 平均变化 |
使用的指标 | Figurelli Series |
时间帧 | H4 |
买入条件 | 平均变化向上穿越阈值, 并且 Figurelli Series 直方图的值高于零。 |
卖出条件 | 平均变化向下穿越阈值, 并且 Figurelli Series 直方图的值低于零。 |
离场条件 | 止盈/止损 |
图例. 11 基于此策略显示的入场示例:
图例. 11. 趋势策略 #10 的入场条件
策略代码:
voidOnTick() {//--- 检查 EA 以前的开单 if(!Trade.IsOpened(Inp_MagicNum)) { //--- 获取数据进行计算 if(!GetIndValue()) return; //--- 如果是买入信号, 开单 if(BuySignal()) Trade.BuyPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); //--- 如果是卖出信号, 开单 if(SellSignal()) Trade.SellPositionOpen(true,Symbol(),Inp_Lot,Inp_MMode,Inp_Deviation,Inp_StopLoss,Inp_TakeProfit,Inp_MagicNum,Inp_EaComment); } }//+------------------------------------------------------------------+//| 买入条件 |//+------------------------------------------------------------------+bool BuySignal() { return(avr_change[1]<1 && avr_change[0]>1 && fig_series[0]>0)?true:false; }//+------------------------------------------------------------------+//| 卖出条件 |//+------------------------------------------------------------------+bool SellSignal() { return(avr_change[1]>1 && avr_change[0]<1 && fig_series[0]<0)?true:false; }//+------------------------------------------------------------------+//| 获取指标的当前值 |//+------------------------------------------------------------------+bool GetIndValue() { return(CopyBuffer(InpInd_Handle1,0,0,2,avr_change)<=0 || CopyBuffer(InpInd_Handle2,0,0,2,fig_series)<=0 )?false:true; }
在上一节中, 我们制定了 10 款趋势跟随策略并为它们准备了代码。为了测试并比较获得的结果, 我们需要选择相同的条件和测试模式。
区间: 01.01.2016 — 01.03.2017 。
货币对: EURUSD。
交易模式: 无延迟。这些不是高频交易策略, 所以延迟的影响微乎其微。
测试: M1 OHLC. 在真实即时报价上进行的预测显示几乎相同的结果。
初始本金: 1000 USD。
杠杆: 1:500.
服务器: MetaQuotes-Demo.
报价: 5-位小数。
几乎在所有的策略中, 离场条件是触发止盈/止损, 8 款策略在 H1 上运行。因此, 我们可以对这些策略使用相同的止盈和止损值。我们将止盈设置为 600 (5-位小数报价), 以及止损为 400。除了以上指定的条件, 我们还要为策略中使用的指标设置预设参数。
策略 #1 的测试 (ADXCloud 指标配合 RSI 直方条进行确认)。
预设:
测试结果:
图例. 12 策略 #1。测试结果
策略 #2 的测试: (标准偏差趋势指标绘制为直方图, 配合 RVI 进行确认)。
预设:
//--- ColorStDev 指标参数inputint period = 12; //平滑周期 StDevinputENUM_MA_METHOD MA_Method=MODE_EMA; //直方图平滑方法inputENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; //应用价格inputint MaxTrendLevel=90; //最强趋势级别inputint MiddLeTrendLevel=50; //中等趋势级别inputint FlatLevel=20; //横盘级别input Trend TrendLevel=Maximum; //使用的趋势//--- ColorZerolagRVI 指标参数inputuint smoothing=15; //平滑周期 RVIinputdouble Factor1=0.05; //加权系数1inputint RVI_period1=14; //RVI 周期 1inputdouble Factor2=0.10; //加权系数2inputint RVI_period2=28; //RVI 周期 2inputdouble Factor3=0.16; //加权系数3inputint RVI_period3=45; //RVI 周期 3inputdouble Factor4=0.26; //加权系数4inputint RVI_period4=65; //RVI 周期 4inputdouble Factor5=0.43; //加权系数5inputint RVI_period5=75; //RVI 周期 5测试结果:
图例. 13 策略 #2. 测试结果
策略 #3 的测试 (比尔·威廉姆斯的 AC 云图, 与熊市动力 - 牛市动力指标的组合)。
预设:
//--- Bears_Bull_power 指标参数input Smooth_Method MA_Method1=MODE_AMA; //均化方法inputuint Length1=12; //均化深度 inputint Phase1=15; //均化参数input Smooth_Method MA_Method2=MODE_ParMA; //平滑周期inputuint Length2=5; //平滑深度inputint Phase2=15; //平滑参数input Applied_price_ IPC=PRICE_WEIGHTED_; //应用价格inputint Shift=0; //偏移//--- CronexAC 指标参数input Smooth_Method XMA_Method=MODE_SMMA_; //平滑方法inputuint FastPeriod=9; //快速平滑周期inputuint SlowPeriod=21; //慢速平滑周期inputint XPhase=15; //平滑参数测试结果:
图例. 14 策略 #3。测试结果
策略 #4 的测试 (Ehlers 的重心配合平均价格速度指标进行确认)。
预设:
//--- CenterOfGravityOSMA 指标参数inputuint Period_=9; //均化周期inputuint SmoothPeriod1=3; //平滑周期1inputENUM_MA_METHOD MA_Method_1=MODE_SMA; //均化方法1inputuint SmoothPeriod2=3; //平滑周期2inputENUM_MA_METHOD MA_Method_2=MODE_SMA; //均化方法2input Applied_price_ AppliedPrice=PRICE_OPEN_; //应用价格//--- 均速指标参数inputint Inp_Bars=1; //柱线数量inputENUM_APPLIED_PRICE Price=PRICE_CLOSE; //应用价格inputdouble Trend_lev=2; //趋势级别测试结果:
图例. 15 策略 #4。测试结果
策略 #5 的测试 (复杂的二元波浪指标)。
预设:
//--- Binary_Wave 指标参数inputdouble WeightMA = 1.0;inputdouble WeightMACD = 1.0;inputdouble WeightOsMA = 1.0;inputdouble WeightCCI = 1.0;inputdouble WeightMOM = 1.0;inputdouble WeightRSI = 1.0;inputdouble WeightADX = 1.0;//---- 均线inputint MAPeriod=10;inputENUM_MA_METHOD MAType=MODE_EMA;inputENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE;//---- MACDinputint FastMACD = 12;inputint SlowMACD = 26;inputint SignalMACD = 9;inputENUM_APPLIED_PRICE PriceMACD=PRICE_CLOSE;//---- OsMAinputint FastPeriod = 12;inputint SlowPeriod = 26;inputint SignalPeriod = 9;inputENUM_APPLIED_PRICE OsMAPrice=PRICE_CLOSE;//---- CCIinputint CCIPeriod=10;inputENUM_APPLIED_PRICE CCIPrice=PRICE_MEDIAN;//---- Momentuminputint MOMPeriod=14;inputENUM_APPLIED_PRICE MOMPrice=PRICE_CLOSE;//---- RSIinputint RSIPeriod=14;inputENUM_APPLIED_PRICE RSIPrice=PRICE_CLOSE;//---- ADXinputint ADXPeriod=10;测试结果:
图例. 16 策略 #5。测试结果
策略 #6 的测试 (复杂的加权振荡器, 与莱曼目标的组合)。
预设:
//--- 莱曼目标指标参数inputint Sample=20;inputint Quartile_1 = 25;inputint Quartile_2 = 50;inputint Quartile_3 = 75;inputint Shift=0;//--- 加权振荡器指标参数//---- RSIinputdouble RSIWeight=1.0;inputuint RSIPeriod=14;inputENUM_APPLIED_PRICE RSIPrice=PRICE_CLOSE;//---- MFIinputdouble MFIWeight=1.0;inputuint MFIPeriod=14;inputENUM_APPLIED_VOLUME MFIVolumeType=VOLUME_TICK;//---- WPRinputdouble WPRWeight=1.0;inputuint WPRPeriod=12;//---- DeMarkerinputdouble DeMarkerWeight=1.0;inputuint DeMarkerPeriod=10;//----input Smooth_Method bMA_Method=MODE_SMMA_;inputuint bLength=5;inputint bPhase=100;测试结果:
图例. 17 策略 #6。测试结果
策略 #7 的测试 (Donchian 通道与 MACD 的组合, 其价格序列由威廉姆斯的 AO 值代替)。
预设:
inputstring Inp_EaComment="Strategy #7"; //EA 注释inputdouble Inp_Lot=0.01; //手数input MarginMode Inp_MMode=LOT; //保证金模式inputint Inp_MagicNum=1111; //魔幻数字inputint Inp_StopLoss=400; //止损(点数)inputint Inp_TakeProfit=600; //止盈(点数)inputint Inp_Deviation = 20; //偏离(点数)//--- Donchian 通道系统指标参数inputuint DonchianPeriod=12; //均化周期input Applied_Extrem Extremes=HIGH_LOW_CLOSE; //极值类型//--- CronexAO 指标参数input Smooth_Method XMA_Method=MODE_ParMA; //均化方法inputuint FastPeriod=14; //快速均化周期inputuint SlowPeriod=25; //慢速均化周期inputint XPhase=15; //平滑参数测试结果:
图例. 18 策略 #7。测试结果
策略 #8 测试 (Schaff 周期振荡器, 基于三个 Tyrone 级别进行确认)。
预设:
inputstring Inp_EaComment="Strategy #8"; //EA 注释inputdouble Inp_Lot=0.01; //手数input MarginMode Inp_MMode=LOT; //保证金模式inputint Inp_MagicNum=1111; //魔幻数字inputint Inp_StopLoss=400; //止损(点数)inputint Inp_TakeProfit=600; //止盈(点数)inputint Inp_Deviation = 20; //偏离(点数)inputdouble Overbuying=90; //超买区域inputdouble Overselling=15; //超买区域//--- Schaff 趋势周期指标参数input Smooth_Method MA_SMethod=MODE_SMMA_; //直方图平滑方法inputint Fast_XMA = 20; //快速均线周期inputint Slow_XMA = 30; //慢速均线周期inputint SmPhase= 100; //均线平滑参数input Applied_price_ AppliedPrice=PRICE_CLOSE_; //应用价格inputint Cycle=10; //随机振荡器周期//--- Tirone 级别指标参数inputint TirPeriod=13; //指标周期inputint Shift=0; //水平偏移柱线数测试结果:
图例. 19 策略 #8。测试结果
策略 #9 的测试 (Keltner 通道绘制为直方图, 且 iTrend 指标绘制为云图)。
预设:
inputstring Inp_EaComment="Strategy #9"; //EA 注释inputdouble Inp_Lot=0.01; //手数input MarginMode Inp_MMode=LOT; //保证金模式inputint Inp_MagicNum=1111; //魔幻数字inputint Inp_StopLoss=400; //止损(点数)inputint Inp_TakeProfit=600; //止盈(点数)inputint Inp_Deviation = 20; //偏离(点数)inputuint BuyLevel=50; //超买区域inputdouble SellLevel=-50; //超卖区域//--- i-KlPrice 指标参数input Smooth_Method MA_Method1=MODE_ParMA; //均线平滑方法inputuint Length1=100; //均线平滑深度inputint Phase1=15; //均线平滑参数input Smooth_Method MA_Method2=MODE_SMMA_; //蜡烛大小平滑方法inputuint Length2=20; //蜡烛大小平滑深度inputint Phase2=100; //蜡烛大小平滑参数inputdouble Deviation=2.0; //通道扩展比率inputuint Smooth=20; //指标平滑周期input Applied_price_ IPC=PRICE_TYPICAL_; //应用价格inputint Shift=0; //指标水平偏移柱线数//--- iTrend 指标参数input Applied_price_ Price_Type=PRICE_TYPICAL_;//--- 均线参数inputuint MAPeriod=14;inputENUM_MA_METHOD MAType=MODE_EMA;inputENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE;//--- 布林带参数inputuint BBPeriod=14;inputdouble deviation_=2.0;inputENUM_APPLIED_PRICE BBPrice=PRICE_CLOSE;input Mode BBMode=Mode_1;测试结果:
图例. 20 策略 #9。测试结果
策略 #10 的测试 (平均价格变化动量和 MA FigurelliSeries 扇形)。
预设:
//--- 平均变化指标参数input Smooth_Method MA_Method1=MODE_SMMA_; //均线平滑方法inputint Length1=12; //均线平滑深度inputint Phase1=15; //均线平滑参数input Applied_price_ IPC1=PRICE_CLOSE_; //均线应用价格input Smooth_Method MA_Method2=MODE_EMA_; //指标平滑方法inputint Length2 = 5; //标平滑深度inputint Phase2=100; //标平滑参数input Applied_price_ IPC2=PRICE_CLOSE_; //平滑应用价格inputdouble Pow=5; //指数inputint Shift=0; //指标水平偏移柱线数//--- 指标参数inputuint StartPeriod=6; //初始周期inputuint Step_=6; //周期计算步进inputuint Total=36; //均线数量inputENUM_MA_METHOD MAType=MODE_EMA; //均线平滑类型inputENUM_APPLIED_PRICE MAPrice=PRICE_CLOSE; //均线应用价格inputint Shift1=0; //指标水平偏移柱线数测试结果:
图例. 21 策略 #10。测试结果
趋势跟随策略的测试和优化分析显示以下结果。
在大多数策略中, 总利润是在强劲或长时间的单边走势期间交易时斩获。
总亏损以及连续多次亏损交易所对应的区域是在横盘期间交易时。
在一些策略中, 由于止盈和止损相同且不可修改而造成亏损。
在某些情况下, 趋势识别滞后, 所以有必要改变时间帧。
请参阅下面的概要表格, 其中列出了本文中开发并使用的专家交易系统的名称, 以及辅助类和上述趋势跟随策略中使用的指标列表。所附存档包含所有列出的文件, 它们位于相应的文件夹中。为了它们能正确操作, 您只需将 MQL5 文件夹保存到终端根文件夹中即可。
文章中使用的程序:
# | 名称 | 类型 | 描述 |
---|---|---|---|
1 | Strategy_1.mq5 | 专家交易系统 | 策略 #1. ADXCloud 指标配合 RSI 直方条进行确认。 |
2 | Strategy_2.mql5 | 专家交易系统 | 策略 #2. 标准偏差趋势指标绘制为直方图, 配合 RVI 进行确认。 |
3 | Strategy_3.mq5 | 专家交易系统 | 策略 #3. 比尔·威廉姆斯的 AC 云图, 与熊市动力 - 牛市动力指标的组合。 |
4 | Strategy_4.mq5 | 专家交易系统 | 策略 #4. Ehlers 的重心配合平均价格速度指标进行确认。 |
5 | Strategy_5.mq5 | 专家交易系统 | 策略 #5. 复杂的二元波浪指标。 |
6 | Strategy_6.mq5 | 专家交易系统 | 策略 #6. 复杂的加权振荡器, 与莱曼目标的组合。 |
7 | Strategy_7.mq5 | 专家交易系统 | 策略 #7. Donchian 通道与 MACD 的组合, 其价格序列由威廉姆斯的 AO 值代替。 |
8 | Strategy_8.mq5 | 专家交易系统 | 策略 #8. Schaff 周期振荡器, 基于三个 Tyrone 级别进行确认。 |
9 | Strategy_9.mq5 | 专家交易系统 | 策略 #9. Keltner 通道绘制为直方图, 且 iTrend 指标绘制为云图。 |
10 | Strategy_10.mq5 | 专家交易系统 | 策略 #10. 平均价格变化动量和 MA FigurelliSeries 扇形。 |
11 | TradeFunctions.mqh | 代码库 | 交易函数类。 |
12 | smoothalgorithms.mqh | 代码库 | 指标中所使用的平滑算法类。 |
13 | adxcloud.mq5 | 指标 | 策略 #1 中所用。 |
14 | rsi_сolor.mq5 | 指标 | 策略 #1 中所用。 |
15 | colorstddev.mq5 | 指标 | 策略 #2 中所用。 |
16 | colorzerolagrvi.mq5 | 指标 | 策略 #2 中所用。 |
17 | Bear_Bulls_Power.mq5 | 指标 | 策略 #3 中所用。 |
18 | cronexao.mq5 | 指标 | 策略 #3 中所用。 |
19 | centerofgravityosma.mq5 | 指标 | 策略 #4 中所用。 |
20 | average_speed.mq5 | 指标 | 策略 #4 中所用。 |
21 | binarywave.mq5 | 指标 | 策略 #5 中所用。 |
22 | objective.mq5 | 指标 | 策略 #6 中所用。 |
23 | WeightOscillator.mq5 | 指标 | 策略 #6 中所用。 |
24 | donchian_channels_system.mq5 | 指标 | 策略 #7 中所用。 |
25 | cronexao.mq5 | 指标 | 策略 #7 中所用。 |
26 | schafftrendcycle.mq5 | 指标 | 策略 #8 中所用。 |
27 | tirone_levels_x3.mq5 | 指标 | 策略 #8 中所用。 |
28 | i-klprice.mq5 | 指标 | 策略 #9 中所用。 |
29 | i_trend.mq5 | 指标 | 策略 #9 中所用。 |
30 | averagechange.mq5 | 指标 | 策略 #10 中所用。 |
31 | figurelliseries.mq5 | 指标 | 策略 #10 中所用。 |