Direction of High and Low prices - no zeros allowed

 

I try to write an indicator which shows the direction of Highs and Lows. It should return 1 for higher values and -1 for lower ones.
In the case of equal highs or equal lows it should neither return 0 (zero), nor EMPTY_VALUEs, but instead return the previous direction (the direction when the highs or lows were unequal). Which means that the only acceptable values are 1 and -1.

I thought it would be quite straightforward, but for unknown reasons the indicator seems to return erratic results when High[i] == High[i+1] or Low[i] == Low[i+1].
For example consider the following sequence of XAUUSD prices (from older to newer) and the corresponding values returned by this indicator (where HiDir represents the direction of Highs and LoDir the direction of Lows.):

Bar 1 : High = 1961.15 Low = 1960.73  ………………………………………..
Bar 2 : High = 1960.76 Low = 1960.58  HiDir = -1 (correct)  LoDir = -1 (correct)
Bar 3 : High = 1960.73 Low = 1960.58  HiDir = -1 (correct)  LoDir = 1 (wrong, it should be -1)   @ 2023.06.09  23:24 (5 minute chart)

My code is this:
#property strict
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  White
#property indicator_width1  3
#property indicator_style1  3
#property indicator_color2  Magenta
#property indicator_width2  2
#property indicator_style2  3


  
//-------------------------------------------------------------------
double H0, H1, L0, L1;
double HiDir[], LoDir[];

//----------------------------------------------------------

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorBuffers(2);
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,HiDir,INDICATOR_DATA);
   SetIndexLabel(0,"HiDir");
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(1,LoDir,INDICATOR_DATA);
   SetIndexLabel(1,"LoDir");



IndicatorDigits(Digits);

//---
   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[])
  {
//---
  int    Hi_PreviousDir, Lo_PreviousDir;
  
   int limit;
   limit=rates_total-prev_calculated;
   if(prev_calculated==0)limit++;
  
   for(int i=0; i<limit-1 ;i++)
   {
    
     H0 = High[i];
     H1 = High[i+1];
     L0 = Low[i];
     L1 = Low[i+1];
      
     if (H0 != H1)
     {
      if (H1>H0) {HiDir[i] = -1; Hi_PreviousDir = -1;} //last direction of highs
      if (H1<H0) {HiDir[i] = 1; Hi_PreviousDir = 1;}   //last direction of highs
     }
     else HiDir[i] = Hi_PreviousDir;
     
     if (L0 != L1)
     {
      if (L1>L0) { LoDir[i] = -1; Lo_PreviousDir = -1;} //last direction of lows
      if (L1<L0) {LoDir[i] = 1; Lo_PreviousDir = 1;}   //last direction of lows
     }
     else LoDir[i] = Lo_PreviousDir; 
       
    }
    
  
  //--- return value of prev_calculated for next call
   return(rates_total);
  }
 
BBad:

I try to write an indicator which shows the direction of Highs and Lows. It should return 1 for higher values and -1 for lower ones.
In the case of equal highs or equal lows it should neither return 0 (zero), nor EMPTY_VALUEs, but instead return the previous direction (the direction when the highs or lows were unequal). Which means that the only acceptable values are 1 and -1.

I thought it would be quite straightforward, but for unknown reasons the indicator seems to return erratic results when High[i] == High[i+1] or Low[i] == Low[i+1].
For example consider the following sequence of XAUUSD prices (from older to newer) and the corresponding values returned by this indicator (where HiDir represents the direction of Highs and LoDir the direction of Lows.):

Bar 1 : High = 1961.15 Low = 1960.73  ………………………………………..
Bar 2 : High = 1960.76 Low = 1960.58  HiDir = -1 (correct)  LoDir = -1 (correct)
Bar 3 : High = 1960.73 Low = 1960.58  HiDir = -1 (correct)  LoDir = 1 (wrong, it should be -1)   @ 2023.06.09  23:24 (5 minute chart)

My code is this:
 static int    Hi_PreviousDir, Lo_PreviousDir;
 
Thanks, but this changed  nothing. In the example I gave the results remain the same.
 
BBad #: Thanks, but this changed  nothing. In the example I gave the results remain the same.
I didn't see this.

   for(int i=1; i<limit ;i++)
   {
    
     H0 = high[i-1];
     H1 = high[i];
     L0 = low[i-1];
     L1 = low[i];
      
     if (H0 != H1)
     {
      if (H0>H1) {HiDir[i] = -1;} //last direction of highs
      if (H0<H1) {HiDir[i] = 1;}   //last direction of highs
     }
     else HiDir[i] = HiDir[i-1];
     
     if (L0 != L1)
     {
      if (L0>L1) {LoDir[i] = -1;} //last direction of lows
      if (L0<L1) {LoDir[i] = 1;}   //last direction of lows
     }
     else LoDir[i] = LoDir[i-1]; 
       
    }

The question is, how do you initialize the first value, as you do not have a bar high[-1]?
 
Dominik Christian Egert #: I didn't see this. The question is, how do you initialize the first value, as you do not have a bar high[-1]?
Doesn't [i-1] refer to the future? In this case, if High[i] == High[i+1]  the  indicator would not return the previous direction, but a future one.
 
BBad #: Doesn't [i-1] refer to the future? In this case, if High[i] == High[i+1]  the  indicator would not return the previous direction, but a future one.
No, not that I am aware.

I cannot see any ArrayAsSeries in your code.

EDIT: I just saw, it's in MQL4 section and now I am not sure if the arrays are in series mode... Maybe you want to check the time array to see.

Anyways, the logic stays the same, you will just need to apply ArrayAsSeries accordingly. Or you turn around the logic, and also adjust your for loop to go backwards.

Whatever the solution is you are going to use, you need to make sure, you are doing it consistently. Either, or, but not mixed.
 
Dominik Christian Egert #:
No, not that I am aware.

I cannot see any ArrayAsSeries in your code.

EDIT: I just saw, it's in MQL4 section and now I am not sure if the arrays are in series mode... Maybe you want to check the time array to see.

Anyways, the logic stays the same, you will just need to apply ArrayAsSeries accordingly. Or you turn around the logic, and also adjust your for loop to go backwards.

Whatever the solution is you are going to use, you need to make sure, you are doing it consistently. Either, or, but not mixed.

Correct me if I am wrong, but unless otherwise defined we work with Timeseries. And with Timeseries i+1 always means a bar back, while i-1 means a bar forward (future).
In my approach I use Timeseries. So, i-1 must be wrong as it references a future value.
If I was to use arrays then i-1 would make sense to me.
If the above are all wrong, I fear I have not understood many things regarding MQL4, which is quite probable I regret to say.

 
BBad #:

Correct me if I am wrong, but unless otherwise defined we work with Timeseries. And with Timeseries i+1 always means a bar back, while i-1 means a bar forward (future).
In my approach I use Timeseries. So, i-1 must be wrong as it references a future value.
If I was to use arrays then i-1 would make sense to me.
If the above are all wrong, I fear I have not understood many things regarding MQL4, which is quite probable I regret to say.

Please use the debugger and check.

I have no access to MT4 at the moment, sorry.
 
Dominik Christian Egert #:
Please use the debugger and check.

I have no access to MT4 at the moment, sorry.
No problem. Thanks.
 
Anyone else with an idea please?
 

Your are building your indicator buffers in the wrong direction :

   for(int i=0; i<limit-1 ;i++)
You should go from past to present, not the reverse.

Your "previous" is from the future.