Alert when bar breaks current daily high/low

 

Hello,


How can I, in an indicator, detect when the current bar closes and breaks the current daily high/low?

I need to check when a bar closes, if it breaks the daily high/low so far, from the first daily bar to the last bar (not counting the current bar).

If I use "

iHigh(NULL,PERIOD_D1,0)

I will get the highest value of the current day including the current bar. But I need the highest value, up to the last bar, to check if the last bar has surpassed the level.


Thanks

 

Below is an example:

   double close[];

//--- Sets indexing for the array like in timeseries
   if(!ArraySetAsSeries(close, true))
     {
      Print(__FUNCTION__, " - Error indexing CLOSE array like in timeseries.");
      return;
     }

//--- Sets the size of the array
   if(ArrayResize(close, 3) < 0)
     {
      Print(__FUNCTION__, " - Error setting CLOSE array size.");
      return;
     }

//--- Gets historical data of the bar prices
   if(CopyClose(_Symbol, _Period, 0, 3, close) < 0)
     {
      Print(__FUNCTION__, " - Failed to copy data from CLOSE prices.");
      return;
     }

//--- High and Low of the previous candle (D1)
   double HiD1 = iHigh(_Symbol, PERIOD_D1, 1);
   if(HiD1 == 0.0)
     {
      Print(__FUNCTION__, " - Error getting the previous day's high: ", GetLastError());
      return;
     }
   double LoD1 = iLow(_Symbol, PERIOD_D1, 1);
   if(LoD1 == 0.0)
     {
      Print(__FUNCTION__, " - Error getting the previous day's low: ", GetLastError());
      return;
     }

//--- Checks whether there was a daily breakout upwards
   if(close[2] <= HiD1 && close[1] > HiD1)
     {
      // . . .
     }

//--- Checks whether there was a daily breakout downwards
   if(close[2] >= LoD1 && close[1] < LoD1)
     {
      // . . .
     }
 
Vinicius Pereira De Oliveira #:

Below is an example:

thanks, but I think you are comparing price with high and low of yesterday. I need compare with highest and lowest price of today, from first bar of today to last bar before current one

thanks
 
powerbucker #thanks, but I think you are comparing price with high and low of yesterday. I need compare with highest and lowest price of today, from first bar of today to last bar before current one thanks

Ah, I see... In this case, you can use the iBarShift function to identify the index of the first candle of the day; then work with the iHighest and iLowest functions to identify the candle indices with the highest and lowest prices of the day; then iHigh and iLow... Try implementing it, if you have problems, show your attempt and describe the difficulty to get help.

 
#property strict
#property indicator_chart_window

#define _prcToStr(a) DoubleToString(a, _Digits)

void OnDeinit(const int reason)
  {
   Comment("");
  }

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(rates_total == prev_calculated)
      return(rates_total);
#ifdef __MQL5__
        ArraySetAsSeries(high, true);
        ArraySetAsSeries(low, true);
        ArraySetAsSeries(time, true);
#endif 
   int idxHigh, idxLow;
   if(!find(idxHigh, idxLow, high, low, time))
     {
      Comment("Looks like today consists of one unformed bar");
      return(rates_total);
     }
   Comment(StringFormat("High %s %s\nLow %s %s", _prcToStr(high[idxHigh]), TimeToString(time[idxHigh]), _prcToStr(low[idxLow]), TimeToString(time[idxLow])));
   return(rates_total);
  }

bool find(int &idxHigh, int &idxLow, const double &high[], const double &low[], const datetime &dt[])
  {
   idxHigh = -1;
   idxLow = -1;
   MqlDateTime time;
   if(!dtToStruct(dt[0], time))
      return(false);
   int dayOfYear = time.day_of_year;
   int limit = ArraySize(dt);
   for(int i = 1; i < limit; i++)
     {
      if(!dtToStruct(dt[i], time))
         return(false);
      if(time.day_of_year != dayOfYear)
         break;
      if(idxHigh == -1 || high[i] > high[idxHigh])
         idxHigh = i;
      if(idxLow == -1 || low[i] < low[idxLow])
         idxLow = i;
     }
   return(idxHigh != -1 && idxLow != -1); // Although it is enough to check one of the variables
  }

bool dtToStruct(datetime a_dt,MqlDateTime &var)
  {
   ResetLastError();
   if(TimeToStruct(a_dt, var))
      return(true);
   PrintFormat("%s error %i, value %I64i", __FUNCTION__, GetLastError(), a_dt);
   return(false);
  }
 

Vladislav Boyko #:

#ifdef __MQL5__
        ArraySetAsSeries(high, true);
        ArraySetAsSeries(low, true);
        ArraySetAsSeries(time, true);
#endif 

This is a lazy way because I am used to writing for MT4.

You can flip indexing for MT5 instead of changing the AS_SERIES flag. But I'm too lazy to do this😄

 
thanks !!
 
There is iHighest and iLowest...you can use this within iHigh and iLow
 
Conor Mcnamara #:
There is iHighest and iLowest...you can use this within iHigh and iLow

I can't stand either of them😄

[edit]

Especially in indicators. The terminal transfers already prepared prices to OnCalculate. Why do you need these terrible functions?

 
Vladislav Boyko #:

I can't stand either of them😄

[edit]

Especially in indicators. The terminal transfers already prepared prices to OnCalculate. Why do you need these terrible functions?

Well they have a purpose. It makes life easier, no?
I could make the donchian channels in just 2 lines of code using iHighest and iLowest
 
powerbucker detect when the current bar closes and breaks the current daily high/low?

Rethink. If the current bar breaks the current daily, the current daily has changed.