MQL5 中的20个交易信号

来源:互联网 发布:linux和windows 编辑:程序博客网 时间:2024/06/01 07:33

MQL5 中的20个交易信号

引言

汇客们力求发现市场价格规律,形成一套交易规则,以更好地把握买卖时机。为此,你需要学会使用交易信号。

交易信号会告诉汇客交易的点位,但不是必须执行的命令。附加的条件会正常地排除掉大多数交易信号。本文的主旨,是用MQL5编写最常用的交易信号。


1.我们知道的的交易信号

入市交易信号,由以下因素确定:
  • 均线交叉
  • 范围突破
  • 超买、超卖的基本随机范围的偏离
  • 通道边界跳跃
  • 通道边界突破
  • 趋势改变


2.如何编程?

有许多编程方法。例如,在OnStart(),OnTick() 等函数里面写码。更多细节可参见MetaEditor中的文档。但这一方法效率低,因为需要重复写码。我们要用的办法,是自已编写函数,供程序调用。

为了方便程序调用,把自定义函数写入外部的包含文件,名称叫SignalTrade,保存在...\MQL5\Include 目录。

各种交易信号样式不同,却有许多共同点,可以归纳成三种:

  • 买进信号
  • 卖出信号
  • 无信号
用一组枚举数值表示这些信号:

  • 1 - 买进
  • -1 - 卖出
  • 0 - 无信号

定义返回信号函数的原型。将函数按操作功能分成几部分,在函数开头设定变量,装入并检测编写的技术指标数据信息,以免程序运行出现不可预知的后果。
数据信息完成检测后,形成上述交易信号并将其返回。


int TradeSignal()  {   //--- zero means absence of signal   int sig=0;      //--- check the handles of indicators   //--- if all the handles are invalid, create them   //--- if the handles are valid, copy the values from indicators   //--- check the copied data   //--- in case of an error of copying, exit from the function   //--- perform the indexation of the array as a timeseries   //--- in case of an indexation error, exit from the function   //--- check conditions and set the value for sig    //--- return the trade signal   return(sig);  }

3. 交易信号20 种示例

我们用不同的技术指标得到交易信号。在MQL5中,通过特定函数使用技术指标,如 iMA,iAC,iMACD,iIchimoku。它们在客户端全局缓冲区,建立相应技术指标的副本。如果该副本使用的参数,与原本相同的,只增加链接数目,不建立副本

这些函数返回相应技术指标副本的 handle,并由其得到相应指标算出的数据。不同类型的指标,有1至5个内部缓冲区,以保存计算后的数据。这些缓冲的数据,可用函数CopyBuffer()复制。创建技术指标后,不能马上使用它的数据,所以,最好在初始化函数 OnInit() 中建立它的handle。函数iCustom()建立用户自定义指标,若成功则返回指标的handle。用户自定义指标最多可有512个缓冲,其中数据内容可通过handle与函数CopyBuffer()得到。          

我们按照原型TradeSignal() 为每个信号创建函数,并编号区别:TradeSignal_01() - TradeSignal_20()。可以通过基于平均线交叉信号的样例,仔细看看信号函数的结构,并以相似方式,编写其他信号。

3.1. 均线交叉

Figure 1. The intersection of two moving averages
图 1. 两条平均线交叉
用函数TradeSignal_01(),可得到两条平均线(Moving Averages)交叉的信号。快线的周期为8,慢线的周期为16。
本函数可以确定的唯一事实,就是均线的交叉,并将其值返回。按照上述规则和原型要求,函数是这样的:
int TradeSignal_01()  {//--- zero means that there is no signal   int sig=0;//--- check the handles of indicators   if(h_ma1==INVALID_HANDLE)//--- if the handle is invalid     {      //--- create is again                                                            h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);      //--- exit from the function      return(0);     }   else //--- if the handle is valid     {      //--- copy value of the indicator to the array      if(CopyBuffer(h_ma1,0,0,3,ma1_buffer)<3) //--- if the array of data is less than required         //--- exit from the function         return(0);      //--- set the indexation in the array as in a timeseries                                         if(!ArraySetAsSeries(ma1_buffer,true))         //--- in case of an indexation error, exit from the function         return(0);     }   if(h_ma2==INVALID_HANDLE)//--- if the handle is invalid     {      //--- create it again                                                            h_ma2=iMA(Symbol(),Period(),16,0,MODE_SMA,PRICE_CLOSE);      //--- exit from the function      return(0);     }   else //--- if the handle is valid      {      //--- copy values of the indicator to the array      if(CopyBuffer(h_ma2,0,0,2,ma2_buffer)<2) //--- if there is less data than required         //--- exit from the function         return(0);      //--- set the indexation in the array as in a timeseries                                         if(!ArraySetAsSeries(ma1_buffer,true))         //--- in case of an indexation error, exit from the function         return(0);     }//--- check the condition and set a value for the sig   if(ma1_buffer[2]<ma2_buffer[1] && ma1_buffer[1]>ma2_buffer[1])      sig=1;   else if(ma1_buffer[2]>ma2_buffer[1] && ma1_buffer[1]<ma2_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

逐段细看程序代码。函数开头有局部变量,保存信号类别,初始值为零,表示没有信号。
int sig=0;
接着,检测handle是否有效。如果无效,则创建它并返回,因为,指标的计算需要一些时间,这样可避免从指标缓冲复制数据时产生错误。
 if(h_ma1==INVALID_HANDLE)//--- if the handle is invalid     {      //--- create it again                                                            h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);      //--- exit from the function      return(0);     }

如果有效,则把数据复制到数组。为了分析的需要,复制的数据包括MA快线的最新3个柱子,和慢线的2个柱子。管理复制的函数是:
int  CopyBuffer(   int       indicator_handle,     // handle of an indicator   int       buffer_num,           // number of buffer of an indicator   int       start_pos,            // where to start from    int       count,                // amount to be copied   double    buffer[]              // an array to copy data to   );

检验复制的数据。若其比预定的数目少,则说明发生了复制错误,数据不能使用。还需将数组下标以时间顺序调整,由下列函数完成:
bool  ArraySetAsSeries(   void  array[],     // array by a link   bool  set          // true means that the indexation order is reversed   );

如果时序调整发生错误,数据不能使用,返回。
lse //--- if the handle is valid      {      //--- copy values of the indicator to the array      if(CopyBuffer(h_ma1,0,0,3,ma1_buffer)<3) //--- if there is less data than required         //--- exit from the function         return(0);      //--- set the indexation in the array like in a timeseries                                         if(!ArraySetAsSeries(ma1_buffer,true))         //--- in case of an indexation error, exit from the function         return(0);     }
好了,技术指标建成了,必要的信息得到了,我们开始生成交易信号。
为了消除当前数据信号的闪烁不定,只分析第1柱和第2柱的收盘价。
生成买进信号。取MA第2柱快线值,和第1柱慢线值,进行比较;再比较MA第1柱的快线值与第1柱的慢线值。如果第2柱的快线值小于第1柱的慢线值,并且,第1柱的快线值大于第1柱的慢线值,就说明MA快线上穿慢线,成为买进信号。于是,变量sig 赋值1。
卖出信号以相似方式生成。如果MA第2柱快线值大于第1柱慢线值,并且,第1柱快线值小于第1柱慢线值,说明MA快线下穿慢线。于是,变量 sig  赋值 -1。否则,说明没有买卖信号,sig  赋值 0。最后,将生成的信号类型值返回。
//--- check the condition and set a value for the sig   if(ma1_buffer[2]<ma2_buffer[1] && ma1_buffer[1]>ma2_buffer[1])      sig=1;   else if(ma1_buffer[2]>ma2_buffer[1] && ma1_buffer[1]<ma2_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);

3.2. 指标MACD的主线与信号线交叉



图 2. 指标MACD的主线与信号线交叉

调用函数 TradeSignal_02() ,得到指标MACD的信号线与主线交叉。信号线下穿主线,是买进的信号;信号线上穿主线,是卖出信号。否则,是无信号。

int TradeSignal_02()  {   int sig=0;   if(h_macd==INVALID_HANDLE)     {      h_macd=iMACD(Symbol(),Period(),12,26,9,PRICE_CLOSE);      return(0);     }   else     {      if(CopyBuffer(h_macd,0,0,2,macd1_buffer)<2)         return(0);      if(CopyBuffer(h_macd,1,0,3,macd2_buffer)<3)         return(0);      if(!ArraySetAsSeries(macd1_buffer,true))         return(0);      if(!ArraySetAsSeries(macd2_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(macd2_buffer[2]>macd1_buffer[1] && macd2_buffer[1]<macd1_buffer[1])      sig=1;   else if(macd2_buffer[2]<macd1_buffer[1] && macd2_buffer[1]>macd1_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.3. 突破价格通道边界


图 3.突破价格通道下边界和上边界

调用函数 TradeSignal_03() 可以得到向上或向下突破价格通道边界的信号。

价格向上穿越通道上边界,并且保持上升,是买进信号。价格下穿通道下边界,并且保持下降,是卖出信号。除此之外,为无信号。

与前两个函数不同,本函数需要一数组保存收盘价格。代码如下:

int  CopyClose(   string           symbol_name,       // symbol name   ENUM_TIMEFRAMES  timeframe,          // period   int              start_pos,         // where to start from    int              count,             // amount to be copied   double           close_array[]      // array for copying close prices to   );

int TradeSignal_03()  {   int sig=0;   if(h_pc==INVALID_HANDLE)     {      h_pc=iCustom(Symbol(),Period(),"Price Channel",22);      return(0);     }   else     {      if(CopyBuffer(h_pc,0,0,3,pc1_buffer)<3)         return(0);      if(CopyBuffer(h_pc,1,0,3,pc2_buffer)<3)         return(0);      if(CopyClose(Symbol(),Period(),0,2,Close)<2)         return(0);      if(!ArraySetAsSeries(pc1_buffer,true))         return(0);      if(!ArraySetAsSeries(pc2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the conditions and set a value for sig   if(Close[1]>pc1_buffer[2])      sig=1;   else if(Close[1]<pc2_buffer[2])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.4. 突破指标ADX自适应通道的边界


图 4. 突破指标ADX自适应通道的上下边界

调用函数 TradeSignal_04() 可以得到突破指标ADX指标自适应通道的上下边界信号。

价格向上穿越ADX通道上边界,并且保持上升,是买进信号。价格下穿通道下边界,并且保持下降,是卖出信号。除此之外,为无信号。
int TradeSignal_04()  {   int sig=0;   if(h_acadx==INVALID_HANDLE)     {      h_acadx=iCustom(Symbol(),Period(),"AdaptiveChannelADX",14);      return(0);     }   else     {      if(CopyBuffer(h_acadx,0,0,2,acadx1_buffer)<2)         return(0);      if(CopyBuffer(h_acadx,1,0,2,acadx2_buffer)<2)         return(0);      if(CopyClose(Symbol(),Period(),0,2,Close)<2)         return(0);      if(!ArraySetAsSeries(acadx1_buffer,true))         return(0);      if(!ArraySetAsSeries(acadx2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for the sig   if(Close[1]>acadx1_buffer[1])      sig=1;   else if(Close[1]<acadx2_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.5. 偏离随机指标的超买区、超卖区


图 5. 在随机指标的超买区或超卖区发生穿越

调用函数 TradeSignal_05() 可以得到价格偏离超买区或超卖区的信号。超买区临界值为80.超卖区临界值为20。

随机指标的K线或D线从低于20上升时,买进;从高于80下降时,卖出。


int TradeSignal_05()  {   int sig=0;   if(h_stoh==INVALID_HANDLE)     {      h_stoh=iStochastic(Symbol(),Period(),5,3,3,MODE_SMA,STO_LOWHIGH);      return(0);     }   else     {      if(CopyBuffer(h_stoh,0,0,3,stoh_buffer)<3)         return(0);      if(!ArraySetAsSeries(stoh_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(stoh_buffer[2]<20 && stoh_buffer[1]>20)      sig=1;   else if(stoh_buffer[2]>80 && stoh_buffer[1]<80)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.6. 偏离指标RSI的超买区或超卖区

图 6. 指标RSI穿越超买区或超卖区

调用函数 TradeSignal_06() 可以得到指标RSI偏离超买区或超卖区的信号。超买区的临界值为70,超卖区的临界值为30。

RSI从低于某值(通常为30)上升时为买点,从高于某值(通常为70)下降时为卖点。

int TradeSignal_06()  {   int sig=0;   if(h_rsi==INVALID_HANDLE)     {      h_rsi=iRSI(Symbol(),Period(),14,PRICE_CLOSE);      return(0);     }   else     {      if(CopyBuffer(h_rsi,0,0,3,rsi_buffer)<3)         return(0);      if(!ArraySetAsSeries(rsi_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(rsi_buffer[2]<30 && rsi_buffer[1]>30)      sig=1;   else if(rsi_buffer[2]>70 && rsi_buffer[1]<70)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);

3.7. 偏离指标CCI的超买区或超卖区

图 7. 偏离指标CCI的超买区或超卖区

调用函数 TradeSignal_07() 可以得到指标CCI偏离超买区或超卖区的信号。超买区的临界值为100,超卖区的临界值为-100。

CCI从低于-100上升时为买点,从高于100下降时为卖点。

int TradeSignal_07()  {   int sig=0;   if(h_cci==INVALID_HANDLE)     {      h_cci=iCCI(Symbol(),Period(),14,PRICE_TYPICAL);      return(0);     }   else     {      if(CopyBuffer(h_cci,0,0,3,cci_buffer)<3)         return(0);      if(!ArraySetAsSeries(cci_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(cci_buffer[2]<-100 && cci_buffer[1]>-100)      sig=1;   else if(cci_buffer[2]>100 && cci_buffer[1]<100)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.8. 偏离指标Williams的超买区或超卖区

图 8. 偏离指标 Williams的超买区或超卖区

Using the TradeSignal_08() function we will get the signal about exiting of the Williams % indicator from the zones ofoverbuying/overselling;levels for that zones are the levels with values -20 and -80.

We buy, as Williams % falls lower than level -80 and then rises above it. We sell, asWilliams % rises above level -20 and then falls below it.

调用函数 TradeSignal_08() 可以得到指标Williams偏离超买区或超卖区的信号。超买区的临界值为-20,超卖区的临界值为-80。

Williams从低于-80上升时为买点,从高于-20下降时为卖点。

int TradeSignal_08()  {   int sig=0;   if(h_wpr==INVALID_HANDLE)     {      h_wpr=iWPR(Symbol(),Period(),14);      return(0);     }   else     {      if(CopyBuffer(h_wpr,0,0,3,wpr_buffer)<3)         return(0);      if(!ArraySetAsSeries(wpr_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(wpr_buffer[2]<-80 && wpr_buffer[1]>-80)      sig=1;   else if(wpr_buffer[2]>-20 && wpr_buffer[1]<-20)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }int TradeSignal_08()  {   int sig=0;   if(h_wpr==INVALID_HANDLE)     {      h_wpr=iWPR(Symbol(),Period(),14);      return(0);     }   else     {      if(CopyBuffer(h_wpr,0,0,3,wpr_buffer)<3)         return(0);      if(!ArraySetAsSeries(wpr_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(wpr_buffer[2]<-80 && wpr_buffer[1]>-80)      sig=1;   else if(wpr_buffer[2]>-20 && wpr_buffer[1]<-20)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }int TradeSignal_08()  {   int sig=0;   if(h_wpr==INVALID_HANDLE)     {      h_wpr=iWPR(Symbol(),Period(),14);      return(0);     }   else     {      if(CopyBuffer(h_wpr,0,0,3,wpr_buffer)<3)         return(0);      if(!ArraySetAsSeries(wpr_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(wpr_buffer[2]<-80 && wpr_buffer[1]>-80)      sig=1;   else if(wpr_buffer[2]>-20 && wpr_buffer[1]<-20)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.9. 跳过指标 Bollinger 通道边界

图 9. 价格跳过指标 Bollinger 通道边界

调用函数 TradeSignal_09() 可以得到价格跳过指标 Bollinger 通道边界时的信号。

价格穿过或触碰上边界后回落,是卖出信号;价格穿过或触碰下边界,是买入信号。

int TradeSignal_09()  {   int sig=0;   if(h_bb==INVALID_HANDLE)     {      h_bb=iBands(Symbol(),Period(),20,0,2,PRICE_CLOSE);      return(0);     }   else     {      if(CopyBuffer(h_bb,1,0,2,bb1_buffer)<2)         return(0);      if(CopyBuffer(h_bb,2,0,2,bb2_buffer)<2)         return(0);      if(CopyClose(Symbol(),Period(),0,3,Close)<3)         return(0);      if(!ArraySetAsSeries(bb1_buffer,true))         return(0);      if(!ArraySetAsSeries(bb2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[2]<=bb2_buffer[1] && Close[1]>bb2_buffer[1])      sig=1;   else if(Close[2]>=bb1_buffer[1] && Close[1]<bb1_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.10. 跳离指标SDC(标准偏离通道)的边界

图 10.价格跳离指标SDC(标准偏离通道)的边界

调用函数 TradeSignal_10() 可以得到价格跳离指标SDC(标准偏离通道)的边界时的信号。

价格穿过或触碰上边界后回落,是卖出信号;价格穿过或触碰下边界,是买入信号。
int TradeSignal_10()  {   int sig=0;   if(h_sdc==INVALID_HANDLE)     {      h_sdc=iCustom(Symbol(),Period(),"StandardDeviationChannel",14,0,MODE_SMA,PRICE_CLOSE,2.0);      return(0);     }   else     {      if(CopyBuffer(h_sdc,0,0,2,sdc1_buffer)<2)         return(0);      if(CopyBuffer(h_sdc,1,0,2,sdc2_buffer)<2)         return(0);      if(CopyClose(Symbol(),Period(),0,3,Close)<3)         return(0);      if(!ArraySetAsSeries(sdc1_buffer,true))         return(0);      if(!ArraySetAsSeries(sdc2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[2]<=sdc2_buffer[1] && Close[1]>sdc2_buffer[1])      sig=1;   else if(Close[2]>=sdc1_buffer[1] && Close[1]<sdc1_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.11. 跃过 Price Channel 指标的通道边界

图 11. 价格跃过 Price Channel 指标的通道边界

调用函数 TradeSignal_11() 可以得到价格跃过 Price Channel 指标的通道边界时的信号。

价格穿过或触碰上边界后回落,是卖出信号;价格穿过或触碰下边界,是买入信号。

int TradeSignal_11()  {   int sig=0;   if(h_pc==INVALID_HANDLE)     {      h_pc=iCustom(Symbol(),Period(),"Price Channel",22);      return(0);     }   else     {      if(CopyBuffer(h_pc,0,0,4,pc1_buffer)<4)         return(0);      if(CopyBuffer(h_pc,1,0,4,pc2_buffer)<4)         return(0);      if(CopyClose(Symbol(),Period(),0,3,Close)<3)         return(0);      if(!ArraySetAsSeries(pc1_buffer,true))         return(0);      if(!ArraySetAsSeries(pc2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[1]>pc2_buffer[2] && Close[2]<=pc2_buffer[3])      sig=1;   else if(Close[1]<pc1_buffer[2] && Close[2]>=pc1_buffer[3])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.12. 跃过 Envelopes 指标的通道边界

图 12. 价格跃过 Envelopes 指标的通道边界

调用函数 TradeSignal_12() 可以得到价格跃过 Envelopes指标的通道边界时的信号。
价格穿过或触碰上边界后回落,是卖出信号;价格穿过或触碰下边界,是买入信号。
int TradeSignal_12()  {   int sig=0;   if(h_env==INVALID_HANDLE)     {      h_env=iEnvelopes(Symbol(),Period(),28,0,MODE_SMA,PRICE_CLOSE,0.1);      return(0);     }   else     {      if(CopyBuffer(h_env,0,0,2,env1_buffer)<2)         return(0);      if(CopyBuffer(h_env,1,0,2,env2_buffer)<2)         return(0);      if(CopyClose(Symbol(),Period(),0,3,Close)<3)         return(0);      if(!ArraySetAsSeries(env1_buffer,true))         return(0);      if(!ArraySetAsSeries(env2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[2]<=env2_buffer[1] && Close[1]>env2_buffer[1])      sig=1;   else if(Close[2]>=env1_buffer[1] && Close[1]<env1_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.13. 突破 Donchian 指标的通道

图 13. 突破 Donchian 指标的通道

调用函数 TradeSignal_13() 可以得到价格穿过或触碰 Donchian 指标通道时的信号。

价格穿过Donchian上通道,保持在其上方时,是买入信号;价格穿过下通道,保持在其下方时,是卖出信号。
int TradeSignal_13()  {   int sig=0;   if(h_dc==INVALID_HANDLE)     {      h_dc=iCustom(Symbol(),Period(),"Donchian Channels",24,3,-2);      return(0);     }   else     {      if(CopyBuffer(h_dc,0,0,3,dc1_buffer)<3)         return(0);      if(CopyBuffer(h_dc,1,0,3,dc2_buffer)<3)         return(0);      if(CopyClose(Symbol(),Period(),0,2,Close)<2)         return(0);      if(!ArraySetAsSeries(dc1_buffer,true))         return(0);      if(!ArraySetAsSeries(dc2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[1]>dc1_buffer[2])      sig=1;   else if(Close[1]<dc2_buffer[2])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.14. 突破 Silver-Channel 指标通道

图 14. 突破 Silver-Channel 指标通道边界

调用 TradeSignal_14() 可以得到穿跃 Silver-Channel指标边界的信号。 Silver-Channel 指标画有8条边界,也可看作支撑线或阻力线。其中2条中线,用于产生信号。

价格穿跃Silver-Channel上通道,并保持在其上方时,是买入信号;穿跃下通道并保持在其下方时,是卖出信号。
int TradeSignal_14()  {   int sig=0;   if(h_sc==INVALID_HANDLE)     {      h_sc=iCustom(Symbol(),Period(),"Silver-channels",26,38.2,23.6,0,61.8);      return(0);     }   else     {      if(CopyBuffer(h_sc,0,0,2,sc1_buffer)<2)         return(0);      if(CopyBuffer(h_sc,1,0,2,sc2_buffer)<2)         return(0);      if(CopyClose(Symbol(),Period(),0,3,Close)<3)         return(0);      if(!ArraySetAsSeries(sc1_buffer,true))         return(0);      if(!ArraySetAsSeries(sc2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[2]<sc1_buffer[1] && Close[1]>sc1_buffer[1])      sig=1;   else if(Close[2]>sc2_buffer[1] && Close[1]<sc2_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.15. 突破 Gallagher 指标通道

图 15. 突破 Gallagher 指标通道

TradeSignal_15() 可以返回价格穿跃 Gallagher 指标通道时的信号。形成这个通道的数据,是10天价格的最大值和最小值。 

价格穿跃Gallagher上通道,并保持在其上方时,是买入信号;穿跃下通道并保持在其下方时,是卖出信号。
int TradeSignal_15()  {   int sig=0;   if(h_gc==INVALID_HANDLE)     {      h_gc=iCustom(Symbol(),Period(),"PriceChannelGalaher");      return(0);     }   else     {      if(CopyBuffer(h_gc,0,0,3,gc1_buffer)<3)         return(0);      if(CopyBuffer(h_gc,1,0,3,gc2_buffer)<3)         return(0);      if(CopyClose(Symbol(),Period(),0,2,Close)<2)         return(0);      if(!ArraySetAsSeries(gc1_buffer,true))         return(0);      if(!ArraySetAsSeries(gc2_buffer,true))         return(0);      if(!ArraySetAsSeries(Close,true))         return(0);     }//--- check the condition and set a value for sig   if(Close[1]>gc1_buffer[2])      sig=1;   else if(Close[1]<gc2_buffer[2])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.16. 反映趋势改变的指标 NRTR

图 16. 用NRTR指标确认趋势变化

TradeSignal_16() 返回 NRTR 指标给出的趋势变化信号。

NRTR 指标显示上升趋势时,是买入信号;显示下降趋势时,是卖出信号。

int TradeSignal_16()  {   int sig=0;   if(h_nrtr==INVALID_HANDLE)     {      h_nrtr=iCustom(Symbol(),Period(),"NRTR",40,2.0);      return(0);     }   else     {      if(CopyBuffer(h_nrtr,0,0,2,nrtr1_buffer)<2)         return(0);      if(CopyBuffer(h_nrtr,1,0,2,nrtr2_buffer)<2)         return(0);      if(!ArraySetAsSeries(nrtr1_buffer,true))         return(0);      if(!ArraySetAsSeries(nrtr2_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(nrtr1_buffer[1]>0)      sig=1;   else if(nrtr2_buffer[1]>0)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.17. 鳄鱼(Alligator)指标的趋势变化

图 17. 鳄鱼(Alligator)指标的趋势变化

TradeSignal_17() 发出鳄鱼指标趋势改变的信号。

鳄鱼的颌、齿、唇闭合扭结时,鳄鱼进入睡眠。随着睡眠的深入,鳄鱼越来越饿,直到它醒来。它醒后的第一件事,是张嘴打哈欠。然后,嗅寻牛或熊的味道,开始打猎。鳄鱼吃饱后,对付饭钱没有兴趣(平衡线聚拢),这就是获利收手的时候。
int TradeSignal_17()  {   int sig=0;   if(h_al==INVALID_HANDLE)     {      h_al=iAlligator(Symbol(),Period(),13,0,8,0,5,0,MODE_SMMA,PRICE_MEDIAN);      return(0);     }   else     {      if(CopyBuffer(h_al,0,0,2,al1_buffer)<2)         return(0);      if(CopyBuffer(h_al,1,0,2,al2_buffer)<2)         return(0);      if(CopyBuffer(h_al,2,0,2,al3_buffer)<2)         return(0);      if(!ArraySetAsSeries(al1_buffer,true))         return(0);      if(!ArraySetAsSeries(al2_buffer,true))         return(0);      if(!ArraySetAsSeries(al3_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(al3_buffer[1]>al2_buffer[1] && al2_buffer[1]>al1_buffer[1])      sig=1;   else if(al3_buffer[1]<al2_buffer[1] && al2_buffer[1]<al1_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.18. AMA指标的趋势改变

图 18.AMA指标的趋势改变

TradeSignal_18() 发出AMA指标趋势改变的信号。

AMA 指标上扬时,是买入信号;下垂时,是卖出信号。

int TradeSignal_18()  {   int sig=0;   if(h_ama==INVALID_HANDLE)     {      h_ama=iAMA(Symbol(),Period(),9,2,30,0,PRICE_CLOSE);      return(0);     }   else     {      if(CopyBuffer(h_ama,0,0,3,ama_buffer)<3)         return(0);      if(!ArraySetAsSeries(ama_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(ama_buffer[2]<ama_buffer[1])      sig=1;   else if(ama_buffer[2]>ama_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.19. 指标 Awesome Oscillator (AO)以颜色表示趋势变化

图 19. 用指标 Awesome Oscillator 确认趋势变化

TradeSignal_19() 根据指标 Awesome Oscillator 直方图颜色的变化,发出趋势变化的信号。

MQL5的功能之一,是创建指标缓冲。缓冲保存线段颜色的索引值。,索引值由语句指令 #property indicator_colorN 设定。指标 Awesome Oscillator 绿色直方图为买入信号;变为红色时,为卖出信号。

int TradeSignal_19()  {   int sig=0;   if(h_ao==INVALID_HANDLE)     {      h_ao=iAO(Symbol(),Period());      return(0);     }   else     {      if(CopyBuffer(h_ao,1,0,20,ao_buffer)<20)         return(0);      if(!ArraySetAsSeries(ao_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(ao_buffer[1]==0)      sig=1;   else if(ao_buffer[1]==1)      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

3.20. 指标Ichimoku的趋势变化

图 20.用指标 Ichimoku 确认趋势变化

TradeSignal_20() 根据指标 Ichimoku 趋势变化,发出信号。指标转折线与基准线的交叉,反映着趋势的变化。

趋势线上穿基准线,是买入信号;下穿时是卖出信号。
int TradeSignal_20()  {   int sig=0;   if(h_ich==INVALID_HANDLE)     {      h_ich=iIchimoku(Symbol(),Period(),9,26,52);      return(0);     }   else     {      if(CopyBuffer(h_ich,0,0,2,ich1_buffer)<2)         return(0);      if(CopyBuffer(h_ich,1,0,2,ich2_buffer)<2)         return(0);      if(!ArraySetAsSeries(ich1_buffer,true))         return(0);      if(!ArraySetAsSeries(ich2_buffer,true))         return(0);     }//--- check the condition and set a value for sig   if(ich1_buffer[1]>ich2_buffer[1])      sig=1;   else if(ich1_buffer[1]<ich2_buffer[1])      sig=-1;   else sig=0;//--- return the trade signal   return(sig);  }

4. 把多个信号攒成技术指标

有了一堆现成的指标,可以把它们汇集成为一个指标。在已有模板上,可以从任何指标接收信号,并且按条件使用准确信号。
写一个指标,不修改其内建参数。指标信号,以键头形式表示,显示在K线图的右边。键头向上,买入;向下,卖出;十字型,无信号。键头采用标准的Wingdings字体。还需要几个函数显示指标信号。这些函数整合到名叫LibFunctions 的库程序中。
在未来的指标文件开头,有 #include 和 #import 语句,以引入与图形显示相关的文件和函数。还有全局变量,以保存从指标收到的信号类型值。

//--- Connect necessary libraries of functions#include <SignalTrade.mqh>//--- Import of functions from the LibFunctions library#import "LibFunctions.ex5"void SetLabel(string nm,string tx,ENUM_BASE_CORNER cn,ENUM_ANCHOR_POINT cr,int xd,int yd,string fn,int fs,double yg,color ct);string arrow(int sig);color Colorarrow(int sig);#import//+------------------------------------------------------------------+//| Declare variables for storing signals of indicators              |//+------------------------------------------------------------------+int SignalMA;int SignalMACD;int SignalPC;int SignalACADX;int SignalST;int SignalRSI;int SignalCCI;int SignalWPR;int SignalBB;int SignalSDC;int SignalPC2;int SignalENV;int SignalDC;int SignalSC;int SignalGC;int SignalNRTR;int SignalAL;int SignalAMA;int SignalAO;int SignalICH;

前面说过,各指标装入终端是一次性的产生引用的指针(handle),因此,这一过程需在程序开始一次性运行的函数 OnInit() 中完成。
int OnInit()  {//--- create indicator handles   h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);   h_ma2=iMA(Symbol(),Period(),16,0,MODE_SMA,PRICE_CLOSE);   h_macd=iMACD(Symbol(),Period(),12,26,9,PRICE_CLOSE);   h_pc=iCustom(Symbol(),Period(),"Price Channel",22);   h_acadx=iCustom(Symbol(),Period(),"AdaptiveChannelADX",14);   h_stoh=iStochastic(Symbol(),Period(),5,3,3,MODE_SMA,STO_LOWHIGH);   h_rsi=iRSI(Symbol(),Period(),14,PRICE_CLOSE);   h_cci=iCCI(Symbol(),Period(),14,PRICE_TYPICAL);   h_wpr=iWPR(Symbol(),Period(),14);   h_bb=iBands(Symbol(),Period(),20,0,2,PRICE_CLOSE);   h_sdc=iCustom(Symbol(),Period(),"StandardDeviationChannel",14,0,MODE_SMA,PRICE_CLOSE,2.0);   h_env=iEnvelopes(Symbol(),Period(),28,0,MODE_SMA,PRICE_CLOSE,0.1);   h_dc=iCustom(Symbol(),Period(),"Donchian Channels",24,3,-2);   h_sc=iCustom(Symbol(),Period(),"Silver-channels",26,38.2,23.6,0,61.8);   h_gc=iCustom(Symbol(),Period(),"PriceChannelGalaher");   h_nrtr=iCustom(Symbol(),Period(),"NRTR",40,2.0);   h_al=iAlligator(Symbol(),Period(),13,0,8,0,5,0,MODE_SMMA,PRICE_MEDIAN);   h_ama=iAMA(Symbol(),Period(),9,2,30,0,PRICE_CLOSE);   h_ao=iAO(Symbol(),Period());   h_ich=iIchimoku(Symbol(),Period(),9,26,52);   return(0);  }
主要的计算,全部由函数 OnCalculate() 进行,内有其他全部代码。
 
int OnCalculate(const int rates_total,                const int prev_calculated,                const datetime &time[],                const double &open[],                const double &high[],                const double &low[],                const double &close[],                const long &tick_volume[],                const long &volume[],                const int &spread[])  {//---assign the signal value to the variable   SignalMA    = TradeSignal_01();   SignalMACD  = TradeSignal_02();   SignalPC    = TradeSignal_03();   SignalACADX = TradeSignal_04();   SignalST    = TradeSignal_05();   SignalRSI   = TradeSignal_06();   SignalCCI   = TradeSignal_07();   SignalWPR   = TradeSignal_08();   SignalBB    = TradeSignal_09();   SignalSDC   = TradeSignal_10();   SignalPC2   = TradeSignal_11();   SignalENV   = TradeSignal_12();   SignalDC    = TradeSignal_13();   SignalSC    = TradeSignal_14();   SignalGC    = TradeSignal_15();   SignalNRTR  = TradeSignal_16();   SignalAL    = TradeSignal_17();   SignalAMA   = TradeSignal_18();   SignalAO    = TradeSignal_19();   SignalICH   = TradeSignal_20();//--- draw graphical objects on the chart in the upper left corner   int size=((int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS)/22);   int i=0;   int x=10;   int y=0;   int fz=size-4;   y+=size;   SetLabel("arrow"+(string)i,arrow(SignalMA),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalMA));   x+=size;   SetLabel("label"+(string)i,"Moving Average",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalMACD),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalMACD));   x+=size;   SetLabel("label"+(string)i,"MACD",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalPC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalPC));   x+=size;   SetLabel("label"+(string)i,"Price Channell",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalACADX),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalACADX));   x+=size;   SetLabel("label"+(string)i,"Adaptive Channel ADX",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalST),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalST));   x+=size;   SetLabel("label"+(string)i,"Stochastic Oscillator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalRSI),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalRSI));   x+=size;   SetLabel("label"+(string)i,"RSI",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalCCI),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalCCI));   x+=size;   SetLabel("label"+(string)i,"CCI",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalWPR),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalWPR));   x+=size;   SetLabel("label"+(string)i,"WPR",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalBB),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalBB));   x+=size;   SetLabel("label"+(string)i,"Bollinger Bands",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalSDC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalSDC));   x+=size;   SetLabel("label"+(string)i,"StDevChannel",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalPC2),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalPC2));   x+=size;   SetLabel("label"+(string)i,"Price Channell 2",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalENV),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalENV));   x+=size;   SetLabel("label"+(string)i,"Envelopes",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalDC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalDC));   x+=size;   SetLabel("label"+(string)i,"Donchian Channels",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalSC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalSC));   x+=size;   SetLabel("label"+(string)i,"Silver-channels",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalGC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalGC));   x+=size;   SetLabel("label"+(string)i,"Galaher Channel",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalNRTR),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalNRTR));   x+=size;   SetLabel("label"+(string)i,"NRTR",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalAL),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAL));   x+=size;   SetLabel("label"+(string)i,"Alligator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalAMA),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAMA));   x+=size;   SetLabel("label"+(string)i,"AMA",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalAO),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAO));   x+=size;   SetLabel("label"+(string)i,"Awesome oscillator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   i++;y+=size;x=10;   SetLabel("arrow"+(string)i,arrow(SignalICH),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalICH));   x+=size;   SetLabel("label"+(string)i,"Ichimoku Kinko Hyo",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);   return(rates_total);  }


新指标做好了。最后是它显示的画面。

5. 攒个炒汇机器人

可以用类似的办法造个EA机器人,并将指标信号显示在K线图中。我们用图形控件,做个小信息系统。它能选取需要的指标,并从图形界面设置指标参数。


我们不直接讨论图形界面的实现,可参见文章 Creating Active Control Panels in MQL5 for Trading 。

为了通过图形界面改变指标参数设置,需要改进库程序SignalTrade.mqh 并存为 SignalTradeExp.mqh。
首先,需要为保存这些参数的设置,增加变量。

//--- input parameters Moving Averageint                periodma1=8;int                periodma2=16;ENUM_MA_METHOD     MAmethod=MODE_SMA;ENUM_APPLIED_PRICE MAprice=PRICE_CLOSE;//--- input parameters MACDint                FastMACD=12;int                SlowMACD=26;int                MACDSMA=9;ENUM_APPLIED_PRICE MACDprice=PRICE_CLOSE;//--- input parameters Price Channelint                PCPeriod=22;//--- input parameters Adaptive Channel ADXint                ADXPeriod=14;//--- input parameters Stochastic Oscillatorint                SOPeriodK=5;int                SOPeriodD=3;int                SOslowing=3;ENUM_MA_METHOD     SOmethod=MODE_SMA;ENUM_STO_PRICE     SOpricefield=STO_LOWHIGH;//--- input parameters RSIint                RSIPeriod=14;ENUM_APPLIED_PRICE RSIprice=PRICE_CLOSE;//--- input parameters CCIint                CCIPeriod=14;ENUM_APPLIED_PRICE CCIprice=PRICE_TYPICAL;//--- input parameters WPRint                WPRPeriod=14;//--- input parameters Bollinger Bandsint                BBPeriod=20;double             BBdeviation=2.0;ENUM_APPLIED_PRICE BBprice=PRICE_CLOSE;//--- input parameters Standard Deviation Channelint                SDCPeriod=14;double             SDCdeviation=2.0;ENUM_APPLIED_PRICE SDCprice=PRICE_CLOSE;ENUM_MA_METHOD     SDCmethod=MODE_SMA;//--- input parameters Price Channel 2int                PC2Period=22;//--- input parameters Envelopesint                ENVPeriod=14;double             ENVdeviation=0.1;ENUM_APPLIED_PRICE ENVprice=PRICE_CLOSE;ENUM_MA_METHOD     ENVmethod=MODE_SMA;//--- input parameters Donchian Channelsint                DCPeriod=24;int                DCExtremes=3;int                DCMargins=-2;//--- input parameters Silver-channelsint                SCPeriod=26;double             SCSilvCh=38.2;double             SCSkyCh=23.6;double             SCFutCh=61.8;//--- input parameters NRTRint                NRTRPeriod   =  40;double             NRTRK        =  2.0;//--- input parameters Alligatorint                ALjawperiod=13;int                ALteethperiod=8;int                ALlipsperiod=5;ENUM_MA_METHOD     ALmethod=MODE_SMMA;ENUM_APPLIED_PRICE ALprice=PRICE_MEDIAN;//--- input parameters AMAint                AMAperiod=9;int                AMAfastperiod=2;int                AMAslowperiod=30;ENUM_APPLIED_PRICE AMAprice=PRICE_CLOSE;//--- input parameters Ichimoku Kinko Hyoint                IKHtenkansen=9;int                IKHkijunsen=26;int                IKHsenkouspanb=52;
用这些变量值,替换指标参数值。其他的保持不变。
h_ma1=iMA(Symbol(),Period(),periodma1,0,MAmethod,MAprice);
重要的是充分利用计算机内存:改变参数设置时,应卸载旧设置,载入新设置。这由下面的函数完成:
bool  IndicatorRelease(   int       indicator_handle,     // indicator handle   );
if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam=="PIPSetEditMA2")     {      periodma2=(int)ObjectGetString(0,"PIPSetEditMA2",OBJPROP_TEXT);      ObjectSetString(0,"PIPSetEditMA2",OBJPROP_TEXT,(string)periodma2);      //--- unload old copy of the indicator      IndicatorRelease(h_ma2);      //--- create new copy of the indicator      h_ma2=iMA(Symbol(),Period(),periodma2,0,MAmethod,MAprice);      ChartRedraw();     }

结论

至此,我们学会了读取指标信息,并将其传递给EA机器人。由此,你可以从任何指标获取信号。

注意

  • 应当复制到目录...\MQL5\Indicators 的文件有:SignalTrade.mq5, AdaptiveChannelADX.mq5, Donchian Channels.mq5, NRTR.mq5, Price Channel.mq5, PriceChannelGalaher.mq5, Silver-channels.mq5, StandardDeviationChannel.mq5
  • 文件 SignalTrade.mqh and SignalTradeExp.mqh 应该复制到目录 ...\MQL5\Include
  • 文件 LibFunctions.mq5 应该复制到目录 ...\MQL5\Libraries
  • 文件 ExpSignalTrade.mq5 应该复制到目录 ...\MQL5\Experts.
附带文件
indicators.zip(8.9 KB)
expsignaltrade.mq5(165.84 KB)
libfunctions__1.mq5(5.69 KB)
signaltrade.mq5(10.57 KB)
signaltrade.mqh(20.16 KB)
signaltradeexp.mqh(23.26 KB)


0 0