//+------------------------------------------------------------------+
//|                                                   OHLC Lines.mq4 |
//|                                                           extraw |
//|                                                extraww@gmail.com |
//+------------------------------------------------------------------+
#property copyright "extraw"
#property link      "extraww@gmail.com"
#property version   "1.01" // auto update when new bar created on other timeframe
#property strict
#property indicator_chart_window

enum Style
{
   Style_Solid       = 0,    //Solid
   Style_Dash        = 1,    //Dash
   Style_Dot         = 2,    //Dot
   Style_DashDot     = 3,    //DashDot
   Style_DashDotDot  = 4     //DashDotDot
};
enum Width
{
   Width_1 = 1,    //1
   Width_2 = 2,    //2
   Width_3 = 3,    //3
   Width_4 = 4,    //4
   Width_5 = 5    //5
};
enum TimeFrame
{
   TF_M1    = PERIOD_M1,    //M1
   TF_M5    = PERIOD_M5,    //M5
   TF_M15   = PERIOD_M15,   //M15
   TF_M30   = PERIOD_M30,   //M30
   TF_H1    = PERIOD_H1,    //H1
   TF_H4    = PERIOD_H4,    //H4
   TF_D1    = PERIOD_D1,    //Daily
   TF_W1    = PERIOD_W1,    //Weekly
   TF_MN1   = PERIOD_MN1,   //Monthly
};
enum OHLC
{
   OHLC_Open   = 0,  //Open
   OHLC_High   = 1,  //High
   OHLC_Low    = 2,  //Low
   OHLC_Close  = 3,  //Close
};

//--- input parameters
input OHLC        TypeOfLines       = 0;
input color       LineColor         = clrBlue;
input Style       LineStyle         = 0;
input Width       LineWidth         = 2;
input bool        LineInBackground  = true;
input TimeFrame   TimeFrameOfLines  = 60;
input int         Lookback_Bars     = 5;

//--- variables
string prefix;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
      prefix = "[OHLC Lines]_" + IntegerToString(TimeFrameOfLines) + "_" + IntegerToString(TypeOfLines) + "_";
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
      if (TimeFrameOfLines <= Period()) return(0);
      if (IsNewBar(TimeFrameOfLines) == false) return(0);   // no new bar, no calculate
      
      //int counted_bars=IndicatorCounted(); //if there are those lines, indicator not update when new bar appear on other timeframe
      //if(counted_bars<0) return(-1);
      
      //delete all old lines to draw new lines, otherwise it won't draw new lines
      DeleteAllLines();      

      double price = 0; 
      datetime dt = 0;
      string name;
            
      for (int i = 0; i <= Lookback_Bars; i++)
      {
         if (TypeOfLines == 0) price = iOpen(NULL, TimeFrameOfLines, i);
         else if (TypeOfLines == 1) price = iHigh(NULL, TimeFrameOfLines, i);
         else if (TypeOfLines == 2) price = iLow(NULL, TimeFrameOfLines, i);
         else if (TypeOfLines == 3) price = iClose(NULL, TimeFrameOfLines, i);
         dt = iTime(NULL, TimeFrameOfLines, i);
         
         name = prefix + IntegerToString(i);
         ObjectCreate(0, name, OBJ_TREND, 0, dt, price, dt + PeriodSeconds((int)TimeFrameOfLines), price);
         ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(0, name, OBJPROP_COLOR, LineColor);
         ObjectSetInteger(0, name, OBJPROP_STYLE, LineStyle);
         ObjectSetInteger(0, name, OBJPROP_WIDTH, LineWidth);
         ObjectSetInteger(0, name, OBJPROP_BACK, LineInBackground);
         ObjectSetInteger(0, name, OBJPROP_RAY, false);
      }
      
      
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   DeleteAllLines();
}
  
//+------------------------------------------------------------------+
//| Check new bar function                                           |
//+------------------------------------------------------------------+
bool IsNewBar(int period)
{
   static datetime oldtime;
   datetime newtime = iTime(NULL, period, 0);
   if (oldtime != newtime)
   {
      oldtime = newtime;
      //printf("newbar");
      return(true);
   }
   return(false);
}

//+------------------------------------------------------------------+
//| Delete all lines function                                        |
//+------------------------------------------------------------------+
void DeleteAllLines()
{
   int obj_total=ObjectsTotal();
   for(int i=obj_total; i>=0; i--)
     {
      string name=ObjectName(i);
      if(StringSubstr(name,0,StringLen(prefix))==prefix)
         ObjectDelete(name);
     }
   return;
}