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. 均线交叉本函数可以确定的唯一事实,就是均线的交叉,并将其值返回。按照上述规则和原型要求,函数是这样的:
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的主线与信号线交叉
调用函数 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指标自适应通道的上下边界信号。
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 指标通道时的信号。
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条中线,用于产生信号。
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天价格的最大值和最小值。
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. 攒个炒汇机器人
我们不直接讨论图形界面的实现,可参见文章 Creating Active Control Panels in MQL5 for Trading 。
首先,需要为保存这些参数的设置,增加变量。
//--- 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.
- MQL5 中的20个交易信号
- MQL5源码:智能交易脚本EA结构解读
- MQL5参考
- MQL5---类
- 趋势交易中的秘密
- 网络中的商标交易
- Hadoop扩展过程中的7个危险信号
- 漫谈游戏中的交易逻辑
- 期权交易中的做市商制度
- MQL5:zig-zag 指标
- MQL5 命令行编译
- MQL5-字符串数据
- 利用MACD指标进阶使用技巧计算交易信号
- 27个危险信号
- 14个预警信号
- 陈耀硕:黄金交易规避4个风险
- 交易
- 交易
- HTML5 Canvas 第二篇
- 网络编程学习_设计模式_半同步半异步模式
- Oracle 多进程更新同一个表
- 最常用的设计模式
- Support Library Features
- MQL5 中的20个交易信号
- 重定向浅淡
- Android--去除EditText边框,添加下划线,
- 【ios 汇总 - UI 视图布局 】
- 文字向上无缝滚动
- uva 1467 - Installations( 贪心+暴力)
- 在应用程序中使用Spring启动嵌入式Jetty并让Web程序共享同一个Application Context(一)
- java中面向对象的思想
- Android多线程之AnsyncTask