Errores, fallos, preguntas - página 3027

 
Сергей Таболин:

Los indicadores son mi punto más débil ))))

¡Pero!

O no entiendo nada de nada, o estás un poco equivocado.

Por lo que sé, prev_calculated es un contador de datos no calculados. Y una vez que se cuentan los datos entrantes, ese contador se pone a cero... Como, eso es todo, chico, no hay más datos nuevos para calcular.... )))

Y por qué razón el indicador debería recalcular completamente en tal caso - ¡no lo sé!

---------------

Mintió un poco ))))

No son los indicadores los que se recalculan, sino que se recalculan los "índices" para que "queden bien" en el historial ;)

el contador se pone a cero por razones ajenas al programador, ¡como si el indicador se hubiera puesto en marcha por primera vez!

No me gustaría que mi mensaje se perdiera en medio de explicaciones incomprensibles, pero finalmente llegó a los desarrolladores.



Debemos tener en cuenta la conexión entre el valor devuelto por OnCalculate() y el segundo parámetro de entrada prev_calculado. Al llamar a la función, el parámetro prev_calculado contiene un valor devuelto por OnCalculate() en la llamada anterior. Esto permite economizar los algoritmos de cálculo del indicador personalizado para evitar cálculos repetidos para aquellas barras que no han cambiado desde la anterior llamada a esta función.

-esto es de la documentación. Un calc que no funciona correctamente rompe todo el concepto de cálculos económicos.
 
Andrey Dik:
El contador se pone a cero por razones ajenas al programador, ¡como si el indicador estuviera funcionando por primera vez!

No quería que mi mensaje se perdiera entre los incomprensibles aplausos, pero llegó a los estimados desarrolladores.

¿Es así en cada bar nuevo? Se están tranquilizando, ¿no?

Si no es cada barra, hay diferentes razones para restablecer el pre_calc.

 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Bichos, errores, preguntas

Andrey Dik, 2021.05.27 13:53

Es decir, el contador precalculado se pone a cero en cuanto aparece la nueva barra del timeframe. significa que el indicador se recalcula de nuevo como si se hubiera lanzado la primera vez.

¿le resulta familiar esta construcción?

if (rates_total == prev_calculated) return rates_total;
  
int startInd = rates_total - prev_calculated;

for (int i = startInd; i >= 0; i--)
{
  //тут считаем индикатор, который обращается к другому индикатору на старшем ТФ
}

¡el problema no está en la lógica del EA (redibujar, no redibujar, infradibujar o lo que sea) sino en el hecho de que prev_calculated se reinicia mientras que nadie le pidió que lo hiciera!

Creo que el problema es:

if (rates_total == prev_calculated) return rates_total;

No dejas que el indicador llamado en otro TF calcule cada tick y luego lo llamas y se sincroniza el historial y el cálculo desde cero de ese indicador


he creado una prueba. el indicador llamado cuenta todo y no se reinicia a prev_calculated == 0

He dibujado el cierre en el indicador y he desenrollado el evento con una nueva barra y prev_calculado == 0 :

// tst.mq5

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[])
{
   int start;
   static datetime t = 0;
   if(t != time[rates_total-1])
   {
      t = time[rates_total-1];
      Print(MQLInfoString(MQL_PROGRAM_NAME), " New bar ", t);
   }
   
   if(prev_calculated == 0)
   {
      start = 0;
      ArrayInitialize(Buffer, EMPTY_VALUE);
      Print(MQLInfoString(MQL_PROGRAM_NAME), " prev_calculated == 0");
   }
   else start = prev_calculated - 1;


   for(int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}

llamar a este indicador (obtener los 2 últimos valores del buffer) y también dibujar el cierre en su TF:

input ENUM_TIMEFRAMES TF = PERIOD_M5;
int OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0, Buffer, INDICATOR_DATA);
   ind_handle = iCustom(NULL, TF, "NewFolder\\tst");
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
   int start;
   static datetime t = 0;
   if(t != time[rates_total-1])
   {
      t = time[rates_total-1];
      Print(MQLInfoString(MQL_PROGRAM_NAME), " New bar ", t);
   }

   if(prev_calculated == 0)
   {
      start = 0;
      ArrayInitialize(Buffer, EMPTY_VALUE);
      Print(MQLInfoString(MQL_PROGRAM_NAME), " prev_calculated == 0");
   }
   else start = prev_calculated - 1;


   for(int i = start; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }
   double buf[];
   if(CopyBuffer(ind_handle, 0, 0, 2, buf) < 0) Print("Error CopyBuffer # ",GetLastError());
//--- return value of prev_calculated for next call
   return(rates_total);
}


ejecutó el último indicador en M1 , log:

2021.05.27 21:48:34.196 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:48:00

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) tst_tf prev_calculated == 0

2021.05.27 21:48:34.197 tst_tf (EURUSD,M1) Error CopyBuffer # 4806

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst Nueva barra 2021.05.27 21:45:00

2021.05.27 21:48:34.197 tst (EURUSD,M5) tst prev_calculated == 0

2021.05.27 21:49:01.636 tst_tf (EURUSD,M1) tst_tf new bar 2021.05.27 21:49:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:50:00

2021.05.27 21:50:00.149 tst_tf (EURUSD,M5) tst Nueva barra 2021.05.27 21:50:00

2021.05.27 21:51:01.789 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:51:00

2021.05.27 21:52:02.832 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:52:00

2021.05.27 21:53:00.920 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:53:00

2021.05.27 21:54:02.778 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:54:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:55:00

2021.05.27 21:55:00.308 tst_tf (EURUSD,M5) tst Nueva barra 2021.05.27 21:55:00

2021.05.27 21:56:00.118 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:56:00

2021.05.27 21:57:00.419 tst_tf (EURUSD,M1) tst_tf Nueva barra 2021.05.27 21:57:00

 
Andrey Khatimlianskii:

¿Es así en cada bar nuevo? ¿Están asegurando demasiado o algo así...

Si no es en cada barra, hay diferentes razones para restablecer pre_calc.

exactamente en cada nueva barra de la TF mayor.

Por ejemplo, si el indicador funciona en M1 y accede al indicador en M5, entonces cada 5 minutos el indicador se recalculará completamente.

 
Igor Makanu:

Creo que el problema es:

No dejas que el indicador llamado en otro TF calcule cada tick y luego lo llamas y hay una sincronización del historial y cálculo desde cero de ese indicador


he creado una prueba. el indicador llamado cuenta todo y no se reinicia a prev_calculated == 0

He dibujado el cierre en el indicador y he desenrollado el evento con una nueva barra y prev_calculado == 0 :

llamar a este indicador (obtener los 2 últimos valores del buffer) y también dibujar el cierre en su TF:

Compruebo la sincronización de los datos en el TF superior solicitado (M5) y la preparación del indicador en él, si no está listo, entonces salgo.

Como resultado, el indicador funciona sólo una vez en la apertura de la barra M1, y no en cada tick:


//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

//проверка на наличие нового бара
if (rates_total == prev_calculated) return rates_total;

Espero que los desarrolladores escuchen mis ruegos.

 
Andrey Dik:

Compruebo la sincronización de datos en el TF superior solicitado (M5) y la disponibilidad del indicador en él, si no está listo, entonces salgo.

Como resultado, el indicador funciona sólo una vez en la apertura de la barra M1, y no en cada tick:


Espero que los desarrolladores escuchen mis ruegos.

esto no debería funcionar correctamente en los indicadores:

if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))

si no me equivoco, en la ayuda hay un recorrido del script para paginar los datos de todos los TFs y debería haber una advertencia de que no se pueden solicitar datos históricos al indicador debido a que el indicador trabaja de forma asíncrona

y se recomienda utilizar BarsCalculated() una vez que se haya vinculado la manija


UPD: script para la paginación del historial y explicación de por qué no funciona en los indicadores:https://www.mql5.com/ru/docs/series/timeseries_access

 
Andrey Dik:

Compruebo la sincronización de datos en el TF superior solicitado (M5) y la disponibilidad del indicador en él, si no está listo, entonces salgo.

Como resultado, el indicador funciona sólo una vez en la apertura de la barra M1, y no en cada tick:


Espero que los desarrolladores escuchen mis ruegos.

¿Para qué sirve ese cheque?

//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

Sería mucho más sencillo escribir return 0; sin condición y ya está.

En cada nueva barra, la condición se cumplirá y todas las barras se recalcularán independientemente de la sincronización. Has escrito un código poco meditado y pretendes que sea un bug terminal...

 
Un error de compilación:
union X1 { //(1) нормально
        char x11[INT_MAX/2+1];
};
union X2 { //(2) Error: 'X2' - struct is too large
        char x21[INT_MAX/2+1];
        char x22[INT_MAX/2+1];
};
¿Cuál es la diferencia fundamental entre (1) y (2)?
 
La unión con un solo campo es algo extraño.
 
Alexey Viktorov:

¿Qué sentido tiene esa comprobación?

Sería más fácil escribir return 0; sin condición y ya está...

La condición se cumplirá en cada nueva barra y todas las barras se recalcularán independientemente de la sincronización. Has escrito un código precipitado y lo has hecho pasar por un error del terminal...

piénsalo de nuevo.