//+------------------------------------------------------------------+
//|                                    DeMark Sequential Vs. 2.0.mq4 |
//|                                       Copyright 2012, Peperlizio |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Peperlizio"
#property link      ""

#property indicator_chart_window
//+------------------------------------------------------------------+
//| Extern Variables                                                 |
//+------------------------------------------------------------------+
extern int  Text_Distance  = 30;
extern int  Text_Dimension = 10;
extern bool Show_8_13_     = true;

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
string   Prefix = "DMS_";
string   Type;                                                                  //Seleziona Up o Dw nelle fasi del programma
string   Pattern;                                                               //Seleziona St o Cd nelle fasi del programma
int      StartUp9,  StartUp8,  StartDw9,  StartDw8;                             //Memorizza la candela di partenza del Setup
double   MinUp9,    MinUp8,    MinDw9,    MinDw8;                               //Memorizza il Min registrato dal Setup
double   MaxUp9,    MaxUp8,    MaxDw9,    MaxDw8;                               //Memorizza il Max registrato dal Setup
double   RanUp9,    RanUp8,    RanDw9,    RanDw8;                               //Memorizza il Range registrato dal Setup
double   RanUp9Bef, RanUp8Bef, RanDw9Bef, RanDw8Bef;                            //Memorizza il Range registrato dal Setup precedente
bool     Buy9,      Buy8,      Sell9,     Sell8;                                //Flag di Setup e Intersezione verificati
bool     IntUp9,    IntUp8,    IntDw9,    IntDw8;                               //Flag di Intersezione verificata
bool     CDUp9,     CDUp8,     CDDw9,     CDDw8;                                //Flag di Countdown verificato
int      CntUp9,    CntUp8,    CntDw9,    CntDw8;                               //Contatore del Countdown
datetime FirstUp9,  FirstUp8,  FirstDw9,  FirstDw8;                             //Memorizza la posizione della 1° candela del Countdown
double   EightUp9,  EightUp8,  EightDw9,  EightDw8;                             //Memorizza la chiusura dell'8° candela del Countdown (per condizione fondamentale)
datetime SignalUp9, SignalUp8, SignalDw9, SignalDw8;                            //Data della candela su cui postare il segnale di acquisto o vendita.
bool     NextUp8,   NextDw8;                                                    //Flag di candela 9 in un conteggio 8-13

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   RanUp9Bef = 0;       RanUp8Bef = 0;       RanDw9Bef = 0;       RanDw8Bef = 0;
   Buy9      = false;   Buy8      = false;   Sell9     = false;   Sell8     = false;
   IntUp9    = false;   IntUp8    = false;   IntDw9    = false;   IntDw8    = false;
   CDUp9     = false;   CDUp8     = false;   CDDw9     = false;   CDDw8     = false;
   CntUp9    = 0;       CntUp8    = 0;       CntDw9    = 0;       CntDw8    = 0;
   NextUp8   = false;   NextDw8   = false;
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   for (int i = ObjectsTotal()-1; i>=0; i--) 
    {
     string tmp = ObjectName(i);
     if (StringFind(tmp,Prefix) >= 0) ObjectDelete(tmp);
    }
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int  i, Cnt, Limit;
  
   int counted_bars = IndicatorCounted(); 
   Limit = Bars - counted_bars;
   
   if (Limit==1 && !IsNewBar()) return(0);               //Avviato l'indicatore vengono controllate le barre da 1 a Bars, 
                                                         //successivamente per ogni nuova barra che compare viene controllata solamente barra 1
   for (i=Limit; i>0; i--) 
    { 
     //----Buy
     Type = "Up"; 
     
     //----Buy Setup
     Pattern = "St";
     Cnt = Counter(i); 
     if (Cnt==7 && Validation(i+7))  {TextMake(9,i,7); TextMake(8,i,7);}
     if (Cnt==8 && Validation(i+8))  {TextMake(9,i,8); TextMake(8,i,8);}
     if (Cnt==9 && Validation(i+9))                                                             //9-13 convalidato
      {  
       TextMake(9,i,9); TextMake(8,i,"û");                                                         //Scrittura numeri
       StartUp9 = i+8;                                                                             //Candela di partenza del Setup
       MinUp9   = iLow (NULL,0,iLowest (NULL,0,MODE_LOW ,6,i+3));                                  //Min più basso registrato nel Setup dalla 1° alla 6° barra
       MaxUp9   = iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,9,i));                                    //Max più alto  registrato nel Setup
       RanUp9   = (MaxUp9 - iLow(NULL,0,iLowest(NULL,0,MODE_LOW,9,i)))/Point;                      //Range del setup 
       if (Intersection(i,MinUp9) || Intersection(i+1,MinUp9)) {Buy9   = true; IntUp9 = false;}    //Intersezione verificata vai a Buy
       else                                                    {IntUp9 = true; Buy9   = false;}    //Intersezione fallita vai a Int
      }
     if (Cnt==0 && Validation(i+9) && Counter(i+1)==8)                                          //8-13 convalidato
      { 
       TextMake(9,i,"û");                                                                          //Scrittura numeri
       StartUp8 = i+8;                                                                             //Candela di partenza del Setup
       MinUp8   = iLow (NULL,0,iLowest (NULL,0,MODE_LOW ,5,i+4));                                  //Min più basso registrato nel Setup dalla 1° alla 5° barra
       MaxUp8   = iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,8,i+1));                                  //Max più alto  registrato nel Setup
       RanUp8   = (MaxUp8 - iLow(NULL,0,iLowest(NULL,0,MODE_LOW,8,i+1)))/Point;                    //Range del setup 
       if (Intersection(i+1,MinUp8)){NextUp8 = true; Buy8 = true; IntUp8 = false;}                 //Intersezione a barra 8 verificata vai a Buy
       else                         {IntUp8  = true; Buy8 = false;}                                //Intersezione fallita vai a Int
      }
     
     //----Buy Intersection 9-13
     MinUp9   = iLow(NULL,0,iLowest(NULL,0,MODE_LOW,StartUp9-i+3,i+3));  
     if(IntUp9 && Intersection(i,MinUp9)) {Buy9 = true; IntUp9 = false;}
     
     //----Buy CountDown    9-13
     Pattern = "Cd"; 
     if ((Buy9 || CDUp9) && (Close[i]>MaxUp9 || Sell9 || CDDw9 || ((Buy9 || IntUp9) && ((RanUp9>RanUp9Bef && RanUp9<=RanUp9Bef*1.618) || RanUp9>=RanUp9Bef*3) ) ) )   //Condizioni Invalidanti
      {         //Chiusura > Max registrato dal Setup || Setup Sell completato || Setup Buy completato  cui Range > del Range el Setup Buy precedente)
       CntUp9    = 0; 
       RanUp9Bef = RanUp9;
       CDUp9     = false;
       if (Close[i]>MaxUp9 || Sell9) Buy9 = false;             //Buy non viene negato se il Recycle è dato dalla condizione del Range
      }
     if (Buy9  && CountDown(i)) {CntUp9++; TextMake(9,i,CntUp9); CDUp9=true; Buy9=false; FirstUp9=iTime(NULL,0,i);}                                      //Setup concluso, attesa Countdown 1
     if (CDUp9 && CountDown(i) && CntUp9>0 && FirstUp9<iTime(NULL,0,i)) {if(CntUp9==8) EightUp9=iClose(NULL,0,i); CntUp9++; TextMake(9,i,CntUp9);}       //Countdown da 2 a 13
     if (CDUp9 && CntUp9 == 13) {SignalUp9=iTime(NULL,0,i)+60*Period(); CDUp9=false;}                                                                    //Termine Countdown
     if (!Buy9 && !CDUp9 && CntUp9>0 && (SignalUp9==iTime(NULL,0,i) || (SignalUp9<iTime(NULL,0,i) && iTime(NULL,0,i+1)!=iTime(NULL,0,i)-60*Period())))   //Segnale di acquisto  
      {                               //(Candela seguente la 13     ||   Caso di fine settimana) 
       CntUp9 = 0;                                             //Azzera il contatore 
       RanUp9Bef = 0;                                          //Azzera il Range precedente (Range Bef serve solo quando un altro setup finisce prima di arrivare a 13)
       if(EightUp9>=iClose(NULL,0,i+1)) TextMake(9,i,"é");     //Condizione fondamentale rispettata 
       else TextMake(9,i,"+");                                 //Condizione fondamentale fallita
      } 
     
     //----8-13
     if (Show_8_13_)
      {
       //----Buy Intersection 8-13
       MinUp8   = iLow(NULL,0,iLowest(NULL,0,MODE_LOW,StartUp8-i+3,i+3));  
       if(IntUp8 && Intersection(i,MinUp8)) {Buy8 = true; IntUp8 = false;}
           
       //----Buy CountDown    8-13
       Pattern = "Cd";
       if ((Buy8 || CDUp8) && (Close[i]>MaxUp8 || Sell8 || CDDw8 || ((Buy8 || IntUp8) && ((RanUp8>RanUp8Bef && RanUp8<=RanUp8Bef*1.618) || RanUp8>=RanUp8Bef*3) ) ) )   //Condizioni Invalidanti
        {          //Chiusura >Max registrato dal Setup || Setup Sell completato || Setup Buy completato  cui Range > del Range el Setup Buy precedente)
         CntUp8    = 0; if(i==316) Alert(RanUp8);
         RanUp8Bef = RanUp8;
         CDUp8     = false;
         if (Close[i]>MaxUp8 || Sell8) Buy8 = false;             //Buy non viene negato se il Recycle è dato dalla condizione del Range
        }
       if (NextUp8 && CountDown(i+1)) {CntUp8++; TextMake(8,i+1,CntUp8); NextUp8=false; CDUp8=true; Buy8=false; FirstUp8=iTime(NULL,0,i+1);}               //Inizio Countdown da barra 8 del Setup
       if (Buy8  && CountDown(i)) {CntUp8++; TextMake(8,i,CntUp8); NextUp8=false; CDUp8=true; Buy8=false; FirstUp8=iTime(NULL,0,i);}                       //Setup concluso, attesa Countdown 1
       if (CDUp8 && CountDown(i) && CntUp8>0 && FirstUp8<iTime(NULL,0,i)) {if(CntUp8==8) EightUp8=iClose(NULL,0,i); CntUp8++; TextMake(8,i,CntUp8);}       //Countdown da 2 a 13
       if (CDUp8 && CntUp8 == 13) {SignalUp8=iTime(NULL,0,i)+60*Period(); CDUp8=false;}                                                                    //Termine Countdown
       if (!Buy8 && !CDUp8 && CntUp8>0 && (SignalUp8==iTime(NULL,0,i) || (SignalUp8<iTime(NULL,0,i) && iTime(NULL,0,i+1)!=iTime(NULL,0,i)-60*Period())))   //Segnale di acquisto                                                                                          //Segnale di acquisto
        {                                //(Candela seguente la 13     ||   Caso di fine settimana) 
         CntUp8    = 0;                                          //Azzera il contatore 
         RanUp8Bef = 0;                                          //Azzera il Range precedente (Range Bef serve solo quando un altro setup finisce prima di arrivare a 13)
         if(EightUp8>=iClose(NULL,0,i+1)) TextMake(8,i,"é");     //Condizione fondamentale rispettata 
         else TextMake(8,i,"+");                                 //Condizione fondamentale fallita
        } 
      }

     
     //----Sell
     Type = "Dw";
     
     //----Sell Setup
     Pattern = "St";
     Cnt = Counter(i); 
     if (Cnt==7 && Validation(i+7))  {TextMake(9,i,7); TextMake(8,i,7);}
     if (Cnt==8 && Validation(i+8))  {TextMake(9,i,8); TextMake(8,i,8);}
     if (Cnt==9 && Validation(i+9))                                                             //9-13 convalidato
      {  
       TextMake(9,i,9); TextMake(8,i,"û");                                                         //Scrittura numeri
       StartDw9 = i+8;                                                                             //Candela di partenza del Setup
       MaxDw9   =  iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,6,i+3));                                 //Max più alto  registrato nel Setup dalla 1° alla 6° barra
       MinDw9   =  iLow (NULL,0,iLowest (NULL,0,MODE_LOW ,9,i));                                   //Min più basso registrato nel Setup
       RanDw9   = (iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,9,i)) - MinDw9)/Point;                   //Range del setup 
       if (Intersection(i,MaxDw9) || Intersection(i+1,MaxDw9)) {Sell9  = true; IntDw9 = false;}    //Intersezione verificata vai a Buy
       else                                                    {IntDw9 = true; Sell9  = false;}    //Intersezione fallita vai a Int
      }
     if (Cnt==0 && Validation(i+9) && Counter(i+1)==8)                                          //8-13 convalidato
      { 
       TextMake(9,i,"û");                                                                          //Scrittura numeri
       StartDw8 = i+8;                                                                             //Candela di partenza del Setup
       MaxDw8   =  iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,5,i+4));                                 //Max più alto  registrato nel Setup dalla 1° alla 6° barra
       MinDw8   =  iLow (NULL,0,iLowest (NULL,0,MODE_LOW ,8,i+1));                                 //Min più basso registrato nel Setup
       RanDw8   = (iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,8,i+1)) - MinDw9)/Point;                 //Range del setup 
       if (Intersection(i+1,MaxDw8)){NextDw8 = true; Sell8 = true; IntDw8 = false;}                //Intersezione a barra 8 verificata vai a Sell
       else                         {IntDw8  = true; Sell8 = false;}                               //Intersezione fallita vai a Int
      }    
      
     //----Sell Intersection
     MaxDw9   = iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,StartDw9-i+3,i+3));  
     if(IntDw9 && Intersection(i,MaxDw9)) {Sell9 = true; IntDw9 = false;}
     
     //----Sell Countdown
     Pattern = "Cd";
     if ((Sell9 || CDDw9) && (Close[i]<MinDw9 || Buy9 || CDUp9 || ((Sell9 || IntDw9) && ((RanDw9>RanDw9Bef && RanDw9<=RanDw9Bef*1.618) || RanDw9>=RanDw9Bef*3) ) ) )   //Condizioni Invalidanti
      {         //Chiusura < Min registrato dal Setup || Setup Buy completato || Setup Sell completato  cui Range > del Range el Setup Buy precedente)
       CntDw9    = 0;  
       RanDw9Bef = RanDw9;
       CDDw9     = false; 
       if (Close[i]<MinDw9 || Buy9) Sell9 = false;             //Sell non viene negato se il Recycle è dato dalla condizione del Range
      }
     if (Sell9 && CountDown(i)) {CntDw9++; TextMake(9,i,CntDw9); CDDw9=true; Sell9=false; FirstDw9=iTime(NULL,0,i);}                                     //Setup concluso, attesa Countdown 1
     if (CDDw9 && CountDown(i) && CntDw9>0 && FirstDw9<iTime(NULL,0,i)) {if(CntDw9==8) EightDw9=iClose(NULL,0,i); CntDw9++; TextMake(9,i,CntDw9);}       //Countdown da 2 a 13
     if (CDDw9 && CntDw9==13)   {SignalDw9=iTime(NULL,0,i)+60*Period(); CDDw9=false;}                                                                    //Termine Countdown
     if (!Sell9 && !CDDw9 && CntDw9>0 && (SignalDw9==iTime(NULL,0,i) || (SignalDw9<iTime(NULL,0,i) && iTime(NULL,0,i+1)!=iTime(NULL,0,i)-60*Period())))  //Segnale di acquisto
      {                                //(Candela seguente la 13     ||   Caso di fine settimana)
       CntDw9 = 0;                                             //Azzera il contatore 
       RanDw9Bef = 0;                                          //Azzera il Range precedente (Range Bef serve solo quando un altro setup finisce prima di arrivare a 13)
       if(EightDw9<=iClose(NULL,0,i+1)) TextMake(9,i,"ê");     //Condizione fondamentale rispettata 
       else TextMake(9,i,"+");                                 //Condizione fondamentale fallita
      } 
     
     //----8-13
     if (Show_8_13_)
      {
       //----Sell Intersection
       MaxDw8   = iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,StartDw8-i+3,i+3));  
       if(IntDw8 && Intersection(i,MaxDw8)) {Sell8 = true; IntDw8 = false;}
//Per inserire il controllo Countdown sull'8° barra del setup 8-13 creare una variabile aggiuntiva per riconoscere la 9° barra (il setup 8-13 viene comunque riconosciuto alla barra successiva, la 9° anche se non conteggiata Es. barra 1576 EURUSD D1)

       //----Sell Countdown 8-13
       Pattern = "Cd";   
       if ((Sell8 || CDDw8) && (Close[i]<MinDw8 || Buy8 || CDUp8 || ((Sell8 || IntDw8) && ((RanDw8>RanDw8Bef && RanDw8<=RanDw8Bef*1.618) || RanDw8>=RanDw8Bef*3) ) ) )   //Condizioni Invalidanti
        {         //Chiusura < Min registrato dal Setup || Setup Buy completato || Setup Sell completato  cui Range > del Range el Setup Buy precedente)
         CntDw8    = 0;  
         RanDw8Bef = RanDw8;
         CDDw8     = false; 
         if (Close[i]<MinDw8 || Buy8) Sell8 = false;             //Sell non viene negato se il Recycle è dato dalla condizione del Range
        }
       if (NextDw8 && CountDown(i+1)) {CntDw8++; TextMake(8,i+1,CntDw8); NextDw8=false; CDDw8=true; Sell8=false; FirstDw8=iTime(NULL,0,i+1);}               //Inizio Countdown da barra 8 del Setup
       if (Sell8 && CountDown(i)) {CntDw8++; TextMake(8,i,CntDw8); NextDw8=false; CDDw8=true; Sell8=false; FirstDw8=iTime(NULL,0,i);}                       //Setup concluso, attesa Countdown 1
       if (CDDw8 && CountDown(i) && CntDw8>0 && FirstDw8<iTime(NULL,0,i)) {if(CntDw8==8) EightDw8=iClose(NULL,0,i); CntDw8++; TextMake(8,i,CntDw8);}        //Countdown da 2 a 13
       if (CDDw8 && CntDw8==13)   {SignalDw8=iTime(NULL,0,i)+60*Period(); CDDw8=false;}                                                                     //Termine Countdown
       if (!Sell8 && !CDDw8 && CntDw8>0 && (SignalDw8==iTime(NULL,0,i) || (SignalDw8<iTime(NULL,0,i) && iTime(NULL,0,i+1)!=iTime(NULL,0,i)-60*Period())))   //Segnale di acquisto
        {                                //(Candela seguente la 13     ||   Caso di fine settimana)
         CntDw8 = 0;                                             //Azzera il contatore 
         RanDw8Bef = 0;                                          //Azzera il Range precedente (Range Bef serve solo quando un altro setup finisce prima di arrivare a 13)
         if(EightDw8<=iClose(NULL,0,i+1)) TextMake(8,i,"ê");     //Condizione fondamentale rispettata 
         else TextMake(8,i,"+");                                 //Condizione fondamentale fallita
        } 
      } 
      
      
    }             //End For 
   return(0);
  }
//+------------------------------------------------------------------+



//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
//----Validation
bool Validation(int Shift)
 {
  if (Close[Shift]>=Close[Shift+4] && Type=="Up") return(true);
  if (Close[Shift]<=Close[Shift+4] && Type=="Dw") return(true);
  return(false);
 }
//+------------------------------------------------------------------+


//----Counter
int Counter(int Shift)
 {
  int Cnt = 0;
  
  if (Type=="Up")
   {
    for (int i=Shift; i<=Shift+9; i++)
     {
      if (Close[i]<=Close[i+4]) Cnt++;
      else break;
     }
   }
  
  if (Type=="Dw")
   {
    for (i=Shift; i<=Shift+9; i++)
     {
      if (Close[i]>=Close[i+4]) Cnt++;
      else break;
     }
   }
  if (Cnt<7 || Cnt>9) Cnt = 0;
  return(Cnt);
 }
//+------------------------------------------------------------------+


//----Intersection
bool Intersection(int Shift, double Price)
 {
  if (Type=="Up" && High[Shift]>=Price) return(true);
  if (Type=="Dw" && Low [Shift]<=Price) return(true);
  return(false);  
 }
//+------------------------------------------------------------------+


//----CountDown
bool CountDown(int Shift)
 {
  if (Type=="Up" && Close[Shift]<=Low [Shift+2]) return(true);
  if (Type=="Dw" && Close[Shift]>=High[Shift+2]) return(true);
  return(false);  
 }
//+------------------------------------------------------------------+

  
//----TextMake
void TextMake(int Sequential, int Shift, string Text) 
 {
  color    Color;
  string   tmp, Font;
  double   Max, Min, Price, Distance, Distance2;
  datetime TimE;
  
  TimE      = iTime(NULL,0,Shift);
  Distance  = Text_Distance*Point;
  Distance2 = 0.6*Point;
  if (MarketInfo(Symbol(),MODE_DIGITS)==3 || MarketInfo(Symbol(),MODE_DIGITS)==5) {Distance=Distance*10; Distance2=Distance2*10;}
  
  Font = "Arial";
  if (Text=="ê" || Text=="é" || Text=="û") Font = "Wingdings";
  
  Max = High[Shift];
  Min = Low [Shift];
  
  tmp = Prefix+Sequential+Type+Pattern+TimE;
  
  switch (Sequential)
   {
    case 8:
    if (Show_8_13_)
     {
      if (Pattern=="St" && Type=="Up") {Color = LimeGreen;   Price = Min-3*Distance+Distance2;}
      if (Pattern=="St" && Type=="Dw") {Color = Magenta;     Price = Max+3*Distance;}
      if (Pattern=="Cd" && Type=="Up") {Color = DeepSkyBlue; Price = Min-4*Distance+Distance2;}
      if (Pattern=="Cd" && Type=="Dw") {Color = Yellow;      Price = Max+4*Distance;}
     }
    break;
    case 9:
    if (Pattern=="St" && Type=="Up") {Color = DarkGreen;   Price = Min-Distance+Distance2;}
    if (Pattern=="St" && Type=="Dw") {Color = Red;         Price = Max+Distance;}
    if (Pattern=="Cd" && Type=="Up") {Color = Blue;        Price = Min-2*Distance+Distance2;}
    if (Pattern=="Cd" && Type=="Dw") {Color = Orange;      Price = Max+2*Distance;}
    break;
   }
  
  ObjectCreate (tmp,OBJ_TEXT,0,TimE,Price);
  ObjectSetText(tmp,Text,Text_Dimension,Font,Color);
   
 }
//----------------------------------------------- 

//----IsNewBar
bool IsNewBar() 
 {
  static int PrevTime=0;
  if (PrevTime==iTime(NULL,0,0)) return(false);
  PrevTime=iTime(NULL,0,0);
  return(true);
 }
//----------------------------------------------- 