//+--------------------------------------------------------------------------------------+ //| Complex_pair_Divergence_V1.0.mq4 | //| based on Complex_pairs1.mq4 by Simeon Semonych and FX5_MACD_divergence_V1.1 by hazem@uk2.net| //| cooked them together by Finimej | //+--------------------------------------------------------------------------------------+ #property copyright "Copyright © 2009, Finimej" #property link "http://onix-trade.net/forum/index.php?showtopic=107" //---- #property indicator_separate_window #property indicator_buffers 4 #property indicator_color1 Green #property indicator_color2 Red #property indicator_color3 Blue #property indicator_color4 Magenta #property indicator_level1 0.0 #property indicator_levelcolor Black #property indicator_levelstyle STYLE_DOT //---- #define arrowsDisplacement 0.0001 //---- input parameters extern string separator1="*** Indicator Settings ***"; extern bool drawIndicatorTrendLines=true; extern bool drawPriceTrendLines=true; extern bool displayAlert=true; //---- buffers double bullishDivergence[]; double bearishDivergence[]; double pair[]; double signal[]; //---- static datetime lastAlertTime; static string indicatorName; //---- parameters // for monthly int mn_per=12; int mn_fast=3; // for weekly int w_per=9; int w_fast=3; // for daily int d_per=5; int d_fast=3; // for H4 int h4_per=12; int h4_fast=2; // for H1 int h1_per=24; int h1_fast=8; // for M30 int m30_per=16; int m30_fast=2; // for M15 int m15_per=16; int m15_fast=4; // for M5 int m5_per=12; int m5_fast=3; // for M1 int m1_per=30; int m1_fast=10; int per1,per2; int signalSMA=9; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators SetIndexStyle(0,DRAW_ARROW); SetIndexStyle(1,DRAW_ARROW); SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2); SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,1); //---- SetIndexBuffer(0,bullishDivergence); //SetIndexLabel(0, bullishDivergence); SetIndexBuffer(1,bearishDivergence); //SetIndexLabel(1, bearishDivergence); SetIndexBuffer(2,pair); SetIndexLabel(2,Symbol()); SetIndexBuffer(3,signal); //SetIndexLabel(3, signal); //---- SetIndexArrow(0,233); SetIndexArrow(1,234); //---- switch(Period()) { case 1: per1 = m1_per; per2 = m1_fast; break; case 5: per1 = m5_per; per2 = m5_fast; break; case 15: per1 = m15_per; per2 = m15_fast; break; case 30: per1 = m30_per; per2 = m30_fast; break; case 60: per1 = h1_per; per2 = h1_fast; break; case 240: per1 = h4_per; per2 = h4_fast; break; case 1440: per1 = d_per; per2 = d_fast; break; case 10080: per1 = w_per; per2 = w_fast; break; case 43200: per1 = mn_per; per2 = mn_fast; break; } indicatorName="CC_Divergence_v1.0 "+Symbol()+"("+Period()+", fast MA "+per2+")"; SetIndexDrawBegin(3,signalSMA); IndicatorDigits(Digits+2); IndicatorShortName(indicatorName); Print("per1=",per1,"per2=",per2); 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)!="pair_DivergenceLine") continue; ObjectDelete(label); } return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { int counted_bars=IndicatorCounted(); if(counted_bars < 0) return(-1); if(counted_bars>0) counted_bars--; int limit=Bars-counted_bars; if(counted_bars==0) limit-=1+1; CalculateIndicator(limit); //---- RefreshRates(); return(0); } //+------------------------------------------------------------------+ //| pp | //+------------------------------------------------------------------+ double pp(int Mode,int Price,int i,int per1x,int per2x) { return((iMA(Symbol(), 0, per2x, 0, Mode,Price, i)-iMA(Symbol(),0,per1x,0,Mode,Price,i))); } //+------------------------------------------------------------------+ //| CalculateIndicator | //+------------------------------------------------------------------+ void CalculateIndicator(int countedBars) { for(int i=countedBars; i>=0; i--) { Calculatepair(i); CatchBullishDivergence(i+2,countedBars); CatchBearishDivergence(i+2,countedBars); } } //+------------------------------------------------------------------+ //| Calculatepair | //+------------------------------------------------------------------+ void Calculatepair(int i) { int limit; int counted_bars=IndicatorCounted(); double OPEN,HIGH,LOW,CLOSE; //---- проверка на возможные ошибки if(counted_bars < 0) return; //---- последний посчитанный бар будет пересчитан if(counted_bars>0) counted_bars --; limit=Bars-counted_bars; if(counted_bars==0) limit-=1+1; //---- основной цикл int Price= 6; int Mode = 3; OPEN = pp(Mode, PRICE_OPEN, i, per1, per2); HIGH = pp(Mode, PRICE_HIGH, i, per1, per2); LOW=pp(Mode,PRICE_LOW,i,per1,per2); CLOSE=pp(Mode,PRICE_CLOSE,i,per1,per2); pair[i]=(OPEN+HIGH+LOW+CLOSE)/4; if((i>=0) && (ipair[lastTrough] && Low[currentTrough]Low[lastTrough]) { bullishDivergence[currentTrough]=pair[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], pair[currentTrough], pair[lastTrough], Green,STYLE_DOT); //---- if(displayAlert==true) DisplayAlert("Reverse bullish divergence on: ",currentTrough); } } //+------------------------------------------------------------------+ //| CatchBearishDivergence | //+------------------------------------------------------------------+ void CatchBearishDivergence(int shift,int maxind) { if(IsIndicatorPeak(shift)==false) return; int currentPeak=shift; int lastPeak=GetIndicatorLastPeak(shift,maxind); if(currentPeak==-1) return; if(lastPeak==-1) return; //---- if(pair[currentPeak]High[lastPeak]) { bearishDivergence[currentPeak]=pair[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], pair[currentPeak], pair[lastPeak],Red,STYLE_SOLID); if(displayAlert==true) DisplayAlert("Classical bearish divergence on: ", currentPeak); } if(pair[currentPeak]>pair[lastPeak] && High[currentPeak]Bars-1) return(false); if(pair[shift]>=pair[shift+1] && pair[shift]>pair[shift+2] && pair[shift]>pair[shift-1]) return(true); else return(false); } //+------------------------------------------------------------------+ //| IsIndicatorTrough | //+------------------------------------------------------------------+ bool IsIndicatorTrough(int shift) { if(shift-1<0) return(false); if(shift+2>Bars-1) return(false); if(pair[shift]<=pair[shift+1] && pair[shift]= signal[i+1] && signal[i] >= signal[i+2] && signal[i] >= signal[i-1] && signal[i] >= signal[i-2]) { for(int j=i; j= pair[j+1] && pair[j] > pair[j+2] && pair[j] >= pair[j-1] && pair[j] > pair[j-2]) return(j); } } } return(-1); } //+------------------------------------------------------------------+ //| GetIndicatorLastTrough | //+------------------------------------------------------------------+ int GetIndicatorLastTrough(int shift,int maxind) { for(int i=shift+2; i