//+------------------------------------------------------------------+
//|                                                   4 Bar Indi.mq4 |
//|                                          Mahadi Hasan Razu, 2021 |
//|                      https://www.mql5.com/en/users/hermesmercury |
//+------------------------------------------------------------------+
#property copyright "Mahadi Hasan Razu, 2021"
#property link      "https://www.mql5.com/en/users/hermesmercury"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers   4

#property indicator_color1 clrLimeGreen
#property indicator_color2 clrLimeGreen
#property indicator_color3 clrRed
#property indicator_color4 clrRed

#property indicator_width1 0 //UpArrow
#property indicator_width2 1
#property indicator_width3 0 //dnArrow
#property indicator_width4 1

input bool             SoundAlert             = false;
input bool             ShowInfoLabel          = false;
input int              InfoLabelWindow        = 0;
input ENUM_BASE_CORNER InfoLabelCorner        = CORNER_RIGHT_LOWER;
input int              InfoLabelX             = 9;
input int              InfoLabelY             = 9;
input color            InfoLabelNeutralColor  = clrGray;
input color            InfoLabelBuyColor      = clrLimeGreen;
input color            InfoLabelSellColor     = clrMagenta;
input string           InfoLabelFontType      = "Tahoma";
input int              InfoLabelFontSize      = 36;
input string           InfoLabelNeutralText   = "Wait";
input string           InfoLabelBuyText       = "Buy";
input string           InfoLabelSellText      = "Sell";


double up[], up_dot[];
double down[], down_dot[];

static datetime prevtime=0;
double Range,AvgRange;

string LabelName = "4_Bar_Indi_InfoLabel";
int    LabelAnchor;
int    AnchorForCornerLeftUpper = ANCHOR_LEFT_UPPER;
int    AnchorForCornerLeftLower = ANCHOR_LEFT_LOWER;
int    AnchorForCornerRightUpper = ANCHOR_RIGHT_UPPER;
int    AnchorForCornerRightLower = ANCHOR_RIGHT_LOWER;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,up);
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,225);
   SetIndexLabel(0,"Buy");

   SetIndexBuffer(1,up_dot);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,159);
   SetIndexLabel(1,"Buy");

   SetIndexBuffer(2,down);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,226);
   SetIndexLabel(2,"Sell");

   SetIndexBuffer(3,down_dot);
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexArrow(3,159);
   SetIndexLabel(3,"Sell");

   SetIndexDrawBegin(0,10);
   SetIndexDrawBegin(1,10);
   SetIndexDrawBegin(2,10);
   SetIndexDrawBegin(3,10);

   IndicatorSetString(INDICATOR_SHORTNAME,"4 Bar");

   if(ChartGetInteger(0,CHART_FOREGROUND))
      ChartSetInteger(0,CHART_FOREGROUND,false);
      
   if(InfoLabelCorner==CORNER_LEFT_LOWER)
    LabelAnchor=AnchorForCornerLeftLower;
   if(InfoLabelCorner==CORNER_LEFT_UPPER)
    LabelAnchor=AnchorForCornerLeftUpper;
   if(InfoLabelCorner==CORNER_RIGHT_LOWER)
    LabelAnchor=AnchorForCornerRightLower;
   if(InfoLabelCorner==CORNER_RIGHT_UPPER)
    LabelAnchor=AnchorForCornerRightUpper;
   
   if(ShowInfoLabel)
   CreateLabel(LabelName,InfoLabelNeutralText,InfoLabelWindow,InfoLabelCorner,InfoLabelX,InfoLabelY,InfoLabelFontSize,InfoLabelFontType,InfoLabelNeutralColor,false,LabelAnchor);
//---

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
 ObjectDelete(0,LabelName);
 }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---

   int i = 1;

   if(rates_total>prev_calculated)
      while(i <= rates_total-prev_calculated)
        {
         // Arrow Place Space -------------------------------
         int counter=i;
         Range=0;
         AvgRange=0;

         if(i+9 < rates_total)
            for(counter=i; counter<=i+9; counter++)
              {
               AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
              }
         Range=AvgRange/10;

         // -----------------------------------------------
         if(i+3 < rates_total)
           {
            if(Close[i]>Open[i] && Close[i]>High[i+1] && Close[i]>High[i+3])
              {
               up[i] = Low[i]-Range*0.5;
               up_dot[i] = Close[i];
              }

            if(Close[i]<Open[i] && Close[i]<Low[i+1] && Close[i]<Low[i+3])
              {
               down[i] = High[i]+Range*0.5;
               down_dot[i] = Close[i];
              }
           }

         i++;

        }

// Signal Alert -------------------------
   if(up[1]!=EMPTY_VALUE)
     {
      if(SoundAlert && prevtime!=Time[0])
       {
      prevtime=Time[0];
      Alert(Symbol()," 4 Bar Buy");
      //PlaySound ("alert.wav");
       }
      if(ObjectFind(LabelName)>=0)
       {
       ObjectSetString(0,LabelName,OBJPROP_TEXT,InfoLabelBuyText);
       ObjectSetInteger(0,LabelName,OBJPROP_COLOR,InfoLabelBuyColor);
       }
     }
   else
   if(down[1]!=EMPTY_VALUE)
     {
      if(SoundAlert && prevtime!=Time[0])
       {
      prevtime=Time[0];
      Alert(Symbol()," 4 Bar Sell");
      //PlaySound ("alert.wav");
       }
      if(ObjectFind(LabelName)>=0)
       {
       ObjectSetString(0,LabelName,OBJPROP_TEXT,InfoLabelSellText);
       ObjectSetInteger(0,LabelName,OBJPROP_COLOR,InfoLabelSellColor);
       }
     }
    else
     {
      if(ObjectFind(LabelName)>=0)
       {
       ObjectSetString(0,LabelName,OBJPROP_TEXT,InfoLabelNeutralText);
       ObjectSetInteger(0,LabelName,OBJPROP_COLOR,InfoLabelNeutralColor);
       }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
void CreateLabel(string name,string t,int wdw,ENUM_BASE_CORNER crnr,int x,int y,int ftsi,string font,color c,bool back,int a)
  {   
      if(ObjectFind(0,name)<0)                           
       ObjectCreate(0,name,OBJ_LABEL,wdw,0,0); 
       ObjectSetInteger(0,name,OBJPROP_COLOR,c);
       ObjectSetInteger(0,name,OBJPROP_ANCHOR,a);
       ObjectSetInteger(0,name,OBJPROP_BACK,back); 
       ObjectSetInteger(0,name,OBJPROP_CORNER,crnr);
       ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
       ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y); 
       ObjectSetInteger(0,name,OBJPROP_FONTSIZE,ftsi); 
       ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false); 
  } 
//+------------------------------------------------------------------+
