//+------------------------------------------------------------------+ //| Moving Average.mq4 | //| Copyright © 2005, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ #include #include // Add defines for signals #define LONG 1 #define SHORT -1 #define FLAT 0 // Divergence Type #define BULLISH 1 #define BEARISH 2 extern string separator1 = "*** OSMA Settings ***"; extern int fastEMA = 12; extern int slowEMA = 26; extern int signal = 9; extern bool displayAlert = true; extern bool sendEmail = true; static datetime lastAlertTime, lastEmailTime; int init() { return(0); } int deinit() { return(0); } double OsMA(int pos) { double val; val = iOsMA(NULL, 0, fastEMA, slowEMA, signal, PRICE_CLOSE, pos); return(val); } //+------------------------------------------------------------------+ //| GetSignal | //| | //+------------------------------------------------------------------+ int GetSignal() { int bull = FLAT, bear = FLAT; double myOsMA; //---- go trading only for first tiks of new bar if(Volume[0]>1) return; myOsMA = OsMA(0); bull = CatchBullishDivergence(0 + 2); if (bull != FLAT) return(LONG); bear = CatchBearishDivergence(0 + 2); if (bear != FLAT) return(SHORT); return (FLAT); } int CatchBullishDivergence(int shift) { double OsMAcurrentTrough, OsMAlastTrough, LowCurrentTrough, LowLastTrough; if(IsIndicatorTrough(shift) == false) return(FLAT); int currentTrough = shift; int lastTrough = GetIndicatorLastTrough(shift); OsMAcurrentTrough = OsMA(currentTrough); OsMAlastTrough = OsMA(lastTrough); LowCurrentTrough = iLow(NULL, 0, currentTrough); LowLastTrough = iLow(NULL, 0, lastTrough); if(OsMAcurrentTrough > OsMAlastTrough && LowCurrentTrough < LowLastTrough) { if(displayAlert == true) DisplayAlert("Classical bullish divergence on: ", currentTrough); if(sendEmail == true) SendAnEmail("Classical bullish divergence on: ", currentTrough); return(BULLISH); } if(OsMAcurrentTrough < OsMAlastTrough && LowCurrentTrough > LowLastTrough) { if(displayAlert == true) DisplayAlert("Reverse bullish divergence on: ", currentTrough); if(sendEmail == true) SendAnEmail("Reverse bullish divergence on: ", currentTrough); return(BULLISH); } return(FLAT); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CatchBearishDivergence(int shift) { double OsMAcurrentPeak, OsMAlastPeak, HighCurrentPeak, HighLastPeak; if(IsIndicatorPeak(shift) == false) return; int currentPeak = shift; int lastPeak = GetIndicatorLastPeak(shift); OsMAcurrentPeak = OsMA(currentPeak); OsMAlastPeak = OsMA(lastPeak); HighCurrentPeak = iHigh(NULL, 0, currentPeak); HighLastPeak = iHigh(NULL, 0, lastPeak); if(OsMAcurrentPeak < OsMAlastPeak && HighCurrentPeak > HighLastPeak) { if(displayAlert == true) DisplayAlert("Classical bearish divergence on: ", currentPeak); if(sendEmail == true) SendAnEmail("Classical bearish divergence on: ", currentPeak); return(BEARISH); } if(OsMAcurrentPeak > OsMAlastPeak && HighCurrentPeak < HighLastPeak) { if(displayAlert == true) DisplayAlert("Reverse bearish divergence on: ", currentPeak); if(sendEmail == true) SendAnEmail("Reverse bearish divergence on: ", currentPeak); return(BEARISH); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsIndicatorPeak(int shift) { double OsMAshift, OsMAshift1, OsMAshiftm1, OsMAcurrent; OsMAshift = OsMA(shift); OsMAshift1 = OsMA(shift+1); OsMAshiftm1 = OsMA(shift-1); if(OsMAshift > 0 && OsMAshift > OsMAshift1 && OsMAshift > OsMAshiftm1) { for(int i = shift + 1; i < Bars; i++) { OsMAcurrent = OsMA(i); if(OsMAcurrent < 0) return(true); if(OsMAcurrent > OsMAshift) break; } } return(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsIndicatorTrough(int shift) { double OsMAshift, OsMAshift1, OsMAshiftm1, OsMAcurrent; OsMAshift = OsMA(shift); OsMAshift1 = OsMA(shift+1); OsMAshiftm1 = OsMA(shift-1); if(OsMAshift < 0 && OsMAshift < OsMAshift1 && OsMAshift < OsMAshiftm1) { for(int i = shift + 1; i < Bars; i++) { OsMAcurrent = OsMA(i); if(OsMAcurrent > 0) return(true); if(OsMAcurrent < OsMAshift) break; } } return(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetIndicatorLastPeak(int shift) { double OsMAshift, OsMAshift1, OsMAshift2, OsMAshiftm1, OsMAshiftm2; for(int i = shift + 5; i < Bars; i++) { OsMAshift = OsMA(i); OsMAshift1 = OsMA(i+1); OsMAshift2 = OsMA(i+2); OsMAshiftm1 = OsMA(i-1); OsMAshiftm2 = OsMA(i-2); if(OsMAshift >= OsMAshift1 && OsMAshift > OsMAshift2 && OsMAshift >= OsMAshiftm1 && OsMAshift > OsMAshiftm2) return(i); } return(-1); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetIndicatorLastTrough(int shift) { double OsMAshift, OsMAshift1, OsMAshift2, OsMAshiftm1, OsMAshiftm2; for(int i = shift + 5; i < Bars; i++) { OsMAshift = OsMA(i); OsMAshift1 = OsMA(i+1); OsMAshift2 = OsMA(i+2); OsMAshiftm1 = OsMA(i-1); OsMAshiftm2 = OsMA(i-2); if(OsMAshift <= OsMAshift1 && OsMAshift < OsMAshift2 && OsMAshift <= OsMAshiftm1 && OsMAshift < OsMAshiftm2) return(i); } return(-1); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DisplayAlert(string message, int shift) { if(shift <= 2 && Time[shift] != lastAlertTime) { lastAlertTime = Time[shift]; Alert(message, Symbol(), " , ", tf2txt(0), " chart"); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SendAnEmail(string message, int shift) { if(shift <= 2 && Time[shift] != lastEmailTime) { lastEmailTime = Time[shift]; SendMail("Alert from MACD Divergence Indicator",message + Symbol() + " , " + tf2txt(0) + " chart"); } } //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ int start() { int NumOrders = 0, Position, signal; RefreshRates(); signal=GetSignal(); // wait until first tick after bar close to take any action; if (signal != FLAT) { if(signal == LONG) { OpenTrade(OP_BUY); return; } if(signal == SHORT) { OpenTrade(OP_SELL); } } return(0); //---- } void OpenTrade(int cmd) { } string tf2txt(int tf) { switch(tf) { case PERIOD_M1: return("M1"); case PERIOD_M5: return("M5"); case PERIOD_M15: return("M15"); case PERIOD_M30: return("M30"); case PERIOD_H1: return("H1"); case PERIOD_H4: return("H4"); case PERIOD_D1: return("D1"); case PERIOD_W1: return("W1"); case PERIOD_MN1: return("MN"); } return("??"); } //+------------------------------------------------------------------+