//+------------------------------------------------------------------+
//|                                                 MTF_Fractals.mq4 |
//|                                           aquaart at forexfactory|
//+------------------------------------------------------------------+

#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Maroon
#property indicator_color2 DarkOliveGreen
#property indicator_color3 FireBrick
#property indicator_color4 DarkGreen
#property indicator_color5 Red
#property indicator_color6 Green
#property indicator_color7 DarkOrange
#property indicator_color8 LimeGreen

//---- input parameters

//---- buffers
/*
double ExtMapBufferMN1_1[];
double ExtMapBufferMN1_2[];
double ExtMapBufferW1_1[];
double ExtMapBufferW1_2[];
*/
double ExtMapBufferD1_1[];
double ExtMapBufferD1_2[];
double ExtMapBufferH4_1[];
double ExtMapBufferH4_2[];
double ExtMapBufferH1_1[];
double ExtMapBufferH1_2[];
double ExtMapBufferM30_1[];
double ExtMapBufferM30_2[];
/*
double ExtMapBufferM15_1[];
double ExtMapBufferM15_2[];
double ExtMapBufferM5_1[];
double ExtMapBufferM5_2[];
*/

int j;
extern double FractalDistInPoints=24;
extern bool Alerter=false;
static int AlertOnce=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
// If u want different timeframes, I had problems getting this to work for M15 or M5...

// If u want different timeframes the highest timeframe needs to be in the D1_1 & D1_2 buffers and 2nd highest timeframe in the H4_1 & H4_2 buffers etc....
/*
   SetIndexStyle(0,DRAW_ARROW,0,5);
   SetIndexDrawBegin(0,j-1);
   SetIndexBuffer(0,ExtMapBufferMN1_1);
   SetIndexLabel(0,"Upper Fractal MN1");
   SetIndexArrow(0, 217);
   SetIndexStyle(1,DRAW_ARROW,0,5);
   SetIndexDrawBegin(1,j-1);
   SetIndexBuffer(1,ExtMapBufferMN1_2);
   SetIndexLabel(1,"Lower Fractal MN1");
   SetIndexArrow(1, 218);
OR
   SetIndexStyle(0,DRAW_ARROW,0,5);
   SetIndexDrawBegin(0,j-1);
   SetIndexBuffer(0,ExtMapBufferW1_1);
   SetIndexLabel(0,"Upper Fractal W1");
   SetIndexArrow(0, 217);
   SetIndexStyle(1,DRAW_ARROW,0,5);
   SetIndexDrawBegin(1,j-1);
   SetIndexBuffer(1,ExtMapBufferW1_2);
   SetIndexLabel(1,"Lower Fractal W1");
   SetIndexArrow(1, 218);
*/
   SetIndexStyle(0,DRAW_ARROW,0,5);
   SetIndexDrawBegin(0,j-1);
   SetIndexBuffer(0,ExtMapBufferD1_1);
   SetIndexLabel(0,"Upper Fractal D1");
   SetIndexArrow(0, 217);
   SetIndexStyle(1,DRAW_ARROW,0,5);
   SetIndexDrawBegin(1,j-1);
   SetIndexBuffer(1,ExtMapBufferD1_2);
   SetIndexLabel(1,"Lower Fractal D1");
   SetIndexArrow(1, 218);
   SetIndexStyle(2,DRAW_ARROW,0,4);
   SetIndexDrawBegin(2,j-1);
   SetIndexBuffer(2,ExtMapBufferH4_1);
   SetIndexLabel(2,"Upper Fractal H4");
   SetIndexArrow(2, 217);
   SetIndexStyle(3,DRAW_ARROW,0,4);
   SetIndexDrawBegin(3,j-1);
   SetIndexBuffer(3,ExtMapBufferH4_2);
   SetIndexLabel(3,"Lower Fractal H4");
   SetIndexArrow(3, 218);
   SetIndexStyle(4,DRAW_ARROW,0,3);
   SetIndexDrawBegin(4,j-1);
   SetIndexBuffer(4,ExtMapBufferH1_1);
   SetIndexLabel(4,"Upper Fractal H1");
   SetIndexArrow(4, 217);
   SetIndexStyle(5,DRAW_ARROW,0,3);
   SetIndexDrawBegin(5,j-1);
   SetIndexBuffer(5,ExtMapBufferH1_2);
   SetIndexLabel(5,"Lower Fractal H1");
   SetIndexArrow(5, 218);
   SetIndexStyle(6,DRAW_ARROW,0,2);
   SetIndexDrawBegin(6,j-1);
   SetIndexBuffer(6,ExtMapBufferM30_1);
   SetIndexLabel(6,"Upper Fractal M30");
   SetIndexArrow(6, 217);
   SetIndexStyle(7,DRAW_ARROW,0,2);
   SetIndexDrawBegin(7,j-1);
   SetIndexBuffer(7,ExtMapBufferM30_2);
   SetIndexLabel(7,"Lower Fractal M30");
   SetIndexArrow(7, 218);
/*
   SetIndexStyle(6,DRAW_ARROW,0,2);
   SetIndexDrawBegin(6,j-1);
   SetIndexBuffer(6,ExtMapBufferM15_1);
   SetIndexLabel(6,"Upper Fractal M15");
   SetIndexArrow(6, 217);
   SetIndexStyle(7,DRAW_ARROW,0,2);
   SetIndexDrawBegin(7,j-1);
   SetIndexBuffer(7,ExtMapBufferM15_2);
   SetIndexLabel(7,"Lower Fractal M15");
   SetIndexArrow(7, 218);

OR

   SetIndexStyle(6,DRAW_ARROW,0,2);
   SetIndexDrawBegin(6,j-1);
   SetIndexBuffer(6,ExtMapBufferM5_1);
   SetIndexLabel(6,"Upper Fractal M5");
   SetIndexArrow(6, 217);
   SetIndexStyle(7,DRAW_ARROW,0,2);
   SetIndexDrawBegin(7,j-1);
   SetIndexBuffer(7,ExtMapBufferM5_2);
   SetIndexLabel(7,"Lower Fractal M5");
   SetIndexArrow(7, 218);
*/   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//------------------------------------------------------------------  
bool Fractal (string M,int P, int shift)
  {
   if (Period()>P)
      return(-1);
   
   P=P/Period()*2+MathCeil(P/Period()/2);
   
   if (shift<P)
      return(-1);
   if (shift>Bars-P)
      return(-1); 
   
   for (int i=1;i<=P;i++)
      {
      if (M=="U")
        {
         if (High[shift+i]>High[shift])
            return(-1);
         if (High[shift-i]>=High[shift])
            return(-1);     
        }
      if (M=="L")
        {
         if (Low[shift+i]<Low[shift])
            return(-1);
         if (Low[shift-i]<=Low[shift])
            return(-1);
        }        
      }
      return(1);   
  }  
//------------------------------------------------------------------
int start()
  {

// If u want different timeframes, I had problems getting this to work for M15 or M5...

// If u want different timeframes the highest timeframe needs to be in the D1_1 & D1_2 buffers and 2nd highest timeframe in the H4_1 & H4_2 buffers etc....  
  
   int /*M5=5, M15=15,*/M30=30, H1=60, H4=240, D1=1440 /*, W1=10080, MN1=43200*/;
   int /*Upper_Fractal_M5, Upper_Fractal_M15,*/Upper_Fractal_M30, Upper_Fractal_H1, Upper_Fractal_H4, Upper_Fractal_D1,/*Upper_Fractal_W1, Upper_Fractal_MN1,*//*Lower_Fractal_M5, Lower_Fractal_M15*/ Lower_Fractal_M30, Lower_Fractal_H1, Lower_Fractal_H4, Lower_Fractal_D1/*, Lower_Fractal_W1, Lower_Fractal_MN1*/;
   j=Bars;

      while(j>=0)

      {
      
/*
       if (Fractal("U",MN1,j)==1)
            {
            ExtMapBufferMN1_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_MN1=ExtMapBufferMN1_1[j];
            }

       if (Fractal("L",MN1,j)==1)
            {
            ExtMapBufferMN1_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_MN1=ExtMapBufferMN1_2[j];
            }       

OR 

       if (Fractal("U",W1,j)==1)
            {
            ExtMapBufferW1_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_W1=ExtMapBufferW1_1[j];
            }
       
       if (Fractal("L",W1,j)==1)
            {
            ExtMapBufferW1_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_W1=ExtMapBufferW1_2[j];
            }
*/
      
       if (Fractal("U",D1,j)==1)
            {
            ExtMapBufferD1_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_D1=ExtMapBufferD1_1[j];
            }

       if (Fractal("L",D1,j)==1)
            {
            ExtMapBufferD1_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_D1=ExtMapBufferD1_2[j];
            }       
 
       if (Fractal("U",H4,j)==1)
            {
            ExtMapBufferH4_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_H4=ExtMapBufferH4_1[j];
            }
       
       if (Fractal("L",H4,j)==1)
            {
            ExtMapBufferH4_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_H4=ExtMapBufferH4_2[j];
            }
       
       if (Fractal("U",H1,j)==1)
            {
            ExtMapBufferH1_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_H1=ExtMapBufferH1_1[j];
            }
       
       if (Fractal("L",H1,j)==1)
            {
            ExtMapBufferH1_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_H1=ExtMapBufferH1_2[j];
            }
       
       if (Fractal("U",M30,j)==1)
            {
            ExtMapBufferM30_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_M30=ExtMapBufferM30_1[j];
            }
       
       if (Fractal("L",M30,j)==1)
            {
            ExtMapBufferM30_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_M30=ExtMapBufferM30_2[j];
            }
/*
       if (Fractal("U",M15,j)==1)
            {
            ExtMapBufferM15_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_M15=ExtMapBufferM15_1[j];
            }

       if (Fractal("L",M15,j)==1)
            {
            ExtMapBufferM15_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_M15=ExtMapBufferM15_2[j];
            }       

OR
 
       if (Fractal("U",M5,j)==1)
            {
            ExtMapBufferM5_1[j]=High[j]+FractalDistInPoints*Point;
            Upper_Fractal_M5=ExtMapBufferM5_1[j];
            }
       
       if (Fractal("L",M5,j)==1)
            {
            ExtMapBufferM5_2[j]=Low[j]-FractalDistInPoints*Point;
            Lower_Fractal_M5=ExtMapBufferM5_2[j];
            }
*/


       j--;
      }


/* Alerts are not operational, to get MTF alerts working seems to be a little more difficult than doing normal alerts*/

if (AlertOnce!=Bars && Alerter==true)
{
if (Upper_Fractal_M30<High[0] && Upper_Fractal_M30>Low[0])
    {
    Alert(Symbol(),"  M30   High Upper Fractal Hit  ",Bid,"   Prepare for BUY Trade");
    AlertOnce=Bars;
    }

if (Lower_Fractal_M30<High[0] && Lower_Fractal_M30>Low[0])
    {
    Alert(Symbol(),"  M30    Low Lower Fractal Hit   ",Bid,"    Prepare for SELL Trade");
    AlertOnce=Bars;
    }


if (Upper_Fractal_H1<High[0] && Upper_Fractal_H1>Low[0])
    {
    Alert(Symbol(),"  H1    High Upper Fractal Hit    ",Bid,"     Prepare for BUY Trade");
    AlertOnce=Bars;
    }


if (Lower_Fractal_H1<High[0] && Lower_Fractal_H1>Low[0])
    {
    Alert(Symbol(),"  H1     Low Lower Fractal Hit    ",Bid,"     Prepare for SELL Trade");
    AlertOnce=Bars;
    }


if (Upper_Fractal_H4<High[0] && Upper_Fractal_H4>Low[0])
    {
    Alert(Symbol(),"  H4     High Upper Fractal Hit    ",Bid,"     Prepare for BUY Trade");
    AlertOnce=Bars;
    }


if (Lower_Fractal_H4<High[0] && Lower_Fractal_H4>Low[0])
    {
    Alert(Symbol(),"  H4     Low Lower Fractal Hit    ",Bid,"     Prepare for SELL Trade");
    AlertOnce=Bars;
    }


if (Upper_Fractal_D1<High[0] && Upper_Fractal_D1>Low[0])
    {
    Alert(Symbol(),"  D1    High Upper Fractal Hit    ",Bid,"     Prepare for BUY Trade");
    AlertOnce=Bars;
    }

if (Lower_Fractal_D1<High[0] && Lower_Fractal_D1>Low[0])
    {
    Alert(Symbol(),"  D1    Low Lower Fractal Hit    ",Bid,"     Prepare for SELL Trade");
    AlertOnce=Bars;
    }

}
   return(0);
}
//+------------------------------------------------------------------+