//+------------------------------------------------------------------+ //| FX5_MACD_Divergence_V1.1.mq4 | //| FX5 | //| hazem@uk2.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, FX5" #property link "hazem@uk2.net" //---- #property indicator_separate_window #property indicator_buffers 4 #property indicator_color1 clrGreen #property indicator_color2 clrRed #property indicator_color3 clrMagenta #property indicator_color4 clrBlue //---- #define arrowsDisplacement 0.0001 //---- input parameters extern string separator1="*** MACD Settings ***"; extern int fastEMA = 12; extern int slowEMA = 26; extern int signalSMA=9; extern string separator2="*** Indicator Settings ***"; extern bool drawIndicatorTrendLines=true; extern bool drawPriceTrendLines=true; extern bool displayAlert=true; //---- buffers double bullishDivergence[]; double bearishDivergence[]; double macd[]; double signal[]; //---- static datetime lastAlertTime; static string indicatorName; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_ARROW); SetIndexStyle(1,DRAW_ARROW); SetIndexStyle(2,DRAW_LINE); SetIndexStyle(3,DRAW_LINE); //---- SetIndexBuffer(0,bullishDivergence); SetIndexBuffer(1,bearishDivergence); SetIndexBuffer(2,macd); SetIndexBuffer(3,signal); //---- SetIndexArrow(0,233); SetIndexArrow(1,234); //---- indicatorName="FX5_MACD_Divergence_v1.1("+fastEMA+", "+ slowEMA+", "+signalSMA+")"; SetIndexDrawBegin(3,signalSMA); IndicatorDigits(Digits+2); IndicatorShortName(indicatorName); return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { for(int i=ObjectsTotal()-1; i>=0; i--) { string label=ObjectName(i); if(StringSubstr(label,0,19)!="MACD_DivergenceLine") continue; ObjectDelete(label); } return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int countedBars=IndicatorCounted(); if(countedBars<0) countedBars=0; CalculateIndicator(countedBars); //---- return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CalculateIndicator(int countedBars) { int limit=Bars-countedBars; if(countedBars==0) limit-=slowEMA; for(int i=limit; i>=0; i--) { CalculateMACD(i); CatchBullishDivergence(i+2); CatchBearishDivergence(i+2); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CalculateMACD(int i) { macd[i]=iMACD(NULL,0,fastEMA,slowEMA,signalSMA, PRICE_CLOSE,MODE_MAIN,i); signal[i]=iMACD(NULL,0,fastEMA,slowEMA,signalSMA, PRICE_CLOSE,MODE_SIGNAL,i); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CatchBullishDivergence(int shift) { if(IsIndicatorTrough(shift)==false) return; int currentTrough=shift; int lastTrough=GetIndicatorLastTrough(shift); //---- if((lastTrough>=0 && lastTroughmacd[lastTrough] && Low[currentTrough]=0 && lastTroughLow[lastTrough]) { bullishDivergence[currentTrough]=macd[currentTrough]- arrowsDisplacement; //---- if(drawPriceTrendLines==true) DrawPriceTrendLine(Time[currentTrough],Time[lastTrough], Low[currentTrough], Low[lastTrough],Green,STYLE_DOT); //---- if(drawIndicatorTrendLines==true) DrawIndicatorTrendLine(Time[currentTrough], Time[lastTrough], macd[currentTrough], macd[lastTrough], Green,STYLE_DOT); //---- if(displayAlert==true) DisplayAlert("Reverse bullish divergence on: ", currentTrough); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CatchBearishDivergence(int shift) { if(IsIndicatorPeak(shift)==false) return; int currentPeak=shift; int lastPeak=GetIndicatorLastPeak(shift); //---- if((lastPeak>=0 && lastPeakHigh[lastPeak]) { bearishDivergence[currentPeak]=macd[currentPeak]+ arrowsDisplacement; if(drawPriceTrendLines==true) DrawPriceTrendLine(Time[currentPeak],Time[lastPeak], High[currentPeak], High[lastPeak],Red,STYLE_SOLID); if(drawIndicatorTrendLines==true) DrawIndicatorTrendLine(Time[currentPeak],Time[lastPeak], macd[currentPeak], macd[lastPeak],Red,STYLE_SOLID); if(displayAlert==true) DisplayAlert("Classical bearish divergence on: ", currentPeak); } if((lastPeak>=0 && lastPeakmacd[lastPeak] && High[currentPeak]=macd[shift+1] && macd[shift]>macd[shift+2] && macd[shift]>macd[shift-1]) return(true); else return(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsIndicatorTrough(int shift) { if(macd[shift]<=macd[shift+1] && macd[shift]1); i++) { if(signal[i] >= signal[i+1] && signal[i] >= signal[i+2] && signal[i] >= signal[i-1] && signal[i] >= signal[i-2]) { for(int j=i;(j1); j++) { if(macd[j] >= macd[j+1] && macd[j] > macd[j+2] && macd[j] >= macd[j-1] && macd[j] > macd[j-2]) return(j); } } } return(-1); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetIndicatorLastTrough(int shift) { for(int i=shift+5;(i1); i++) { if(signal[i] <= signal[i+1] && signal[i] <= signal[i+2] && signal[i] <= signal[i-1] && signal[i] <= signal[i-2]) { for(int j=i;(j1); j++) { if(macd[j] <= macd[j+1] && macd[j] < macd[j+2] && macd[j] <= macd[j-1] && macd[j] < macd[j-2]) return(j); } } } return(-1); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DisplayAlert(string message,int shift) { if(shift<=2 && Time[shift]!=lastAlertTime) { lastAlertTime=Time[shift]; Alert(message,Symbol()," , ",Period()," minutes chart"); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawPriceTrendLine(datetime x1,datetime x2,double y1, double y2,color lineColor,double style) { string label="MACD_DivergenceLine_v1.0# "+DoubleToStr(x1,0); ObjectDelete(label); ObjectCreate(label,OBJ_TREND,0,x1,y1,x2,y2,0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,lineColor); ObjectSet(label,OBJPROP_STYLE,style); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawIndicatorTrendLine(datetime x1,datetime x2,double y1, double y2,color lineColor,double style) { int indicatorWindow=WindowFind(indicatorName); if(indicatorWindow<0) return; string label="MACD_DivergenceLine_v1.0$# "+DoubleToStr(x1,0); ObjectDelete(label); ObjectCreate(label,OBJ_TREND,indicatorWindow,x1,y1,x2,y2, 0,0); ObjectSet(label,OBJPROP_RAY,0); ObjectSet(label,OBJPROP_COLOR,lineColor); ObjectSet(label,OBJPROP_STYLE,style); } //+------------------------------------------------------------------+