Problem with iBarshift not giving desired index

 

Good day


Here is some code that takes a larger time frame and divides it into 1 minute candles and sums the volume of each of the 1 minute candles. I expected this to equal the same volume of the larger time frame but is seems like the iTime function is sometimes returning the incorrect start time.

When I test the code on the tester it sometimes gives the incorrect volume. But only sometimes.

Can anybody help me with a better and more dependable way?

int barsTotal;

int OnInit(){
   
   barsTotal = 0;
   
   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){
   
}
void OnTick(){
   
   int bars = iBars(_Symbol,PERIOD_CURRENT);
   if(barsTotal != bars){
      barsTotal = bars;
      
      volSum(3,PERIOD_CURRENT,PERIOD_M1);
      DebugBreak();
      
   }
   
}

long volSum(int shift, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, ENUM_TIMEFRAMES countTimeframe = PERIOD_M1){
   
   datetime startTime = iTime(_Symbol,timeframe,shift);
   datetime endTime = startTime + PeriodSeconds(timeframe);
   int startIndex = iBarShift(_Symbol,countTimeframe,startTime,false);
   int endIndex = iBarShift(_Symbol,countTimeframe,endTime,false);
   long volTotal = 0;
   
   Print("startIndex: ",startIndex);
   Print("endIndex: ",endIndex);
   Print(startIndex-endIndex," minutes");
   
   if(startIndex > 0 && endIndex > 0){
      for(int i = startIndex; i >= endIndex  && !IsStopped() ; i--){
         long voli = iVolume(_Symbol,countTimeframe,i);
         volTotal = volTotal + voli;
      }
   }
   Print("volTotal(",volTotal,") = iVolume(",iVolume(_Symbol,timeframe,shift),")");
   return volTotal;
}
 
Louis Fourie:
iBarShift

exact=false

[in]  A return value, in case the bar with the specified time is not found. If exact=false, iBarShift returns the index of the nearest bar, the Open time of which is less than the specified time (time_open<time). If such a bar is not found (history before the specified time is not available), then the function returns -1. If exact=true, iBarShift does not search for a nearest bar but immediately returns -1.

The documentation may help in this case: https://www.mql5.com/en/docs/series/ibarshift

Documentation on MQL5: Timeseries and Indicators Access / iBarShift
Documentation on MQL5: Timeseries and Indicators Access / iBarShift
  • www.mql5.com
iBarShift - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Yashar Seyyedin #:

exact=false

[in]  A return value, in case the bar with the specified time is not found. If exact=false, iBarShift returns the index of the nearest bar, the Open time of which is less than the specified time (time_open<time). If such a bar is not found (history before the specified time is not available), then the function returns -1. If exact=true, iBarShift does not search for a nearest bar but immediately returns -1.

The documentation may help in this case: https://www.mql5.com/en/docs/series/ibarshift

Yes but if you set the exact to true then it sometimes returns -1 instead of the index. This makes the code even less accurate. That is why I was wondering if there is a better way to do this.

 
Louis Fourie #:

Yes but if you set the exact to true then it sometimes returns -1 instead of the index. This makes the code even less accurate. That is why I was wondering if there is a better way to do this.

I suppose what you need to do is actually check the time of the volume-value and decide, if that's supposed to be added to the sum for the higher timeframe.

You need to somehow manage the data alignment more carefully, as the functions will only return what they "can".

Additional logic is required.
 

I made a new function that uses CopyTickVolume and so doesn't need a start or end index but uses start and end datetime but there is still a difference between the volTotal and the iVolume.

How does the iVolume functions calculate its return value? Also how is it there are sometimes 61 minutes in an hour?

long volSum2(int shift, ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT, ENUM_TIMEFRAMES countTimeframe = PERIOD_M1){
   
   datetime startTime = iTime(_Symbol,timeframe,shift);
   datetime endTime = startTime + PeriodSeconds(timeframe);
   long volTotal = 0;
   long volArr[];
   int candleCount = CopyTickVolume(_Symbol,countTimeframe,startTime,endTime,volArr);
   
   Print("startTime: ",startTime);
   Print("endTime: ",endTime);
   Print("Qty of candles counted: ",candleCount);
   
   if(candleCount > 0){
      for(int i = 0; i < candleCount; i++){
         volTotal = volTotal + volArr[i];
      }
   }
   Print("volTotal(",volTotal,") = iVolume(",iVolume(_Symbol,timeframe,shift),") Percent error: ",(1-(double)iVolume(_Symbol,timeframe,shift)/volTotal)*100);
   return volTotal;
}
 
Louis Fourie #:

I made a new function that uses CopyTickVolume and so doesn't need a start or end index but uses start and end datetime but there is still a difference between the volTotal and the iVolume.

How does the iVolume functions calculate its return value? Also how is it there are sometimes 61 minutes in an hour?

I cannot follow your 61 minute claim just by looking at your post, could you please provide sufficient information, such that people can read and relate to what you are stating...

Tick count, and tick volume are two different values. When counting price updates (tick count) you count every change, while volume only counts changes to bid price. - Try a search on the forum, and you will find an explanation for the differences.
 

you need subtract one second

datetime endTime = startTime + PeriodSeconds(timeframe) - 1;
 
Louis Fourie:

Good day


Here is some code that takes a larger time frame and divides it into 1 minute candles and sums the volume of each of the 1 minute candles. I expected this to equal the same volume of the larger time frame but is seems like the iTime function is sometimes returning the incorrect start time.

When I test the code on the tester it sometimes gives the incorrect volume. But only sometimes.

Can anybody help me with a better and more dependable way?

https://www.mql5.com/ru/forum/170952/page234#comment_50523898
 
Dominik Egert #:
I cannot follow your 61 minute claim just by looking at your post, could you please provide sufficient information, such that people can read and relate to what you are stating...

Tick count, and tick volume are two different values. When counting price updates (tick count) you count every change, while volume only counts changes to bid price. - Try a search on the forum, and you will find an explanation for the differences.

Hi Dominik


The 61 minute is the amount of candles copied in the function CopyTickVolume(_Symbol,countTimeframe,startTime,endTime,volArr). Also I never realized there is a difference between tick volume and volume. Very helpful.

But if I change my code as Samuel suggested then it works every time. Thanks for everyone's help. 

 
Samuel Manoel De Souza #:

you need subtract one second

Thanks Samuel this fixes the problem.