i-Divergency





//+------------------------------------------------------------------+
//|                                                   Divergency.mq4 |
//|                                       Copyright © Trofimov, 2008 |
//+------------------------------------------------------------------+
#property copyright "Copyright © Trofimov, 2008"
#property link      ""
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 DarkSlateBlue
#property indicator_width1 2
#property indicator_color2 Red
#property indicator_width2 2
#property indicator_color3 FireBrick
#property indicator_width3 1
#property indicator_color4 DarkGreen
#property indicator_width4 1

#property indicator_maximum  100
#property indicator_minimum -100

extern double Delta=10; // - ìèíèìàëüíîå ðàññòîÿíèå ìåæäó ìèíèìóìîì è ìàêñèìóìîì
int    ExtremumPoint=3; // - êîëè÷åñòâî òî÷åê ïî êîòîðûì îïðåäåëÿþòñÿ ýêñòðåìóìû. Ìîæåò áûòü ëþáûì íå÷¸òíûì çíà÷åíèåì áîëüøå åäèíèöû (Íàïðèìåð: 3,5,7,9....)
int    Buffer=500;      // - ðàçìåð áóôåðà ìàññèâà Stochastic[]
int    CurBuffer;       // - òåêóùèé (ïîñëåäíèé çàïîëíåííûé) áóôåðíûé èíäåêñ ìàññèâà Stochastic[]
double Stochastic[];
int    UpStochIdx[2];   // - ìàññèâ, ñîäåðæàùèé áóôåðíûå èíäåêñû òð¸õ ïîñëåäíèõ ìàêñèìóìîâ
int    DnStochIdx[2];   // - ìàññèâ, ñîäåðæàùèé áóôåðíûå èíäåêñû òð¸õ ïîñëåäíèõ ìèíèìóìîâ
int    CurrentCandle;
datetime LastTime;

//---- Ìàññèâ äàííûõ èíäèêàòîðà
double StochBuffer[];
double EndLimit[];
double StochUp[],StochDn[];
//+------------------------------------------------------------------+
int init() {
   //if(Buffer==0) Buffer=Bars;
   ArrayResize(Stochastic, Buffer);
   IndicatorBuffers(4);
//---- ïàðàìåòðû ðèñîâàíèÿ (óñòàíîâêà íà÷àëüíîãî áàðà)
   SetIndexDrawBegin(0,Buffer);
//---- 2 ðàñïðåäåëåííûõ áóôåðà èíäèêàòîðà
   SetIndexBuffer(0,StochBuffer);
   SetIndexBuffer(1,EndLimit);
   SetIndexBuffer(2,StochUp);
   SetIndexBuffer(3,StochDn);
//---- èìÿ èíäèêàòîðà è ïîäñêàçêè äëÿ ëèíèé
   IndicatorShortName("Divergency("+DoubleToStr(Delta,1)+")");
   SetIndexLabel(0,"Divergency");
   SetIndexLabel(1,"Limit");
   SetIndexLabel(2,"Top");
   SetIndexLabel(3,"Low");
//--- ñòèëü îòðèñîâêè
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexStyle(2, DRAW_ARROW);
   SetIndexStyle(3, DRAW_ARROW);
   SetIndexArrow(2, 108);
   SetIndexArrow(3, 108);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   static int OldUpStochIdx,OldDnStochIdx;
   int limit;
   // Ïðîïóùåííûå áàðû
   int counted_bars=IndicatorCounted();
//---- îáõîäèì âîçìîæíûå îøèáêè
   if(counted_bars<0) return(-1);
//---- íîâûå áàðû íå ïîÿâèëèñü è ïîýòîìó íè÷åãî ðèñîâàòü íå íóæíî
   limit=Bars-counted_bars-1;
//---- îñíîâíîé öèêë
   for(int i=limit; i>=0; i--) {
      CurrentCandle=i+1;//-ýòî ïîëíîñòüþ ñôîðìèðîâàâøàÿñÿ ñâå÷à
      if(LastTime!=iTime(NULL,0,CurrentCandle)) {
         AddStochastic();
         LastTime=iTime(NULL,0,CurrentCandle);
         //Èíäèêàòîð ïåðåñå÷åíèÿ ãðàíèö 20/80
         //EndLimit[i]=0;
         if(OldUpStochIdx!=UpStochIdx[0]) {
            if(Stochastic[UpStochIdx[0]]>80) {
               EndLimit[i]=-50;
               OldUpStochIdx=UpStochIdx[0];
            }
         }
         if(OldDnStochIdx!=DnStochIdx[0]) {
            if(Stochastic[DnStochIdx[0]]<20) {
               EndLimit[i]=50;
               OldDnStochIdx=DnStochIdx[0];
            }
         }
         //Èíäèêàòîð äèâåðãåíöèè
         //StochBuffer[i]=0;
         if(VectorStochastic(true)<0 && VectorPrice(true)>0) {
            if(GetIndexNormal(UpStochIdx[0])<GetIndexNormal(DnStochIdx[0])) {//åñëè ïîñëåäíèé ìèíèìóì ñòàðåå ïîñëåäíåãî ìàêñèìóìà
               StochBuffer[i]=-100;
            }
         }
         if(VectorStochastic(false)>0 && VectorPrice(false)<0) {
            if(GetIndexNormal(UpStochIdx[0])>GetIndexNormal(DnStochIdx[0])) {//åñëè ïîñëåäíèé ìàêñèìóì ñòàðåå ïîñëåäíåãî ìèíèìóìà
               StochBuffer[i]=100;
            }
         }
         //Print("===== ",TimeToStr(LastTime)," =====");
      }
   }
   return(0);
  }
//+------------------------------------------------------------------+
int AddStochastic() {
   //Äîáàâëÿåò íîâîå çíà÷åíèå ñòîõàñòèêà â ìàññèâ
   if(CurBuffer==0) 
      CurBuffer=Buffer-1;
   else
      CurBuffer--;
   Stochastic[CurBuffer]=iStochastic(NULL,0,5,3,3,MODE_EMA,0,MODE_MAIN,CurrentCandle);

   //Ïðîâåðêà íà âîçíèêíîâåíèå ýêñòðåìóìà
   int countUp, countDn;
   int idxTop=(ExtremumPoint-1)/2; // - íîðìàëüíûé èíäåêñ âåðøèíû
   for (int i = idxTop-1; i >= 0 ; i--) { //Öûêë íîðìàëüíîãî èíäåêñà
      if(Stochastic[GetIndexBuffer(i)]<Stochastic[GetIndexBuffer(i+1)] &&
      Stochastic[GetIndexBuffer(idxTop+(idxTop-i))]<Stochastic[GetIndexBuffer(idxTop+(idxTop-i)-1)]) {
         countUp++;
      }
      if(Stochastic[GetIndexBuffer(i)]>Stochastic[GetIndexBuffer(i+1)] &&
      Stochastic[GetIndexBuffer(idxTop+(idxTop-i))]>Stochastic[GetIndexBuffer(idxTop+(idxTop-i)-1)]) {
         countDn++;
      }
   } //Next i
   if(countUp==idxTop) { //âåðøèíà îêàçàëàñü ìàêñèìóìîì
      if(GetIndexNormal(DnStochIdx[0])<GetIndexNormal(UpStochIdx[0])) { //Åñëè ïðåäûäóùèì ñòîèò ìèíèìóì
         if(Stochastic[GetIndexBuffer(idxTop)]-Stochastic[DnStochIdx[0]]>Delta){ 
         //Åñëè ìåæäó ïðåäûäóùèì ìèíèìóìîì è ïðåäïîëîæèòåëüíûì ìàêñèìóìîì ðàñòîÿíèå ïî âåðòèêàëè áîëüøå Delta
            UpStochIdx[2]=UpStochIdx[1];
            UpStochIdx[1]=UpStochIdx[0];
            UpStochIdx[0]=GetIndexBuffer(idxTop);
            StochUp[CurrentCandle-1]=Stochastic[UpStochIdx[0]];
         }
      } else { //Åñëè ïðåäûäóùèì ñòîèò ìàêñèìóì
         if(Stochastic[UpStochIdx[0]]<Stochastic[GetIndexBuffer(idxTop)]) { //åñëè ïðåäûäóùèé ìàêñèìóì áûë ìåíüøå íàñòîÿùåãî
            StochUp[CurrentCandle-2+GetIndexNormal(UpStochIdx[0])]=EMPTY_VALUE;
            //StochUp[CurrentCandle-1+idxTop]=Stochastic[GetIndexBuffer(idxTop)];
            StochUp[CurrentCandle-1]=Stochastic[GetIndexBuffer(idxTop)];
            UpStochIdx[0]=GetIndexBuffer(idxTop);
         }
      }
   } else if(countDn==idxTop) { //âåðøèíà îêàçàëàñü ìèíèìóìîì
      if(GetIndexNormal(UpStochIdx[0])<GetIndexNormal(DnStochIdx[0])) { //Åñëè ïðåäûäóùèì ñòîèò ìàêñèìóì
         if(Stochastic[UpStochIdx[0]]-Stochastic[GetIndexBuffer(idxTop)]>Delta){ 
         //Åñëè ìåæäó ïðåäûäóùèì ìàêñèñóìîì è ïðåäïîëîæèòåëüíûì ìèíèìóìîì ðàñòîÿíèå ïî âåðòèêàëè áîëüøå Delta
            DnStochIdx[2]=DnStochIdx[1];
            DnStochIdx[1]=DnStochIdx[0];
            DnStochIdx[0]=GetIndexBuffer(idxTop);
            StochDn[CurrentCandle-1]=Stochastic[DnStochIdx[0]];
         }
      } else { //Åñëè ïðåäûäóùèì ñòîèò ìèíèìóì
         if(Stochastic[DnStochIdx[0]]>Stochastic[GetIndexBuffer(idxTop)]) { //åñëè ïðåäûäóùèé ìèíèìóì áûë áîëüøå íàñòîÿùåãî
            StochDn[CurrentCandle-2+GetIndexNormal(DnStochIdx[0])]=EMPTY_VALUE;
            //StochDn[CurrentCandle-1+idxTop]=Stochastic[GetIndexBuffer(idxTop)];
            StochDn[CurrentCandle-1]=Stochastic[GetIndexBuffer(idxTop)];
            DnStochIdx[0]=GetIndexBuffer(idxTop);
         }
      }
   }
   return(0);
}
//+------------------------------------------------------------------+
int GetIndexBuffer(int Idx) {
   //âîçâðàùàåò áóôåðíûé èíäåêñ ìàññèâà, ãäå Idx - íîðìàëüíûé èíäåêñ
   if(Idx>Buffer-1) {
      Print("Íåäîïóñòèìîå çíà÷åíèå èíäåêñà äëÿ ìàññèâà");
      return(-1);
   }
   int retIndex=CurBuffer+Idx;
   if(retIndex>Buffer-1) retIndex=retIndex-Buffer;
   return(retIndex);
}
//+------------------------------------------------------------------+
int GetIndexNormal(int IdxBuf) {
   //âîçâðàùàåò íîðìàëüíûé èíäåêñ, ãäå IdxBuf - áóôåðíûé èíäåêñ ìàññèâà
   if(IdxBuf>Buffer-1) {
      Print("Íåäîïóñòèìîå çíà÷åíèå èíäåêñà äëÿ ìàññèâà");
      return(-1);
   }
   int retIndex=IdxBuf-CurBuffer;
   if(retIndex<0) retIndex=retIndex+Buffer;
   return(retIndex);
}
//+------------------------------------------------------------------+
int VectorStochastic(bool MaxMin) {
   //âîçâðàùàåò íàïðàâëåíèå òðåíäîâîé ëèíèè, ïðîâåä¸ííîé ÷åðåç âåðøèíû ñòîõàñòèêà:
   //1 - ââåðõ, -1 - âíèç, 0 - ãîðèçîíòàëüíî
   //MaxMin - òèïû àíàëèçèðóåìûõ âåðøèí: true - ìàêñèìóìû, false - ìèíèìóìû 
   if(MaxMin) {
      //Print("Stochastic[UpStochIdx[0]]="+Stochastic[UpStochIdx[0]],", Stochastic[UpStochIdx[1]]="+Stochastic[UpStochIdx[1]]);
      if(Stochastic[UpStochIdx[0]]>Stochastic[UpStochIdx[1]]) {
         //Print("Stochastic[0]="+Stochastic[UpStochIdx[0]],", Stochastic[1]="+Stochastic[UpStochIdx[1]],", return 1");
         return(1);
      } else if(Stochastic[UpStochIdx[0]]<Stochastic[UpStochIdx[1]]) {
         //Print("Stochastic[0]="+Stochastic[UpStochIdx[0]],", Stochastic[1]="+Stochastic[UpStochIdx[1]],", return -1");
         return(-1);
      }
   } else {
      //Print("Stochastic[DnStochIdx[0]]="+Stochastic[DnStochIdx[0]],", Stochastic[DnStochIdx[1]]="+Stochastic[DnStochIdx[1]]);
      if(Stochastic[DnStochIdx[0]]>Stochastic[DnStochIdx[1]]) {
         //Print("Stochastic[0]="+Stochastic[DnStochIdx[0]],", Stochastic[1]="+Stochastic[DnStochIdx[1]],", return 1");
         return(1);
      } else if(Stochastic[DnStochIdx[0]]<Stochastic[DnStochIdx[1]]) {
         //Print("Stochastic[0]="+Stochastic[DnStochIdx[0]],", Stochastic[1]="+Stochastic[DnStochIdx[1]],", return -1");
         return(-1);
      }
   }
   return(0);
}
//+------------------------------------------------------------------+
int VectorPrice(bool MaxMin) {
   //âîçâðàùàåò íàïðàâëåíèå òðåíäîâîé ëèíèè, ïðîâåä¸ííîé ÷åðåç ïèêè ñâå÷åé òåêóùåãî ãðàôèêà:
   //1 - ââåðõ, -1 - âíèç, 0 - ãîðèçîíòàëüíî
   //MaxMin - òèïû àíàëèçèðóåìûõ ïèêîâ: true - High, false - Low 
   int Extremum0,Extremum1;
   if(MaxMin) {
      Extremum0=iHighest(NULL,0,MODE_HIGH,GetIndexNormal(DnStochIdx[0]),CurrentCandle);
      Extremum1=iHighest(NULL,0,MODE_HIGH,GetIndexNormal(DnStochIdx[1])-GetIndexNormal(DnStochIdx[0]),GetIndexNormal(DnStochIdx[0])+CurrentCandle);
      //Print("High[Extremum0]=",High[Extremum0],", High[Extremum1]=",High[Extremum1]);
      if(High[Extremum0]>High[Extremum1]) {
         //Print("High[0]=",High[Extremum0],", High[1]=",High[Extremum1],", return 1");
         return(1);
      } else {
         //Print("High[0]=",High[Extremum0],", High[1]=",High[Extremum1],", return -1");
         return(-1);
      }
   } else {
      Extremum0=iLowest(NULL,0,MODE_LOW,GetIndexNormal(UpStochIdx[0]),CurrentCandle);
      Extremum1=iLowest(NULL,0,MODE_LOW,GetIndexNormal(UpStochIdx[1])-GetIndexNormal(UpStochIdx[0]),GetIndexNormal(UpStochIdx[0])+CurrentCandle);
      //Print("Low[Extremum0]=",Low[Extremum0],", Low[Extremum1]=",Low[Extremum1]);
      if(Low[Extremum0]>Low[Extremum1]) {
         //Print("Low[0]=",Low[Extremum0],", Low[1]=",Low[Extremum1],", return 1");
         return(1);
      } else {
         //Print("Low[0]=",Low[Extremum0],", Low[1]=",Low[Extremum1],", return -1");
         return(-1);
      }
   }
   return(0);
}
//+------------------------------------------------------------------+





Sample





Analysis



Market Information Used:

Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar


Indicator Curves created:


Implements a curve of type DRAW_HISTOGRAM
Implements a curve of type DRAW_ARROW

Indicators Used:

Stochastic oscillator


Custom Indicators Used:

Order Management characteristics:

Other Features: