iHighest result bar outside the array

 
Hi!

I am trying to make a function to draw daily boxes, when I get the index of the highest candle in a range of candles I get an index that is outside the range. I hope you can understand my problem.

If I want to obtain the highest candle from candle 40 to candle 14, iHighest returns 54, when the correct index would be 32, for example.


void DailyBox(){


   int idxAlto,idxBajo,idxINI, idxFIN;

   int velaD = iBarShift(_Symbol,0,iTime(_Symbol,PERIOD_D1,0));
  
   datetime diaIni,diaFin;
   
   double PA,PB;
   
    
   for(int i=1; i<=Days_Back; i++){
   
      if(i==1){diaIni=Today();diaFin=daysback(1);}

      diaIni=daysback(i-1);
      diaFin=daysback(i);
      
      
      idxINI = iBarShift(_Symbol,PERIOD_CURRENT,diaIni,true);
      idxFIN = iBarShift(_Symbol,PERIOD_CURRENT,diaFin,true);
    
      idxAlto = iHighest(_Symbol,PERIOD_CURRENT,MODE_HIGH,idxFIN,idxINI);
      idxBajo = iLowest (_Symbol,PERIOD_CURRENT, MODE_LOW,idxFIN,idxINI);
      
     PA = iHigh(_Symbol,PERIOD_CURRENT,idxAlto);
     PB = iLow (_Symbol,PERIOD_CURRENT,idxBajo);
      
         ObjectCreate("D1Box_"+i, OBJ_RECTANGLE, 0, diaIni, PA, diaFin, PB);
            ObjectSet("D1Box_"+i, OBJPROP_COLOR, DB_Color );
            ObjectSet("D1Box_"+i, OBJPROP_BACK , rellenoDB );
            ObjectSet("D1Box_"+i, OBJPROP_STYLE, DB_Line_Style );


Print("diaIni: ", diaIni, "  diaFin: ", diaFin, "  idxINI: ", idxINI, "  idxFIN: ", idxFIN,"  idxAlto: ",idxAlto,"  idxBajo: ",idxBajo);

   }
Print("velaD: ",velaD);

}


this is the print output:

Can someone tell me what I'm doing wrong?

 
lehi.salazar:
Hi!

I am trying to make a function to draw daily boxes, when I get the index of the highest candle in a range of candles I get an index that is outside the range. I hope you can understand my problem.

If I want to obtain the highest candle from candle 40 to candle 14, iHighest returns 54, when the correct index would be 32, for example.



this is the print output:

Can someone tell me what I'm doing wrong?

I am not able to debug this code extract as it won't compile, but I would suspect the Days_Back value and daysback(i) are not giving you the right values. 

Have you debugged those to check the are within expected limits? (Test it with a small range first to make it easier to debug)

 
lehi.salazar:

If I want to obtain the highest candle from candle 40 to candle 14, iHighest returns 54, when the correct index would be 32, for example.

iHighest/iLowest count from right to left.

int  iHighest(
   const string        symbol,              // Symbol
   ENUM_TIMEFRAMES     timeframe,           // Period
   ENUM_SERIESMODE     type,                // Timeseries identifier
   int                 count=WHOLE_ARRAY,   // Number of elements
   int                 start=0              // Index
  );

Pay attention to the start and count parameters.

If you had a start value of 0, and a count value of 5, it would start at bar 0, then check bars 0, 1, 2, 3, and 4 (5 in total).

The reason you're getting an unexpected value is because you're thinking it will start at bar 40 and then check bar 40, 39, 38, 37... 14.

 
Yes, you need to write your own iHighest because MQ's doesnt work right.
Look inside Examples/ZigZag code for alternative iHighest/iLowest function.
 
R4tna C #:

I am not able to debug this code extract as it won't compile, but I would suspect the Days_Back value and daysback(i) are not giving you the right values. 

Have you debugged those to check the are within expected limits? (Test it with a small range first to make it easier to debug)

Hello R4tna
Days_Back is the number of days back to draw the boxes and daysback(i) is a function I made to bring back the previous day.
you can compile it with the function, and adjusting the parameters
DB_Color , DBfill, DB_Line_Style to some color and linetype to Solid.

Days_Back and daysback(i) work correctly, the problem is that iHighest returns a value that is outside the range that I set.

here is the daysback function:


datetime daysback(int dias){
        return( iTime(NULL, PERIOD_D1, dias) );   
}
 
lehi.salazar #: Days_Back is the number of days back to draw the boxes and daysback(i) is a function I made to bring back the previous day.
datetime daysback(int dias){
        return( iTime(NULL, PERIOD_D1, dias) );   
}
  1. You could use D1 timeframe, but then you have to deal with 4066 / synchronization issue.

    On MT4: Unless the current chart is that specific symbol(s)/TF(s) referenced, you must handle 4066/4073 errors before accessing candle/indicator values.
              Download history in MQL4 EA - MQL4 programming forum - Page 3 #26.4 (2019)

    On MT5: Unless the current chart is that specific pair/TF, you must synchronize the terminal Data from the Server before accessing candle/indicator values.
              Error 4806 while using CopyBuffer() - Expert Advisors and Automated Trading - MQL5 programming forum #10 (2020)
              Is it mystical?! It is! - Withdraw - Technical Indicators - MQL5 programming forum (2019)
              Timeseries and Indicators Access / Data Access - Reference on algorithmic/automated trading language for MetaTrader 5
              Synchronize Server Data with Terminal Data - Symbols - General - MQL5 programming forum #2 (2018)
              SymbolInfoInteger doesn't work - Symbols - General - MQL5 programming forum (2019)

  2. Instead, you can just find it using the existing timeframe.

    datetime daysback(int dias){
       datetime bod = date();                         // Beginning of the day.
       while(--dias >= 0){
          int iptd=iBarShift(_Symbol,_Period, bod-1); // Previous trading bar.
          bod = date(iTime(_Symbol,_Period, iptd) );  // Previous trading date.
       }
       return bod;
    }
              date/time (2017)
              Find bar of the same time one day ago - MQL4 programming forum (2017)

 
Hello everyone

Thanks for your help, I was finally able to create the daily boxes without using the iHighest function, I did a manual walkthrough for a specific range of time (one day) and it worked perfectly.

I share my code in case it helps someone, you just have to make the adjustments to the input variables.

Greetings and thanks! 

void DailyBox(){



   int idxAlto,idxBajo,idxINI, idxFIN;

   int velaD = iBarShift(_Symbol,0,iTime(_Symbol,PERIOD_D1,0));

   datetime diaIni,diaFin;

   double PA,PB;

   

   for(int i=1; i<=Days_Back; i++){

      PA=0;

      PB=1000;

   

      if(i==1){diaIni=Today();diaFin=daysback(1);}



      diaIni=daysback(i-1);

      diaFin=daysback(i);

      

      idxINI = iBarShift(_Symbol,PERIOD_CURRENT,diaIni,true);

      idxFIN = iBarShift(_Symbol,PERIOD_CURRENT,diaFin,true);

      

      

      for(int a=idxFIN; a>=idxINI;a--){

         if (High[a] > PA){

            PA = High[a];

         }

         

         if (Low[a] < PB){

            PB = Low[a];

         }

      }

         ObjectCreate("D1Box_"+i, OBJ_RECTANGLE, 0, diaIni, PA, diaFin, PB);

            ObjectSet("D1Box_"+i, OBJPROP_COLOR, DB_Color );

            ObjectSet("D1Box_"+i, OBJPROP_BACK , rellenoDB );

            ObjectSet("D1Box_"+i, OBJPROP_STYLE, DB_Line_Style );

   }

}

 
lehi.salazar #:
Hello everyone

Thanks for your help, I was finally able to create the daily boxes without using the iHighest function, I did a manual walkthrough for a specific range of time (one day) and it worked perfectly.

I share my code in case it helps someone, you just have to make the adjustments to the input variables.

Greetings and thanks! 

Maybe I missed something, but why go through all that trouble?

iHighest/iLowest does what you want and it does it in one line of code

In your original example, you just have to set the start param to 14, then set the count param to (40-14) + 1.
 
Alexander Martinez #:

Maybe I missed something, but why go through all that trouble?

iHighest/iLowest does what you want and it does it in one line of code

In your original example, you just have to set the start param to 14, then set the count param to (40-14) + 1.

Hi Alexander

It should work like you said but the iHighest/iLowest resulted in an index outside the specified range so the lines of the boxes did not match the high/low of the range, so I shared the code so that you could compile it and check that the result was wrong. even if you compare the performance of the two functions even with the setting you mention of "you just have to set the start param to 14, then set the count param to (40-14) + 1." You will see that the results are different. Anyway, that's why I share the solution I found in case someone has the same problem.

Using iHihgest/iLowest:




Using manual calculation:



Reason: