Uma divisão por erro zero apareceu em um indicador

Aleksey Vyazmikin  

Desde o início da semana, o terminal começou a travar estupidamente - não sei mais o que fazer.

Em um indicador, apareceu um erro de divisão por zero - há um delta simples - a data inicial é solicitada e os segundos são adicionados a ela e a data inicial é subtraída. Antes disso, o indicador funcionava de forma estável por meio ano.

Onde cavar? Como decidir?

Código - por padrão executado em TF abaixo de TimeFrames, recomendado por 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 )
        {
        }
     }
//----

  }
Georgiy Merts  
Aleksey Vyazmikin:

Desde o início da semana, o terminal está bloqueado - não sei o que fazer.

Em um indicador surgiu uma divisão por erro zero - há um delta simples - uma data de início é solicitada e os segundos são adicionados a ela e a data de início é subtraída. O indicador estava funcionando bem por meio ano antes disso.

Onde eu cavo? Como consertá-lo?

Passe pelo depurador e veja?

Obviamente, a divisão não verifica um possível valor nulo.

[Excluído]  
Aleksey Vyazmikin:

Desde o início da semana, o terminal está bloqueado - não sei o que fazer.

Em um indicador surgiu uma divisão por erro zero - há um delta simples - uma data de início é solicitada e os segundos são adicionados a ela e a data de início é subtraída. O indicador estava funcionando bem por meio ano antes disso.

Onde cavar? Como consertá-lo?

Quando tal erro ocorre, você vê o número da linha e a posição na mesma. Verifique qual é o valor e verifique o valor a 0 antes de dividir.

Aleksey Vyazmikin  
Georgiy Merts:

Vá até o depurador e veja?

Obviamente, ao dividir - não há verificação de um possível valor zero.

Alexey Kozitsyn:

Quando este erro ocorre, você escreve o número da linha e a posição na mesma. Veja qual é o valor e verifique qual é o 0 antes de dividir.

Obrigado, isso é certamente claro - verifique a divisão por zero! Estou mais preocupado com a razão pela qual este zero começou a ocorrer, ao acessar a matriz de datas a partir do indicador.

Vladimir Karputov  
Aleksey Vyazmikin:

Obrigado, isso é certamente claro - verifique a divisão por zero! Estou mais preocupado com o motivo deste zero, ao acessar a matriz de datas a partir do indicador.

Você pode me dar um exemplo? Problema mínimo de reprodução de código?

[Excluído]  
Aleksey Vyazmikin:

Obrigado, isso é certamente claro - verifique a divisão por zero! Estou mais preocupado com o motivo deste zero, ao acessar a matriz de datas a partir do indicador.

É aqui que você precisa descobrir a partir do código qual é o denominador! E por que se torna zero... Se é uma referência de data, então alguma data é zerada.

[Excluído]  
Aleksey Vyazmikin:

Também tenho alguns dos indicadores "float" desde a atualização. precisam descobrir o que está errado...

Aleksey Vyazmikin  
Vladimir Karputov:

Você pode dar um exemplo? Problema mínimo de reprodução de código?

O indicador foi escrito por ordem - tudo é complicado lá, estou tentando conseguir a razão eu mesmo, mas até agora não consigo...

Aqui o limite se torna 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);
     }
//--вырезано
}
Vladimir Karputov  
Aleksey Vyazmikin:

O indicador foi escrito por ordem - é tudo complicado, estou tentando conseguir a causa eu mesmo, mas até agora não consigo...

Aqui o limite se torna zero.TimeFrames==PERIOD_H1

Precisa de um problema mínimo de reprodução de código. Não é um pedaço de código.

Aleksey Vyazmikin  
Alexey Kozitsyn:

É aqui que você precisa descobrir a partir do código qual é o denominador! E por que se torna zero... Se for referente a datas, então alguma data é zerada.

Sim, preciso descobrir - ontem estive imprimindo datas por meio dia - tudo estava bem, depois desliguei a impressora e quase imediatamente recebi um erro - anomalias...

Acima afixado o código, você pode me dizer onde cavar?


Alexey Kozitsyn:

Também obtive alguns indicadores "flutuantes" após a atualização. precisam descobrir o que está errado...

Sim, posso imaginar como deve ser para aqueles que, por exemplo, não entendem nada do código.

Razão: