Zero divide time frame dependent

 

Hello all,

I was puzzled why the indicator below did not update on the M1 time frame - the error message was 'zero divide'. However the print statement showed the variable 'volume' to have a positive value.

I then watched the M5 time frame which updated perfectly as did all the other time frames.

Essentially it is only the M1 time frame that does not update because it is getting a zero value (from somewhere!) for the 'volume'.

Can anybody offer an explanation please?

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Green
#property indicator_color2 Red

//---- buffers
double BuyBuffer[], SellBuffer[];
double spread, ndigit;
//long volume;  
double volume;    


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexBuffer(0,BuyBuffer);
   SetIndexStyle(0,DRAW_HISTOGRAM,EMPTY,2);
   SetIndexBuffer(1,SellBuffer);
   SetIndexStyle(1,DRAW_HISTOGRAM,EMPTY,2);
   
   //set base line level
   SetLevelValue(0,0);
   SetLevelStyle(STYLE_DOT,1);
   //set value if empty
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   
   //compensate for different digit brokers
   if(Digits == 4 || Digits == 5)ndigit = 0.0001;
   else if(Digits == 3 || Digits == 2)ndigit = 0.01;  
//----
   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int limit;
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
  
   for(int i=1; i<limit; i++)
   {
    //volume = Volume[i];
    volume = MathAbs(iOBV(NULL,0,PRICE_CLOSE,i));
    Print(volume);
    spread = (High[i] - Low[i])/ndigit;
   
    if(Open[i] < Close[i]){BuyBuffer[i]  = spread/volume; SellBuffer[i] = 0.0;}
    else {SellBuffer[i] = spread/volume; BuyBuffer[i] = 0.0;}
   }
//----
   return(0);
  }

If I use volume = Volume[i] there is no problem on any time frame!

 

May be it's because after the switch of the TF the new values of the OBV are not yet calculated.

Make a check like:

volume = MathAbs(iOBV(NULL,0,PRICE_CLOSE,i));
if (volume <= 0.001 ) return(0); // it's a double, instead of sleep return and wait for the next tick..
 
Carl Schreiber:

May be it's because after the switch of the TF the new values of the OBV are not yet calculated.

Make a check like:

OK but without switching TF on a new bar on the M1 there is nothing  - so lets say I leave it on the M1 for 5 minutes there will be 5 blank spaces (no bars) in the indicator window - if I change TF to M5 then immediately back to M1 everything has been updated.

It is not updating dynamically on the M1 TF.

 
sd59:

Hello all,

I was puzzled why the indicator below did not update on the M1 time frame - the error message was 'zero divide'. However the print statement showed the variable 'volume' to have a positive value.

I then watched the M5 time frame which updated perfectly as did all the other time frames.

Essentially it is only the M1 time frame that does not update because it is getting a zero value (from somewhere!) for the 'volume'.

Can anybody offer an explanation please?

If I use volume = Volume[i] there is no problem on any time frame!

Have you checked the calculation of iOBV()? If it's the same as https://www.mql5.com/en/code/7997, then it is inherent that the return values can range from negative to positive, and zero is definitely possible (and the chance of it hitting zero on M1 timeframe is much higher than other timeframes given it's smaller volume every bar).

On Balance Volume
On Balance Volume
  • www.mql5.com
On Balance Volume Technical Indicator (OBV) is a momentum technical indicator that relates volume to price change. The indicator, which Joseph Granville came up with, is pretty simple. When the security closes higher than the previous close, all of the day’s volume is considered up-volume. When the security closes lower than the previous close...
 

Seng is correct... But don't even bother trying to work out why you get the Zero Divide error... just stop it from happening by giving the OBV value a value of 0.000001... something like this:

if(volume == 0) then volume  = 0.0000001;

That's what I do whenever I get the Zero Divide issue... and it works for me...

Edit: It normally happens on the start of a new candle... the OBV goes to Zero.... and then the code gets tripped up

...sorry... was thinking aloud...

if(volume == 0) volume = 0.000001;
 
Mike Tanton:

Don't even bother trying to work out why you get the Zero Divide error... just stop it from happening by giving the OBV value a value of 0.000001... something like this:

That's what I do whenever I get the Zero Divide issue... and it works for me...

Edit: It normally happens on the start of a new candle... the OBV goes to Zero.... and then the code gets tripped up

...sorry... was thinking aloud...

Thanks for the suggestions guys - OBV definitely has negative values which is why I have the MathAbs function in place - while I was running my indicator I also has the OBV indicator loaded in a separate window and there was no way it got a zero value as it was laying in a positive value range.

This is the output in the experts tab where the value is from the print statement.


It's weird if I simply change 'volume' to equal the real volume (i.e Volume[i])) then there isn't a problem.

 
sd59:

Thanks for the suggestions guys - OBV definitely has negative values which is why I have the MathAbs function in place - while I was running my indicator I also has the OBV indicator loaded in a separate window and there was no way it got a zero value as it was laying in a positive value range.

This is the output in the experts tab where the value is from the print statement.


It's weird if I simply change 'volume' to equal the real volume (i.e Volume[i])) then there isn't a problem.

That's because the "real" Volume indicator can but doesn't generally go to "exact" zero on the change of a candle... but if the markets are going "sideways" then the OBV does... and that's when it trips up your code... just use the...

if(volume == 0) volume = 0.00001;

...trick and get on with things...

Edit: sorry... I'm not being sarcastic here... it's just... you know
 
Mike Tanton:

That's because the "real" Volume indicator can but doesn't generally go to "exact" zero on the change of a candle... but if the markets are going "sideways" then the OBV does... and that's when it trips up your code... just use the...

...trick and get on with things...

Edit: sorry... I'm not being sarcastic here... it's just... you know

Yep agreed I will do that if I continue to use the OBV. 

Can you explain the printout though? The OBV value is not zero just before the buffer calc?

 
sd59: It's weird if I simply change 'volume' to equal the real volume (i.e Volume[i])) then there isn't a problem.

Why do you think that's weird? You will never get a tick with zero (tick) volume.

 
William Roeder:

Why do you think that's weird? You will never get a tick with zero (tick) volume.

I wondered when you might appear! 

This wasn't done today it was done when the markets were open and there ticks galore!!! And your point is...?

 

...take it easy sd59... Roeders' point is that the Volume (not your OBV - volume) will probably never be "exactly" zero.. 0.000000... I think

PS: this trick does not only work for the OBV... whenever I get a Zero Divide... I check the relevance of it and then just over-ride it...

Go for it...

Edit:... try not to piss Roeder off...lol
Reason: