//+------------------------------------------------------------------+
//|                                              PipMoved HLOC MTF.mq4     |
//|                                                   BlueRain       |
//|                                       V2.1 Developed by BlueRain | 
//+------------------------------------------------------------------+

//v1.1  10/4/2020 Added Start time


#property copyright "BlueRain"
#property link      ""
#property version   "2.00"
#property strict
#property indicator_chart_window

string INDI_NAME="PipMovedHLCO-";

input string UniqueID = ".";


input ENUM_TIMEFRAMES TimeFrame = PERIOD_D1;
input int NoOfPeriod = 5;

input bool ShowTimeColume = false; //Show Timeformat for Candle Index
input bool Enable_Show_Filtered_TimeCol  = false;
input int  Filtered_Hour = 8;
input int  Filtered_Min = 0;



input int FontSize=12;  //Font Size
input string FontName="Calibri"; //Font Name
input  color  FontColor = clrBlue;
input color PositivePipColor = clrGreen;
input color NegativePipColor = clrRed;

input int  Xposition = 300;
input int  Yposition  = 0;
input int  SpaceBetweenCol = 50;
input int  SpaceBetweenRow = 15;


string Sessionconfig = "----Session Stat Options --";
bool  ShowSessionStats = false;
datetime  SessionStartTime = D'02:00'; 
datetime  SessionEndTime = D'11:00';  




string LabelID = "PipMovedHLOC:"; 
  
 
double Poin;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  
   if (Point==0.00001) Poin=0.0001;
   else {
      if (Point==0.001) Poin=0.01;
      else Poin=Point;
   }
   
   LabelID = LabelID + UniqueID; 

   return(INIT_SUCCEEDED);
  }
//+-------------------------------------------------------------------------------------------+
int deinit()
  {
   deleteObjects();
   return(0);
  }
  
  
    
void deleteObjects()
{
   string lookFor       = LabelID;
   int    lookForLength = StringLen(lookFor);
   for (int i=ObjectsTotal()-1; i>=0; i--)
   {
      string objectName = ObjectName(i);
         if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
   }
}


  
  
//+------------------------------------------------------------------+
//| 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[])
  {
  
       //header
       
       deleteObjects();
         
       DrawHeader();
       
      
       int startY = Yposition+SpaceBetweenRow;
      int currentYRow = 0;
      currentYRow = startY;
      int rowcount = 0;
   
      
       for(int barcount = 0; barcount < NoOfPeriod; barcount++)
       {
          currentYRow = startY + rowcount*SpaceBetweenRow;
         
         //if fixed hour is enabled, 
         if ( Enable_Show_Filtered_TimeCol )
         {
            MqlRates rt[];
            CopyRates(Symbol(),TimeFrame,barcount,1,rt);
         
            if ( TimeHour(rt[0].time) == Filtered_Hour && TimeMinute(rt[0].time) == Filtered_Min)
            {
               DrawPIpChangedRange(TimeFrame,barcount,Xposition,currentYRow);
               rowcount++;
               
            }
          
         }
         else
         {
    
          DrawPIpChangedRange(TimeFrame,barcount,Xposition,currentYRow);
          rowcount++;
         }
         
       }
       
      
      int startbarindex = 0;
      int endbarindex = 0;
      
      if (ShowSessionStats)
      {
      
             currentYRow = DrawSessionHeader(Xposition,currentYRow);
            
              // DrawLabel(LabelID +  "StartTime",Xposition,Yposition+SpaceBetweenRow,"Candle Start Time : " + TimeToStr(StartTime), FontSize,FontName,FontColor);
             ENUM_TIMEFRAMES TF = TimeFrame;
             if (TF >= PERIOD_H4) TF = PERIOD_H1;
             
             startbarindex = iBarShift(Symbol(),TF,SessionStartTime);
             endbarindex = iBarShift(Symbol(),TF,SessionEndTime);
             
             int barrange = MathAbs(endbarindex - startbarindex); 
             
             MqlRates rt[];
             int copied = CopyRates(Symbol(),TF, endbarindex + 1, barrange,rt);  
        
            
            if ( copied > 0)
            {
                   
                  double openprice = rt[0].open;
                  
                  double closeprice = rt[copied - 1].close;
                  
                 
               
                  double highest = GetHighestPrice(rt);
                  double lowest  = GetLowestPrice(rt);
                  double range = MathAbs(highest - lowest)/Poin;
         
                  //draw data
               
                 startY = currentYRow + SpaceBetweenRow*2;
                 DrawSessionHLOCRange(Xposition, startY, openprice,highest,lowest,closeprice, range);
                 
                 
              }
              
            
        
       }
      
      
      
      
      
      
       
       WindowRedraw();
       
//--- return value of prev_calculated for next call
   return(rates_total);
  }

void DrawHeader()
{

   int dx = Xposition;
   
      DrawLabel(LabelID +  "HeaderCount",dx,Yposition,TF2Str(TimeFrame), FontSize,FontName,FontColor);
   
   
     if (ShowTimeColume)
   {  
   
   dx = dx + SpaceBetweenCol+75;
   DrawLabel(LabelID +  "HeaderOP",dx,Yposition,"OP/P", FontSize,FontName,FontColor);
   
   }
   else
   {
   dx = dx + SpaceBetweenCol-20;
   DrawLabel(LabelID +  "HeaderOP",dx,Yposition,"OP/P", FontSize,FontName,FontColor);
   }
   
     dx = dx + SpaceBetweenCol+27;
   DrawLabel(LabelID +  "HeaderOC",dx,Yposition,"OP/C", FontSize,FontName,FontColor);

   
   
     dx = dx + SpaceBetweenCol;
   DrawLabel(LabelID +  "HeaderOL",dx,Yposition,"OP/L", FontSize,FontName,FontColor);


  dx = dx + SpaceBetweenCol;
   DrawLabel(LabelID +  "HeaderOH",dx,Yposition,"OP/H", FontSize,FontName,FontColor);

   dx = dx + SpaceBetweenCol;
   DrawLabel(LabelID +  "HeaderHL",dx,Yposition,"TOTAL", FontSize,FontName,FontColor);


 //  DrawLabel(LabelID +  "Header_Line",Xposition,Yposition+SpaceBetweenRow,"------------------------------------------", FontSize,FontName,FontColor);
 
 
 }

 

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
color GetRangeColor(double range)
  {
   if(range<0)
      return NegativePipColor;
   
   return PositivePipColor;
  }

color GetCandleColor(double open, double close )
  {
   if( open > close)
      return NegativePipColor;
   
   return PositivePipColor;
  }




//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double getRange(string symbol,int period)
  {
   int DataPeriod=PERIOD_D1;
   int DataBar=iBarShift(symbol,DataPeriod,Time[0]);
   double range = iHigh(symbol, period, DataBar) - iLow(symbol, period, DataBar);
   double point = MarketInfo(symbol, MODE_POINT);
   if(point > 0) return (NormalizeDouble(range / point, 0));
   return 1;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawPipRangeHeader(ENUM_TIMEFRAMES timeframe, int barcount, int x, int y)
  {
     
   DrawPIpChangedRange(timeframe,barcount, x,y);
     
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawPIpChangedRange(ENUM_TIMEFRAMES timeframe, int barcount, int x,int y)
  {
  
   int dx=x;
   color timeColor;
   double PipRange;
   double CandleRange;
    
   
    MqlRates rt[];
    CopyRates(Symbol(),timeframe,barcount,1,rt);
   
   
   //bar count
   dx=dx;
   if (ShowTimeColume)
   {   
   DrawLabel(LabelID +  IntegerToString(barcount) + "DC",dx,y,TimeToStr(rt[0].time), FontSize-1,FontName,GetRangeColor(rt[0].close - rt[0].open));
   dx = dx + 90;
   }
   else
   {
   DrawLabel(LabelID +  IntegerToString(barcount) + "DC",dx,y,IntegerToString(barcount+1), FontSize,FontName,FontColor);
   }
   
   // open   
   dx = dx+SpaceBetweenCol - 20;
   PipRange = rt[0].open;
   DrawLabel(LabelID +  IntegerToString(barcount) + "OP",dx,y,RightJustified(5,DoubleToStr(PipRange,4)), FontSize,FontName,GetRangeColor(rt[0].close - rt[0].open));
 
  
   //open - close
   dx=dx+SpaceBetweenCol + 30;
   PipRange = (rt[0].close - rt[0].open)/Poin;
   DrawLabel(LabelID +  IntegerToString(barcount) + "OC",dx,y,RightJustified(5,DoubleToStr(PipRange,0)), FontSize,FontName,GetRangeColor(PipRange));
  
    
   //Open - low
   dx=dx+SpaceBetweenCol;
   PipRange = (rt[0].low - rt[0].open)/Poin;
   DrawLabel(LabelID +  IntegerToString(barcount) + "OL" ,dx,y,RightJustified(5,DoubleToStr(PipRange,0)), FontSize,FontName,GetRangeColor(PipRange));
   
   //Open - high
    dx=dx+SpaceBetweenCol;
   PipRange = (rt[0].high - rt[0].open)/Poin;
   DrawLabel(LabelID +  IntegerToString(barcount) +"OH",dx,y,RightJustified(6,DoubleToStr(PipRange,0)), FontSize,FontName,GetRangeColor(PipRange));
   

   //High - low
   dx=dx+SpaceBetweenCol;
   PipRange = (rt[0].high - rt[0].low)/Poin;
   CandleRange = (rt[0].close - rt[0].open)/Poin;
   DrawLabel(LabelID +  IntegerToString(barcount)+"HL",dx,y,RightJustified(7,DoubleToStr(PipRange,0)), FontSize,FontName,GetRangeColor(CandleRange));
  
  

  }

 
 int DrawSessionHeader(int X, int Y)
{

   int dx = X;
   int dy = Y + SpaceBetweenRow*2;
   
   DrawLabel(LabelID +  "Sessionst",dx,dy,"S: " + TimeToStr(SessionStartTime), FontSize,FontName,FontColor);
   
   dx = dx + SpaceBetweenCol + 100;
   
   DrawLabel(LabelID +  "Sessionet",dx,dy,"E: " + TimeToStr(SessionEndTime), FontSize,FontName,FontColor);
   
   //next line
   dy = dy + SpaceBetweenRow;

   dx = X;
   DrawLabel(LabelID +  "SessionOpen",dx,dy,"O", FontSize,FontName,FontColor);
   
   
   dx = dx + SpaceBetweenCol+10;
   DrawLabel(LabelID +  "SessionHigh",dx,dy,"H", FontSize,FontName,FontColor);


  dx = dx + SpaceBetweenCol+10;
   DrawLabel(LabelID +  "SessionLow",dx,dy,"L", FontSize,FontName,FontColor);

   dx = dx + SpaceBetweenCol+10;
   DrawLabel(LabelID +  "SessionClose",dx,dy,"C", FontSize,FontName,FontColor);
   
   dx = dx + SpaceBetweenCol+10;
   DrawLabel(LabelID +  "Sessiontotal",dx,dy,"TOTAL", FontSize,FontName,FontColor);
   
   

  return dy;
 
 
 }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawSessionHLOCRange(int x,int y, double open,double high, double low,  double close, double range)
 {
  
   int dx=x;
   int dy = y;
   double candlerange; 
       
   
   //bar count
   dx=x ;
   dy = dy;
    DrawLabel(LabelID +  "sessiono" ,dx,dy,DoubleToStr(open,4), FontSize,FontName,FontColor);
   
   
   // high   
   dx = dx+SpaceBetweenCol+10;
   DrawLabel(LabelID +  "sessionh" ,dx,dy,DoubleToStr(high,4), FontSize,FontName,FontColor);
   
  // low  
   dx = dx+SpaceBetweenCol+10;
  DrawLabel(LabelID +  "sessionl" ,dx,dy,DoubleToStr(low,4), FontSize,FontName,FontColor);
  
  
  // close  
   dx = dx+SpaceBetweenCol+10;
   DrawLabel(LabelID +  "sessionc" ,dx,dy,DoubleToStr(close,4), FontSize,FontName,FontColor);
  
  // range  
   dx = dx+SpaceBetweenCol+10;
   candlerange = (open - close)/Poin;
   
   DrawLabel(LabelID +  "sessionr" ,dx,dy,DoubleToStr(range,2), FontSize,FontName,GetRangeColor(candlerange));
  
   
  
  

  }

string RightJustified(int length, string text)
{
   int lookForLength = StringLen(text);
   string blank  = " ";
   string tempstring = text;
   
   while ( lookForLength < length )
   {
       tempstring = blank + tempstring;
       lookForLength = StringLen(tempstring);
   }
 
 return(tempstring);  
}


double GetHighestPrice(MqlRates &rt[])
{

  double highest = rt[0].high;
  
  for ( int n = 0; n <= ArraySize(rt) - 1; n++)
  {
     
      if ( highest < rt[n].high )
           highest = rt[n].high;
   
   }
   
   return ( highest);
   
 }


double GetLowestPrice(MqlRates &rt[])
{

  double lowest = rt[0].low;;
  
  for ( int n = 0; n <= ArraySize(rt) - 1; n++)
  {
     
      if ( lowest > rt[n].low )
           lowest = rt[n].low;
   
   }
   
   return ( lowest);
   
 }



double GetPipChangedRange(int period)
{

  double PipRange;
  
  MqlRates rt;
  rt.open = iOpen(Symbol(),period,0);
  rt.close  = iClose(Symbol(),period,0);
  
  PipRange = (rt.close - rt.open)/Poin;
  
return PipRange;

}

 
  
//+------------------------------------------------------------------+

void DrawLabel(string name,int x,int y,string label,int size=9,string font="Arial",color clr=DimGray,string tooltip="")
  {
   
   ObjectDelete(name);
   ObjectCreate(name,OBJ_LABEL,0,0,0);
   ObjectSetText(name,label,size,font,clr);
   ObjectSet(name,OBJPROP_CORNER,0);
   ObjectSet(name,OBJPROP_XDISTANCE,x);
   ObjectSet(name,OBJPROP_YDISTANCE,y);
   ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);
//--- justify text
//ObjectSet(name, OBJPROP_ANCHOR, 0);
//ObjectSetString(0, name, OBJPROP_TOOLTIP, tooltip);
//ObjectSet(name, OBJPROP_SELECTABLE, 0);
//---
  }
//+------------------------------------------------------------------+
//| The function sets chart background color.                        |
//+------------------------------------------------------------------+
bool ChartColorSet(int prop_id,const color clr,const long chart_ID=0)
  {
//--- reset the error value
   ResetLastError();
//--- set the chart background color
   if(!ChartSetInteger(chart_ID,prop_id,clr))
     {
      //--- display the error message in Experts journal
      Print(__FUNCTION__+", Error Code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//| Set chart display type (candlesticks, bars or                    |
//| line).                                                           |
//+------------------------------------------------------------------+
bool ChartModeSet(const long value,const long chart_ID=0)
  {
//--- reset the error value
   ResetLastError();
//--- set property value
   if(!ChartSetInteger(chart_ID,CHART_MODE,value))
     {
      //--- display the error message in Experts journal
      Print(__FUNCTION__+", Error Code = ",GetLastError());
      return(false);
     }
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+

double getPoint(string symbol)
  {
   return MarketInfo(symbol,MODE_POINT);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double getModifier(string symbol)
  {
   int digits=(int)MarketInfo(symbol,MODE_DIGITS);
   double modifier=1;
   if(digits==3 || digits==5)
      modifier=10.0;
   return modifier;
  }




//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string TF2Str(int nperiod)
  {
   switch(nperiod)
     {
      case PERIOD_M1: return("M1");
      case PERIOD_M5: return("M5");
      case PERIOD_M15: return("M15");
      case PERIOD_M30: return("M30");
      case PERIOD_H1: return("H1");
      case PERIOD_H4: return("H4");
      case PERIOD_D1: return("D1");
      case PERIOD_W1: return("W1");
      case PERIOD_MN1: return("MN");
     }
     
        if (Period() == PERIOD_M1)  return("M1");
     if (Period() == PERIOD_M5) return("M5");
     if (Period() == PERIOD_M15) return("M15");
     if (Period() == PERIOD_M30) return("M30");
     if (Period() == PERIOD_H1) return("H1");
     if (Period() == PERIOD_H4) return("H4");
     if (Period() == PERIOD_D1) return("D1");
     if (Period() == PERIOD_W1) return("W1");
     if (Period() == PERIOD_MN1) return("MN");
     
   return((string)Period());
  }
//+------------------------------------------------------------------+


