A division by zero error appeared in one indicator

 

From the beginning of the week, the terminal began to hang stupidly - I don’t know what to do anymore.

In one indicator there was an error of division by zero - there is a simple delta - the initial date is requested and seconds are added to it and the initial date is subtracted. Before that, the indicator worked stably for half a year.

Where to dig? How to decide?

Code - run on TF below TimeFrames by default, recommended by M1.  

 //+------------------------------------------------------------------+
//|                                                   IndDrafter.mq5 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link        ""
#property version    "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots    1
//----
input int                    IndId = 1 ;                 //номер индикатора
input ENUM_TIMEFRAMES   TimeFrames = PERIOD_H1 ;         //период работы
input bool           UseDeltaPrice = true ;             //разрешение использовать для расчета ширины канала индикатор DeltaPrice
input int                HighPoint = 1000 ;             //фиксированная ширина канала для верхней цены, в пунктах
input int                 LowPoint = 1000 ;             //фиксированная ширина канала для нижней цены, в пунктах
input int             VariantDraft = 6 ;                 //вариант построения графических фигур, 1-8
input int                 BarsUsed = 100 ;                 //количество отображаемых баров, 0-вся история
input int         PeriodDeltaPrice = 3 ;                 //период индикатора DeltaPrice
input bool            UsePriceInfo = true ;             //разрешение вывода показаний положения цены
input ENUM_APPLIED_PRICE     Price = PRICE_CLOSE ;       //тип цены
input bool         UseVerticalLine = true ;             //разрешение вывода вертикальной линии раздела времени
input ENUM_LINE_STYLE   StyleDraft = STYLE_DASH ;       //стиль линии графических фигур
input color            ColorDraft1 = clrLimeGreen ;     //первый цвет линии графических фигур
input color            ColorDraft2 = clrDarkOrchid ;     //второй цвет линии графических фигур
input color            ColorDraft3 = clrDarkTurquoise ; //третий цвет линии графических фигур
input ENUM_DRAW_TYPE StyleBuffer = DRAW_LINE ;         //стиль линии индикатора положения цены
input color            ColorBuffer = clrRed ;           //цвет линии индикатора положения цены
input int              WidhtBuffer = 1 ;                 //ширина линии индикатора положения цены
input bool             UseFiboGrid = true ;             //разрешение накладывать сеть на графические фигуры
input ENUM_LINE_STYLE StyleFiboUp = STYLE_DOT ;         //стиль линий сетки
input color            ColorFiboUp = clrWhite ;         //цвет верхней сетки
input int              WidhtFiboUp = 1 ;                 //ширина линий верхней Fibo сетки
input double             LevelUp01 = 23.6 ;             //значение первого уровня
input double             LevelUp02 = 38.2 ;             //значение второго уровня
input double             LevelUp03 = 50.0 ;             //значение третье уровня
input double             LevelUp04 = 61.8 ;             //значение четвертого уровня
input double             LevelUp05 = 76.4 ;             //значение пятого уровня
input double             LevelUp06 = 100.0 ;             //значение шестого уровня
input double             LevelUp07 = 123.6 ;             //значение седьмого уровня
input double             LevelUp08 = 138.2 ;             //значение восьмого уровня
input double             LevelUp09 = 150.0 ;             //значение девятого уровня
input double             LevelUp10 = 161.8 ;             //значение десятого уровня
input ENUM_LINE_STYLE StyleFiboDn = STYLE_DOT ;         //стиль линий сетки
input color            ColorFiboDn = clrAqua ;           //цвет нижней сетки
input int              WidhtFiboDn = 1 ;                 //ширина линий нижней Fibo сетки
input double             LevelDn01 = 23.6 ;             //значение первого уровня
input double             LevelDn02 = 38.2 ;             //значение второго уровня
input double             LevelDn03 = 50.0 ;             //значение третье уровня
input double             LevelDn04 = 61.8 ;             //значение четвертого уровня
input double             LevelDn05 = 76.4 ;             //значение пятого уровня
input double             LevelDn06 = 100.0 ;             //значение шестого уровня
input double             LevelDn07 = 123.6 ;             //значение седьмого уровня
input double             LevelDn08 = 138.2 ;             //значение восьмого уровня
input double             LevelDn09 = 150.0 ;             //значение девятого уровня
input double             LevelDn10 = 161.8 ;             //значение десятого уровня
                                                     //input uint              InpCenterTime=12;            //время центральной линии
//----
double ExtBuffer[];
//----
double level_up[ 10 ];
double level_dn[ 10 ];
//----
int counted_bars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
   IndicatorSetInteger ( INDICATOR_DIGITS , _Digits );
   IndicatorSetDouble ( INDICATOR_MAXIMUM , 2.05 );
   IndicatorSetDouble ( INDICATOR_MINIMUM ,- 0.05 );
   IndicatorSetString ( INDICATOR_SHORTNAME , "Drafter " + IntegerToString (IndId)+ " " + IntegerToString (VariantDraft));
//----
   SetIndexBuffer ( 0 ,ExtBuffer);
   PlotIndexSetInteger ( 0 , PLOT_DRAW_TYPE ,StyleBuffer);
   PlotIndexSetInteger ( 0 , PLOT_LINE_WIDTH ,WidhtBuffer);
   PlotIndexSetInteger ( 0 , PLOT_LINE_COLOR ,ColorBuffer);
   PlotIndexSetDouble ( 0 , PLOT_EMPTY_VALUE , EMPTY_VALUE );
   PlotIndexSetString ( 0 , PLOT_LABEL , "var " + IntegerToString (VariantDraft));
//----
   counted_bars= 0 ;
   level_up[ 0 ]=LevelUp01;
   level_up[ 1 ]=LevelUp02;
   level_up[ 2 ]=LevelUp03;
   level_up[ 3 ]=LevelUp04;
   level_up[ 4 ]=LevelUp05;
   level_up[ 5 ]=LevelUp06;
   level_up[ 6 ]=LevelUp07;
   level_up[ 7 ]=LevelUp08;
   level_up[ 8 ]=LevelUp09;
   level_up[ 9 ]=LevelUp10;
   level_dn[ 0 ]=LevelDn01;
   level_dn[ 1 ]=LevelDn02;
   level_dn[ 2 ]=LevelDn03;
   level_dn[ 3 ]=LevelDn04;
   level_dn[ 4 ]=LevelDn05;
   level_dn[ 5 ]=LevelDn06;
   level_dn[ 6 ]=LevelDn07;
   level_dn[ 7 ]=LevelDn08;
   level_dn[ 8 ]=LevelDn09;
   level_dn[ 9 ]=LevelDn10;
//----
   ObjectsDeleteAll ( 0 , "IndDrafter tline " + IntegerToString (IndId), 0 );
   ObjectsDeleteAll ( 0 , "IndDrafter triangle " + IntegerToString (IndId), 0 );
   ObjectsDeleteAll ( 0 , "IndDrafter fibo line " + IntegerToString (IndId), 0 );
   ObjectsDeleteAll ( 0 , "IndDrafter fibo text " + IntegerToString (IndId), 0 );
//----
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
   ObjectsDeleteAll ( 0 , "IndDrafter tline " + IntegerToString (IndId), 0 );
   ObjectsDeleteAll ( 0 , "IndDrafter triangle " + IntegerToString (IndId), 0 );
   ObjectsDeleteAll ( 0 , "IndDrafter fibo line " + IntegerToString (IndId), 0 );
   ObjectsDeleteAll ( 0 , "IndDrafter fibo text " + IntegerToString (IndId), 0 );
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   if ( _Period >=TimeFrames) return ( 0 );
   if (prev_calculated== 0 ) counted_bars= 0 ;
//---
   ArraySetAsSeries (time, true );
   ArraySetAsSeries (open, true );
   ArraySetAsSeries (high, true );
   ArraySetAsSeries (low, true );
   ArraySetAsSeries (close, true );
   ArraySetAsSeries (ExtBuffer, true );
//----
   int Bars = Bars ( _Symbol ,TimeFrames);
   int limit= 0 ;
   int pdprice=(UseDeltaPrice?PeriodDeltaPrice: 0 );
   MqlRates rates_array[];
   if (counted_bars== 0 )
     {
       if (BarsUsed> 0 )
         limit= CopyRates ( _Symbol ,TimeFrames,time[ 0 ],BarsUsed+pdprice,rates_array);
       else if (BarsUsed== 0 )
         limit= CopyRates ( _Symbol ,TimeFrames,time[ 0 ], Bars ( _Symbol ,TimeFrames,time[rates_total- 1 ],time[ 0 ])+pdprice,rates_array);
         //limit=CopyRates(_Symbol,TimeFrames,time[rates_total-1],time[0],rates_array);
       if (limit<=pdprice) return ( 0 );
       ArraySetAsSeries (rates_array, true );
       for ( int i=limit-pdprice- 1 ;i>= 0 ;i--)
         CreateFigure(i,time,open,high,low,close,rates_array);
     }
   else
     {
      limit= CopyRates ( _Symbol ,TimeFrames, 0 , Bars -counted_bars+pdprice+ 1 ,rates_array);
       if (limit<=pdprice) return ( 0 );
       ArraySetAsSeries (rates_array, true );
       for ( int i=limit-pdprice- 1 ;i>= 0 ;i--)
         CreateFigure(i,time,open,high,low,close,rates_array);
     }
//----
   counted_bars= Bars ;
   return (rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CreateFigure( int i, const datetime & Time [], const double & Open [], const double & High [], const double & Low [], const double & Close [], MqlRates &rates[])
  {
   datetime start_time=rates[i].time;
   datetime stop_time=(start_time+ PeriodSeconds (TimeFrames));
//---
   int start_index,stop_index,limit;
   datetime vertical_line_time;
//---
   start_index= ArrayBsearch ( Time ,start_time);
   if ( Time [start_index]<start_time) start_index=(start_index> 0 ?start_index- 1 :start_index);
   start_time= Time [start_index];
   if (i> 0 )
     {
      stop_index= ArrayBsearch ( Time ,stop_time);
       if ( Time [stop_index]>stop_time) stop_index++;
      stop_time= Time [stop_index];
      limit=start_index-stop_index+ 1 ;
      vertical_line_time= Time [start_index-(limit>> 1 )];
     }
   else
     {
       if (TimeFrames== PERIOD_MN1 )
        {
         MqlDateTime mql_time;
         TimeToStruct (start_time+ 2678400 ,mql_time);
         int days= 32 -mql_time.day;
         stop_time=start_time+days* 86400 ;
        }
       else if (TimeFrames== PERIOD_W1 ) stop_time-= 86400 ;
      vertical_line_time=start_time+(stop_time-start_time)/ 2 ;
      limit=( int )(stop_time-start_time)/ PeriodSeconds ( _Period );
     }
//---
   double center_line_point=rates[i].open;
   double delta_price_high= 0.0 ;
   double delta_price_low= 0.0 ;
//----
   if (UseDeltaPrice== true )
     {
      delta_price_high=center_line_point+HighPoint* _Point ;
      delta_price_low=center_line_point-LowPoint* _Point ;
     }
//----
   if (UseDeltaPrice== false )
     {
      delta_price_high=center_line_point+HighPoint* _Point ;
      delta_price_low=center_line_point-LowPoint* _Point ;
     }
//----
   if (UseVerticalLine){};
//----
   if (VariantDraft== 6 )
     {
       if (UsePriceInfo== true )
        {
         if (limit/ 2 == 0 )
         {
         //limit=2;
         Print ( "i=" ,i, " start_time - " , TimeToString (start_time, TIME_DATE | TIME_MINUTES ), " stop_time - " , TimeToString (stop_time, TIME_DATE | TIME_MINUTES ));
         Print ( "start_index=" ,start_index, " stop_index=" ,stop_index);
         Print ( "TimeFrames=" , PeriodSeconds (TimeFrames));
         //start_index=ArrayBsearch(Time,start_time);
         }
         double d1=(delta_price_high-center_line_point)/(( double )limit/ 2.0 );
         double d2=(center_line_point-delta_price_low)/(( double )limit/ 2.0 );
         //----
        }
       //----
       if (UseFiboGrid== true )
        {
        }
     }
//----

  }
 
Aleksey Vyazmikin:

Since the beginning of the week, the terminal has been deadlocked - I don't know what to do.

In one indicator a division by zero error has appeared - there is a simple delta - a start date is requested and the seconds are added to it and the start date is subtracted. The indicator was working fine for half a year before that.

Where to dig? How to fix it?

Go through the debugger and see?

Obviously, the division does not check for a possible null value.

 
Aleksey Vyazmikin:

Since the beginning of the week, the terminal has been deadlocked - I don't know what to do.

In one indicator a division by zero error has appeared - there is a simple delta - a start date is requested and the seconds are added to it and the start date is subtracted. The indicator was working fine for half a year before that.

Where to dig? How to fix it?

When such an error occurs, you see the line number and position in it. Check what value is there and check it to 0 before dividing.

 
Georgiy Merts:

Go to the debugger and see?

Obviously, when dividing - there is no check for a possible zero value.

Alexey Kozitsyn:

When this error occurs, you write line number and position in it. See what value is there and check it for 0 before dividing.

Thanks, that's certainly clear - check the division by zero! I'm more concerned about why this zero started occurring, when accessing the date array from the indicator.

 
Aleksey Vyazmikin:

Thanks, that's certainly clear - check the division by zero! I'm more concerned about why this zero is occurring, when accessing the date array from the indicator.

Can you show me an example? Minimum code reproducible problem?

 
Aleksey Vyazmikin:

Thanks, that's certainly clear - check the division by zero! I'm more concerned about why this zero is occurring, when accessing the date array from the indicator.

This is where you need to find out from the code what the denominator is! And why it becomes zero... If it's a date reference, then some date is zeroed out...

 
Aleksey Vyazmikin:

I've also had some of the indicators "float" since the update... I need to find out what's wrong...

 
Vladimir Karputov:

Can you show an example? Minimum code reproducible problem?

The indicator was written to order - everything is tricky there, I'm trying to get the reason myself, but so far I can't...

Here limit becomes zero.TimeFrames==PERIOD_H1

double d1=(delta_price_high-center_line_point)/(limit/2);
void CreateFigure(int i,const datetime &Time[],const double &Open[],const double &High[],const double &Low[],const double &Close[],MqlRates &rates[])
  {
   datetime start_time=rates[i].time;
   datetime stop_time=(start_time+PeriodSeconds(TimeFrames));

   int start_index,stop_index,limit;
   datetime vertical_line_time;

   start_index=ArrayBsearch(Time,start_time);
   if(Time[start_index]<start_time) start_index=(start_index>0?start_index-1:start_index);
   start_time=Time[start_index];
   if(i>0)
     {
      stop_index=ArrayBsearch(Time,stop_time);
      if(Time[stop_index]>stop_time) stop_index++;
      stop_time=Time[stop_index];
      limit=start_index-stop_index+1;
      vertical_line_time=Time[start_index-(limit>>1)];
     }
   else
     {
      if(TimeFrames==PERIOD_MN1)
        {
         MqlDateTime mql_time;
         TimeToStruct(start_time+2678400,mql_time);
         int days=32-mql_time.day;
         stop_time=start_time+days*86400;
        }
      else if(TimeFrames==PERIOD_W1) stop_time-=86400;
      vertical_line_time=start_time+(stop_time-start_time)/2;
      limit=(int)(stop_time-start_time)/PeriodSeconds(_Period);
     }
//--вырезано
}
 
Aleksey Vyazmikin:

The indicator was written to order - it's all tricky, I'm trying to get the cause myself, but so far I can't...

Here limit becomes zero.TimeFrames==PERIOD_H1

Need a minimal code reproducible problem. Not a piece of code.

 
Alexey Kozitsyn:

This is where you need to find out from the code what the denominator is! And why it becomes zero... If it's referring to dates, then some date is zeroed out...

Yes, I need to find out - I was printing dates for half a day yesterday - everything was fine, then I switched off the printer and almost immediately got an error - anomalies...

Above posted the code, can you tell me where to dig?


Alexey Kozitsyn:

I also got some indicators "floating" after the update... need to figure out what's wrong...

Yeah, I can imagine what it must be like for those who, for example, don't understand the code at all.

Reason: