//+------------------------------------------------------------------+ //| Custom MACD.mq4 | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, Herb Spirit, Inc." #property link "http://www.herbspirit.com/mql" //---- #define INDICATOR_NAME "MACD_Colored" #define INDICATOR_VERSION "v103" // this version implements various signals and alerts //---- indicator settings #property indicator_separate_window #property indicator_buffers 3 #property indicator_color1 Lime #property indicator_color2 Red #property indicator_color3 Silver #property indicator_style3 STYLE_DOT #property indicator_level1 45 #property indicator_level2 30 #property indicator_level3 15 #property indicator_level4 -15 #property indicator_level5 -30 #property indicator_level6 -45 #property indicator_levelcolor Gray #property indicator_levelstyle STYLE_DOT //---- indicator parameters extern string Alert_On="ANY"; extern bool EMail_Alert=true; extern int Max_Alerts=3; extern int Alert_Before_Minutes=15; extern int Alert_Every_Minutes=5; extern bool ShowSignal=true; int FastEMA=5; int SlowEMA=13; extern int FontSize=8; extern color FontColor=Silver; //---- indicator buffers double MacdBuffer[]; double MacdBufferUp[]; double MacdBufferDn[]; double SignalBuffer[]; //---- string shortname; datetime alertbartime,nextalerttime; int alertcount; string alerttype[]={"RT","RB","VT","VB","TC","ZB"}; int minlevel[]={5,10,15,-5,-10,-15}; int hourlevel[]={45,30,15,-15,-30,-45}; int daylevel[]={90,60,30,-30,-60,-90}; datetime nextbartime; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- drawing settings SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexStyle(1,DRAW_HISTOGRAM); SetIndexStyle(2,DRAW_LINE); switch(Period()) { case PERIOD_M1: case PERIOD_M5: case PERIOD_M15: case PERIOD_M30: for(int i=0;i0) counted_bars--; int limit=Bars-counted_bars; if(counted_bars==0) limit-=1+1; //if(Time[0]!=nextbartime) { int xsize=ArraySize(MacdBufferUp); ArrayResize(MacdBuffer,xsize); // nextbartime=Time[0]; } for(int i=0;iMacdBuffer[i+1]) { MacdBufferUp[i]=MacdBuffer[i]; MacdBufferDn[i]=0; } else { MacdBufferDn[i]=MacdBuffer[i]; MacdBufferUp[i]=0; } if(ShowSignal || firstsignal) { if(!ShowTops(i)) { if(ShowBottoms(i)) firstsignal=false; } else firstsignal=false; } } //---- signal line counted in the 2-nd buffer for(i=0; ipriMACD) { pips--; close[0]-=Point; curMACD=(iMAOnArray(close,0,FastEMA,0,MODE_EMA,0)- iMAOnArray(close,0,SlowEMA,0,MODE_EMA,0))/Point; } } string objname=shortname+","+Symbol()+","+Period()+",pips"; if(ObjectFind(objname)<0) ObjectCreate(objname,OBJ_TEXT, WindowFind(shortname), Time[0]+Period()*60,MacdBuffer[0]/2); else ObjectMove(objname,0,Time[0]+Period()*60,MacdBuffer[0]/2); if(pips!=0) ObjectSetText(objname,DoubleToStr(pips,0),FontSize,"Courier",FontColor); else ObjectSetText(objname," ",FontSize,"Courier",FontColor); //---- send alerts if(Max_Alerts==0) return(0); string alertmsg; if(!IsAlert(alertmsg)) return(0); alertmsg=Symbol()+","+Period()+" : "+alertmsg; Alert(alertmsg); if(EMail_Alert) SendMail("MACD Colored Alert",TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS)+" : "+alertmsg); Print(alertmsg); //---- done return(0); } //+------------------------------------------------------------------+ bool ShowTops(int shift) { // check for basic pattern string objname=SetPatternObjectName(shift); bool basicpattern=(MacdBuffer[shift]diff1); if(MacdBuffer[shift+2]!=0) double ratio2=MathAbs(MacdBuffer[shift+3]/MacdBuffer[shift+2]); else ratio2=1000; if(MacdBuffer[shift+1]!=0) double ratio1=MathAbs(MacdBuffer[shift+2]/MacdBuffer[shift+1]); else ratio1=1000; if(MacdBuffer[shift+1]!=0) double ratio0=MathAbs(MacdBuffer[shift]/MacdBuffer[shift+1]); else ratio0=1000; roundpattern=(roundpattern || MathAbs(ratio0-ratio1)>0.1); // 0 and 2 are close to each other double minratio=0.8; if(MacdBuffer[shift+1]<10 && MacdBuffer[shift+1]>-10) minratio=0.6; bool ratioround=(ratio0>minratio && ratio1>minratio && ratio2>minratio); bool ratiovtop=(MathAbs(ratio0-ratio1)<0.3); string patname=" "; if(ratiovtop) patname="VT"; // default is v-top if(ratioround && roundpattern) if(MacdBuffer[shift+1]<5) return(false); else patname="RT"; // round top pattern if(patname==" ") return(false); if(MacdBuffer[shift+1]<3 && MacdBuffer[shift+1]>-3) patname="ZB"; // zero line bounce if(MacdBuffer[shift+1]<=-3) patname="TC"; // trend continue bool strongpattern=(MacdBuffer[shift+4]10); if(ObjectFind(objname)<0) { ObjectCreate(objname,OBJ_TEXT, WindowFind(shortname), Time[shift+1],0); } if(strongpattern) ObjectSetText(objname,patname,FontSize+2,"Arial",FontColor); else ObjectSetText(objname,patname,FontSize,"Arial",FontColor); return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool ShowBottoms(int shift) { // check for basic pattern string objname=SetPatternObjectName(shift); string objdesc=ObjectDescription(objname); bool basicpattern=(MacdBuffer[shift]>MacdBuffer[shift+1] && MacdBuffer[shift+2]>MacdBuffer[shift+1] && MacdBuffer[shift+3]>MacdBuffer[shift+2]); if(!basicpattern) { ObjectDelete(objname); return(false); } double diff2=MathAbs(MacdBuffer[shift+2]-MacdBuffer[shift+3]); double diff1=MathAbs(MacdBuffer[shift+1]-MacdBuffer[shift+2]); double diff0=MathAbs(MacdBuffer[shift]-MacdBuffer[shift+1]); bool roundpattern=(diff2>diff1);//&&diff2>diff0); if(MacdBuffer[shift+3]!=0) double ratio2=MathAbs(MacdBuffer[shift+2]/MacdBuffer[shift+3]); else ratio2=1000; if(MacdBuffer[shift+2]!=0) double ratio1=MathAbs(MacdBuffer[shift+1]/MacdBuffer[shift+2]); else ratio1=1000; if(MacdBuffer[shift]!=0) double ratio0=MathAbs(MacdBuffer[shift+1]/MacdBuffer[shift]); else ratio0=1000; roundpattern=(roundpattern || MathAbs(ratio0-ratio1)>0.1); // 0 and 2 are close to each other double minratio=0.8; if(MacdBuffer[shift+1]<10 && MacdBuffer[shift+1]>-10) minratio=0.6; bool ratioround=(ratio0>minratio && ratio1>minratio && ratio2>minratio); bool ratiovtop=(MathAbs(ratio0-ratio1)<0.3); string patname=" "; if(ratiovtop) patname="VB"; // default is v-top if(ratioround && roundpattern) if(MacdBuffer[shift+1]>-5) return(false); else patname="RB"; // round top pattern if(patname==" ") return(false); if(MacdBuffer[shift+1]<3 && MacdBuffer[shift+1]>-3) patname="ZB"; // zero line bounce if(MacdBuffer[shift+1]>=3) patname="TC"; // trend continue bool strongpattern=(MacdBuffer[shift+4]>MacdBuffer[shift+3] && MacdBuffer[shift+5]>MacdBuffer[shift+4] && MacdBuffer[shift+1]>10); if(ObjectFind(objname)<0) ObjectCreate(objname,OBJ_TEXT, WindowFind(shortname), Time[shift+1],0); if(strongpattern) ObjectSetText(objname,patname,FontSize+2,"Arial",FontColor); else ObjectSetText(objname,patname,FontSize,"Arial",FontColor); return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsAlert(string &alertmsg) { if(ArraySize(alerttype)==0) return(false); if(alerttype[0]=="") return(false); int shift; if(TimeCurrent()nextalerttime) { if(alertcount0) alertmsg=timetoalert+" minutes since "+alertname; else alertmsg=alertname; if(alertcount=97&&char1<=122) input_p=StringSetChar(input_p,i,char1-32); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void StringToArray(string input_p,string &output[],string delim) { ArrayResize(output,0); int start1=0; while(start1