//+------------------------------------------------------------------+
//|                                                         veg2.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 2
#property indicator_color1 FireBrick
#property indicator_color2 FireBrick

extern int ADRperiod = 10;

double ADRhigh[], ADRlow[]; 

double adr_high = 0, adr_low = 0, adr = 0, todays_open = 0, todays_high = 0, todays_low = 0, today_range = 0, last_high = 0, last_low = 0, price = 0;
int cnt = 0, prev_day = 0, cur_day = 0, D1shift;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorBuffers(2);
   IndicatorDigits(Digits);
   
   SetIndexBuffer (0, ADRhigh);
   SetIndexBuffer (1, ADRlow);
   
   SetIndexStyle (0, DRAW_LINE,2);
   SetIndexStyle (1, DRAW_LINE,2);
   
   SetIndexDrawBegin(0,0);
   SetIndexDrawBegin(1,0);
   
   SetIndexLabel(0,"ADRhigh");
   SetIndexLabel(1,"ADRlow");
//---
   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[])
  {
//---
   bool adr_reached = false, lastreached;
   
   
   //loop through history to collect data
   for (cnt = Bars - ADRperiod; cnt >= 0 ;cnt--) {
   
   //bool adr_reached = false, lastreached;
   cur_day = TimeDay(Time[cnt]);
   //Print("PrevDay = ",prev_day, "; CurrDay = ",cur_day);
   //Print("BarTime = ",TimeToStr(iTime(Symbol(),0,cnt),TIME_DATE|TIME_MINUTES));
      
      
   //Acquire the high/low of the 'previous' day to get the actual range of 'previous' (both historical and realtime 'today')
      if (prev_day != cur_day) {
         
         //get todays open
            todays_open = Open[cnt];
                  
         //reset day hi/lo values from the day before        
            todays_high = Open[cnt];
            todays_low = Open[cnt];
         
         //get shift of D1 candle we are currently in
            D1shift = iBarShift(Symbol(),PERIOD_D1,Time[cnt]);
         
         //get the D1 ATR1 for said day (need to find which D1 candle the current candle belongs to??)
            adr = NormalizeDouble(iATR(Symbol(),PERIOD_D1,ADRperiod,D1shift+1),Digits);
            //Print("ADR = ",adr, " @ ",  TimeToStr(Time[cnt],TIME_DATE|TIME_MINUTES));
             
         //calculate initial ADR from daily open
            adr_high= todays_open + adr;
            adr_low= todays_open - adr;
            
         //reset ADR-limit vs price-range variables because it's a new day
            adr_reached = false;
            lastreached = adr_reached;
         
         //remember this day as the 'current' day     
            prev_day = cur_day;
      }
      
      //Check current high/low/close at cnt against stored high/low of the day and recalculate the ADR limits accordingly     
      for (int k= 0; k<3; k++) {
         
            switch (k) {
               case 0: price= NormalizeDouble(Low[cnt],Digits); break;
               case 1: price= NormalizeDouble(High[cnt],Digits); break;
               case 2: price= NormalizeDouble(Close[cnt],Digits); break;
            }
            
            //stored the current high/low for checking against new high/low in adr adjustment
               last_high= todays_high;
               last_low= todays_low;
            
            //remember if ADR has been reached for this day
               lastreached= adr_reached;
            
            //get new high/low price for the day (if it exists)      
               todays_high= MathMax(todays_high, price);
               todays_low= MathMin(todays_low, price);
            
            //calculate todays range
               today_range= NormalizeDouble(todays_high - todays_low,Digits);
            
            //calculate if the adr limit has been reached
               adr_reached = today_range >= (adr - Point/2);   // "Point/2" to avoid rounding problems (double variables)
         
         
            // adr-high (adjustments for current price action)
            if (!lastreached && !adr_reached) {
               adr_high= todays_low + adr;
            }
            else
            if (!lastreached && adr_reached && price>=last_high) {
               adr_high= todays_low + adr;
            }
            else
            if (!lastreached && adr_reached && price<last_high) {
               adr_high= last_high;
            }
            else {
               adr_high= adr_high;
            }
         

            // adr-low (adjustments for current price action)
            if (!lastreached && !adr_reached) {
               adr_low= todays_high - adr;
            }
            else
            if (!lastreached && adr_reached && price>=last_low) {
               adr_low= todays_low;
            }
            else
            if (!lastreached && adr_reached && price<last_low) {
               adr_low= last_high - adr;
            }
            else {
               adr_low= adr_low;
            }
      } //end current price switch loop
   
   //write values to buffers
      ADRhigh[cnt] = adr_high;
      ADRlow[cnt] = adr_low;   
  
  } //end history scan
 //--- return value of prev_calculated for next call
   return(rates_total);
  }
  //Fin