///////////////////\\\\\\\\\\\\\\\\\\
///////////  MTF_Fractals  \\\\\\\\\\
////////////  Fillellin  \\\\\\\\\\\\
///////////////////\\\\\\\\\\\\\\\\\\

#property     indicator_chart_window
#property     indicator_buffers                                    2
#property     description                                         "© MTF Fractals Alerts & Labels"
#property     copyright		                                       "Copyright © 2019, Alexander Voronkov / Fillellin"
#property     strict
#property     link				                                    "https://www.mql5.com/ru/users/fillellin"

extern string ————————————————————————1———————————————————————— = "————————|  Settings for  TIME-Frame :";
input         ENUM_TIMEFRAMES     TimeFrame                     =  PERIOD_H1;           //  Time Frame:

extern string ————————————————————————2———————————————————————— = "————————|  Settings for  Count Bars :";
input         int                 CountBars                     =  2000;                //  Count Bars:

extern string ————————————————————————3———————————————————————— = "————————|  Settings for  Up Fractals :";
input         color               UpColor                       =  clrNONE;             //  Up Fractal Color:
input         int                 UpSymbol                      =  108;                 //  Up Fractal Symbol:
input         string —————————————————————————————————————————— =  "";
input         color               UpLinColor                    =  clrRed;              //  Up Fractal Extend Line Color:
input         int                 UpLinWidth                    =  0;                   //  Up Fractal Extend Width:
input         ENUM_LINE_STYLE     UpLinStyle                    =  STYLE_SOLID;         //  Up Fractal Extend Style:

extern string ————————————————————————4———————————————————————— = "————————|  Settings for  Down Fractals :";
input         color               DnColor                       =  clrNONE;             //  Down Fractal Color:
input         int                 DnSymbol                      =  108;                 //  Down Fractal Symbol:
input         string —————————————————————————————————————————  =  "";
input         color               DnLinColor                    =  clrBlue;             //  Down Fractal Extend Line Color:
input         int                 DnLinWidth                    =  0;                   //  Down Fractal Extend Width:
input         ENUM_LINE_STYLE     DnLinStyle                    =  STYLE_SOLID;         //  Down Fractal Extend Style:

extern string ————————————————————————5———————————————————————— = "————————|  Settings for  Shift Labels :";
input         int                 ShiftLabel                    =  55;                  //  Shift Labels:

extern string ————————————————————————6———————————————————————— = "————————|  Settings for  Validation Candle :";
input         bool                ShowCandle                    =  false;               //  Show Validation Candle ?

extern string ————————————————————————7———————————————————————— = "————————|  Settings for  Alerts :";
input         bool	             ShowAlert                     =  true;                //  Use signals "Alert" ?
input         bool                SendPush                      =  false;               //  PUSH send messages to your phone ?
input         bool                SendMailInfo                  =  false;               //  Send notifications by e-mail ?
input         bool                ShowSound                     =  false;               //  Use beeps "Sound" ?
input         string              SoundNameBull                 =  "buy.wav";           //  Title signal Buy:
input         string              SoundNameBear                 =  "sell.wav";          //  Title signal Sell:

int           x;
int           y;
double        p;
datetime      d;

string        IndID                                             =  StringConcatenate("© MTF Fractals ",TimeFrame);
double        level;
long          times;
int           limit;
int           timef;

int           heigh;
color         colour;

double        UpBuffer[];
double        DoBuffer[];

bool          upAlerts=false;
bool          dnAlerts=false;

//————————————————————————————|

void OnDeinit(const int reason)
{
   objDelete(IndID);
}

//————————————————————————————|

int OnInit()
{
   SetIndexBuffer(0,UpBuffer);
   SetIndexBuffer(1,DoBuffer);

   SetIndexArrow (0,UpSymbol);
   SetIndexArrow (1,DnSymbol);

   SetIndexStyle (0,DRAW_ARROW,EMPTY,EMPTY,UpColor);
   SetIndexStyle (1,DRAW_ARROW,EMPTY,EMPTY,DnColor);

   return(INIT_SUCCEEDED);
}

//—————————————————————————————————————————————————|

int OnCalculate(const int       rates_total,
                const int       prev_calculated,
                const datetime &time[],
                const double   &open[],
                const double   &high[],
                const double   &low[],
                const double   &close[],
                const long     &tick_volume[],
                const long     &volume[],
                const int      &spread[])
{
//———————————————————————————————————————————|

   ChartSetInteger(0,CHART_FOREGROUND,0,true);

//—————————————————————————————————————————————————|

                               limit=CountBars;
   if(CountBars > rates_total) limit=rates_total-10;

//————————————————————————————————————————————————————————|

                           timef = TimeFrame;
   if(TimeFrame <=_Period) timef =(ENUM_TIMEFRAMES)_Period;
   int             i,c,dif=timef /_Period;

//——————————————————————————————————————————————————————————————————|

          colour =(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND,0);
          heigh =(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
   double WPMax = WindowPriceMax();
   double WPMin = WindowPriceMin();
   double distn = WPMax - WPMin;

//———————————————————————————————————————————————————————————————————————————————|

   for(i = 0; i < limit; i++)
   {
      if(iBarShift(NULL,timef,time[i])< 3)
      {
         UpBuffer[i]= 0;
         DoBuffer[i]= 0;
         continue;
      }
      UpBuffer[i]= iFractals(NULL,timef,MODE_UPPER,iBarShift(NULL,timef,time[i]));
      DoBuffer[i]= iFractals(NULL,timef,MODE_LOWER,iBarShift(NULL,timef,time[i]));
   }

//———————————————————————————————————————————————————————————————————————————————|

   for(i = limit; i >= 0; i--)
   {
      if(UpBuffer[i]> 0)
      {
         level = UpBuffer[i];

         for(c = i; c > 0; c--){if(MathMin(open[c],close[c])< level && MathMax(open[c],close[c])> level) /*levUp=c; */break;}

         Trend(StringConcatenate(i,"_Uu_",UpLinColor),time[i],level,time[c],level,UpLinStyle,UpLinWidth,UpLinColor,StringConcatenate("UPPER LEVEL = ",DoubleToStr(level,_Digits)));

//————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————|

         if(time[c]== time[0])
         {
            Lines(StringConcatenate(0,"_u_",UpLinColor),0,level,UpLinStyle,UpLinWidth,UpLinColor,StringConcatenate("UPPER LEVEL = ",DoubleToStr(level,_Digits)));
            Trend(StringConcatenate(0,"_U_",UpLinColor),0,level,time[i],level,UpLinStyle,UpLinWidth,colour,StringConcatenate("UPPER LEVEL = ",DoubleToStr(level,_Digits)));

            x = 0;
            y = 0;
            d =(datetime)time[0];
            p =(double)level;

            if(ChartTimePriceToXY(0,0,d,p,x,y))

            Bimap(StringConcatenate("Resistance",UpLinColor), CORNER_RIGHT_UPPER, 50+ShiftLabel, y-23, 50, 15, ModColor(UpLinColor), colour, UpLinColor, false, ALIGN_CENTER, "", 9, "Arial Black",
            StringConcatenate(StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7),""), StringConcatenate(StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7)," RES"));
         }

         if(ShowCandle) UpBuffer[i-2*dif]= level;

         i -= dif;         
      }
   }

//———————————————————————————|

   for(i = limit; i >= 0; i--)
   {
      if(DoBuffer[i]> 0)
      {
         level = DoBuffer[i];

         for(c = i; c > 0; c--){if(MathMin(open[c],close[c])< level && MathMax(open[c],close[c])> level) break;}

         Trend(StringConcatenate(i,"_Ll_",DnLinColor),time[i],level,time[c],level,DnLinStyle,DnLinWidth,DnLinColor,StringConcatenate("LOWER LEVEL = ",DoubleToStr(level,_Digits)));

//————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————|

         if(time[c]== time[0])
         {
            Lines(StringConcatenate(0,"_l_",UpLinColor),0,level,DnLinStyle,DnLinWidth,DnLinColor,StringConcatenate("LOWER LEVEL = ",DoubleToStr(level,_Digits)));
            Trend(StringConcatenate(0,"_L_",DnLinColor),0,level,time[i],level,DnLinStyle,DnLinWidth,colour,StringConcatenate("LOWER LEVEL = ",DoubleToStr(level,_Digits)));

            x = 0;
            y = 0;
            d =(datetime)time[0];
            p =(double)level;

            if(ChartTimePriceToXY(0,0,d,p,x,y))

            Bimap(StringConcatenate("Support",DnLinColor), CORNER_RIGHT_UPPER, 50+ShiftLabel, y-23, 50, 15, ModColor(DnLinColor), colour, DnLinColor, false, ALIGN_CENTER, "", 9, "Arial Black",
            StringConcatenate(StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7),""), StringConcatenate(StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7)," - S"));
         }

         if(ShowCandle) DoBuffer[i-2*dif]= level;

         i -= dif;
      }
   }

//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————|

   string name;
   double value=0;

   for(int n = ObjectsTotal()-1; n >= 0; n--)
   {
                    name = ObjectName(n);
      if(StringFind(name , IndID)== 0 && ObjectGet(name,OBJPROP_TIME1)!= time[0]
                                      && ObjectGet(name,OBJPROP_TIME2)== time[0]) value = ObjectGetValueByShift(name,0);

      if(times != time[0]&&(SendMailInfo||ShowAlert||ShowSound||SendPush))
      {
         if(((open[0]< value && high[0]>= value)||(close[1]< value && high[0]>= value))&& upAlerts)
         {
            upAlerts=false;

            if(SendPush)     SendNotification(StringConcatenate(Symbol(), " « ", StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7), " » ( Breaking UP = ", DoubleToStr(value,_Digits), " )"));
            if(SendMailInfo) SendMail(StringConcatenate(AccountCompany(), " ", AccountNumber(), " ", Symbol()),
                             StringConcatenate(" « ", StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7), " » ( Breaking UP = ", DoubleToStr(value,_Digits), " ) ", TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES)));
            if(ShowAlert)    Alert(Symbol(), " « ", StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7), " » ( Breaking UP = ", DoubleToStr(value,_Digits), " )");
            if(ShowSound)    PlaySound(SoundNameBull);
		                       times = time[0];
         }
         if(!upAlerts && high[0]< value) upAlerts=true;

//——————————————————————————————————————————————————————————————————————————————————————————————|

         if(((open[0]> value && low[0]<= value)||(close[1]> value && low[0]<= value))&& dnAlerts)
         {
            dnAlerts=false;

            if(SendPush)     SendNotification(StringConcatenate(Symbol(), " « ", StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7), " » ( Breaking DOWN = ", DoubleToStr(value,_Digits), " )"));
            if(SendMailInfo) SendMail(StringConcatenate(AccountCompany(), " ", AccountNumber(), " ", Symbol()),
                             StringConcatenate(" « ", StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7), " » ( Breaking DOWN = ", DoubleToStr(value,_Digits), " ) ", TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES)));
            if(ShowAlert)    Alert(Symbol(), " « ", StringSubstr(EnumToString((ENUM_TIMEFRAMES)timef),7), " » ( Breaking DOWN = ", DoubleToStr(value,_Digits), " )");
            if(ShowSound)    PlaySound(SoundNameBear);
		                       times = time[0];
         }
         if(!dnAlerts && low[0]> value) dnAlerts=true;
      }
   }

   return(rates_total);
}

//———————————————————————————————————————————————————|

color ModColor(double clr, int i=0)
{
   string strClr=ColorToString((color)clr);
   string strRed,strGreen,strBlue;
   int    cRed,cGreen,cBlue;
   int    pos;
          pos       = StringFind  (strClr,",",0);
          strRed    = StringSubstr(strClr,0,pos);
          strClr    = StringSubstr(strClr,pos+1);
          pos       = StringFind  (strClr,",",0);
          strGreen  = StringSubstr(strClr,0,pos);
          strClr    = StringSubstr(strClr,pos+1);
          strBlue   =              strClr;
          cRed      = StrToInteger(strRed);
          cGreen    = StrToInteger(strGreen);
          cBlue     = StrToInteger(strBlue);
   return           ( StringToColor
                    ( IntegerToString(((int)(cRed  <i?cRed-cRed:cRed-i))/2)+","
                    + IntegerToString(((int)(cGreen<i?cGreen-cGreen:cGreen-i))/2)+","
                    + IntegerToString(((int)(cBlue <i?cBlue-cBlue:cBlue-i))/2)));
}

//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————|

void Bimap(string main, int corn, int posx, int posy, int widh, int pusy, color colir, color colur, color coltr, bool back, int align, string shift, int size, string font, string val, string text)
{
          string name  = StringConcatenate(IndID,"-",main);
   if(ObjectFind(name)!=-1)   ObjectDelete(name);
   {
      ObjectCreate    (0,name,OBJ_EDIT,0,0,0);
      ObjectSetInteger(0,name,OBJPROP_STATE,true);
      ObjectSetInteger(0,name,OBJPROP_XSIZE,widh);
      ObjectSetInteger(0,name,OBJPROP_YSIZE,pusy);
      ObjectSetInteger(0,name,OBJPROP_CORNER,corn);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,colur);
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,1?posx+11:posx-11);
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,posy+11);

      if(val != " ")
      {
         ObjectSetString (0,name,OBJPROP_TEXT,StringConcatenate(shift,val));
         ObjectSetString (0,name,OBJPROP_FONT,font);
         ObjectSetInteger(0,name,OBJPROP_COLOR,coltr);
         ObjectSetInteger(0,name,OBJPROP_ALIGN,align);
         ObjectSetInteger(0,name,OBJPROP_FONTSIZE,size);
         ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,colir);
      }
      else
      {
         ObjectSetString (0,name,OBJPROP_TEXT,NULL);
         ObjectSetInteger(0,name,OBJPROP_COLOR,colir);
      }

      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
      ObjectSetString (0,name,OBJPROP_TOOLTIP,text);
      ObjectSetInteger(0,name,OBJPROP_READONLY,true);
      ObjectSetInteger(0,name,OBJPROP_BACK,back);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
   }
}

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————|

void Trend(string main, datetime time, double price, datetime tami, double prace, int style, int wldth, color colir, string text)
{
            string name = StringConcatenate(IndID,"_",main);
   if(ObjectFind  (name)!=-1)            ObjectDelete(name);
   {
      ObjectCreate(name, OBJ_TREND,0,time,price,tami,prace);
      ObjectSet   (name, OBJPROP_RAY,                    0);
      ObjectSet   (name, OBJPROP_BACK,               false);
      ObjectSet   (name, OBJPROP_STYLE,              style);
      ObjectSet   (name, OBJPROP_WIDTH,              wldth);
      ObjectSet   (name, OBJPROP_COLOR,              colir);
      ObjectSet   (name, OBJPROP_HIDDEN,              true);
      ObjectSetString (0,name,OBJPROP_TOOLTIP,        text);
      ObjectSetInteger(0,name,OBJPROP_SELECTED,      false);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,    false);
   }
}

//—————————————————————————————————————————————————————————————————————————————————————————————————|

void Lines(string main, datetime time, double price, int style, int width, color colir, string text)
{
            string name = StringConcatenate(IndID,"_",main);
   if( ObjectFind (name)!=-1)            ObjectDelete(name);
   {
      ObjectCreate(name, OBJ_HLINE,0,           time,price);
      ObjectSet   (name, OBJPROP_RAY,                 true);
      ObjectSet   (name, OBJPROP_BACK,               false);
      ObjectSet   (name, OBJPROP_STYLE,              style);
      ObjectSet   (name, OBJPROP_WIDTH,              width);
      ObjectSet   (name, OBJPROP_COLOR,              colir);
      ObjectSet   (name,OBJPROP_HIDDEN,               true);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,    false);
      ObjectSetString (0,name,OBJPROP_TOOLTIP,        text);
   }
}

//—————————————————————————————————————————————————————————|

void objDelete(string prefix)
{
       int     objTotals = ObjectsTotal(); string name;
   for(int i = objTotals - 1; i >= 0; i--)
   {                name = ObjectName(i);
      if(StringFind(name , prefix)== 0) ObjectDelete(name);
   }
}

//————————————————| end of the algorithm |————————————————|