Apareció un error de división por cero en un indicador - página 6

 
Aleksey Vyazmikin:

Lógicamente, no debería ser igual a cero en absoluto, ¡no está claro por qué es así!

Tu d1 da números minúsculos, yo evito esos problemas convirtiendo el precio en int, es decir, por ejemplo int bid=int((tick_array[0].bid+_Point/10)/_Point); seguro que a veces te sale 0.00000999999 en 5 dígitos, si haces los cálculos en double
 
Aleksey Vyazmikin:

No debería ser igual a cero por lógica en absoluto, ¡no entiendo por qué ocurre así!

Ejecutado en el depurador en Si-9.18. El tiempo en los índices es de 2016 por alguna razón. Aunque el valor de i es 2189. En consecuencia, comienza el cálculo al principio del gráfico, donde no hay liquidez. El tiempo inicial entre el arranque y la parada es de 1 hora. Pero para esa hora, sólo hay un valor de tiempo. Lo encuentra tanto con la variable de inicio como con la de parada. En consecuencia, inicio = parada. Por supuesto, si los restas, obtienes cero. Todavía no he descubierto el resto.

 
ovak77:
Tienes d1 con números diminutos, yo evito esos problemas convirtiendo el precio a int, es decir, por ejemplo int bid=int((tick_array[0].bid+_Point/10)/_Point); seguro que a veces devuelve 0 si los cálculos se realizan en double

No discutamos d1 - si es necesario, pues es necesario, todo se cuenta correctamente allí. La pregunta es ¿por qué obtenemos el mismo valor para start_time y stop_time, así como para start_index y stop_index?

 
Aleksey Vyazmikin:

No discutamos d1 - si es necesario, pues es necesario, todo se cuenta correctamente allí. La pregunta es ¿por qué obtenemos el mismo valor para start_time y stop_time que para start_index y stop_index?

Depende de ti, prueba a dividir 0,0000099999 entre 2, por ejemplo
 

Después de otro cuelgue, el terminal deja de funcionar.... ¿Cómo puedo resucitarlo sin reinstalar?

Resultó estar colgado en la memoria - mató a la fuerza el proceso - se inició.

 
Aleksey Vyazmikin:

¿Cómo es posible que el tiempo se iguale? Todo funciona correctamente desde hace medio año...

void CreateFigure(int i,const datetime &Time[],const double &Open[],const double &High[],const double &Low[],const double &Close[],MqlRates &rates[])
  {                                                              //i = 2189 
   datetime start_time=rates[i].time;                            //start_time=rates[i].time = D'2016.10.06 12:00:00'
   datetime stop_time=(start_time+PeriodSeconds(TimeFrames));    //stop_time = D'2016.10.06 13:00:00'
//---                                                            //Time[38572] = D'2016.10.05 19:23:00'
   int start_index,stop_index,limit;                             //Time[38571] = D'2016.10.06 12:35:00'
   datetime vertical_line_time;                                  //Time[38570] = D'2016.10.06 19:05:00'
//---
   start_index=ArrayBsearch(Time,start_time);                    //start_index = 38571
   if(Time[start_index]<start_time) start_index=(start_index>0?start_index-1:start_index);
   start_time=Time[start_index];                                 //start_time = D'2016.10.06 12:35:00'
   if(i>0)
     {
      stop_index=ArrayBsearch(Time,stop_time);                   //stop_index = 38571
      if(Time[stop_index]>stop_time) stop_index++;
      stop_time=Time[stop_index];                                //stop_time  = D'2016.10.06 12:35:00'
      limit=start_index-stop_index+1;
      vertical_line_time=Time[start_index-(limit>>1)];
Primero tieneslimit=index_de_parada+1, es decir,limit==1, y luego donde la división por 2 eslimit=(int)(tiempo_de_parada-hora_de_inicio)/PeriodoSegundos(_Periodo). No se añade uno. El cero se divide por el período.
 
Sergey Savinkin:

Ejecutado en el depurador en Si-9.18. El tiempo en los índices es de 2016 por alguna razón. Aunque el valor de i es 2189. Por lo tanto, inicia el cálculo al principio del gráfico, donde no hay liquidez. El tiempo inicial entre el arranque y la parada es de 1 hora. Pero para esa hora, sólo hay un valor de tiempo. Lo encuentra tanto con la variable de inicio como con la de parada. En consecuencia, inicio = parada. Por supuesto, si los restas, obtienes cero. Todavía no he descubierto el resto.

Poner BarsUsed=100 en los parámetros de entrada.

 
Aleksey Vyazmikin:

Poner BarsUsed=100 en los parámetros de entrada.

Sí, así no se producen errores. Pero si te metes en algún instrumento ilíquido o en un momento ilíquido - sesión nocturna, por ejemplo, entonces puedes conseguir fácilmente 1 barra baja en una hora. Así, el límite = 0 está garantizado para ti. Y si la cotización es 2 - entonces el límite/2 seguirá dando 0 cuando se redondee.

 
Sergey Savinkin:

Sí, no es un error. Pero si te metes en un instrumento sin liquidez o en un momento sin liquidez -por ejemplo, durante la sesión de la tarde, puede haber una barra baja en una hora-. Así, el límite = 0 está garantizado para ti. Y si la cotización es 2 - entonces el límite/2 seguirá siendo 0 cuando se redondee.

Tal vez, lo pensaré, gracias. Pero el problema global es otro.... El problema es que no es estable.

 
ovak77:
Depende de ti, prueba a dividir 0,0000099999 entre 2, por ejemplo

Impreso d1 - para mis propósitos es

2018.07.04 19:38:06.404 IndDrafter_Test (Si-9.18,M1)    d1=35.71428571428572
2018.07.04 19:38:06.404 IndDrafter_Test (Si-9.18,M1)    d1=32.78688524590164
2018.07.04 19:38:06.404 IndDrafter_Test (Si-9.18,M1)    d1=32.78688524590164
2018.07.04 19:38:06.404 IndDrafter_Test (Si-9.18,M1)    d1=32.78688524590164
2018.07.04 19:38:06.404 IndDrafter_Test (Si-9.18,M1)    d1=43.47826086956522

De todos modos, ese no es el punto, gracias.