Errores, fallos, preguntas - página 1999

 
Alexey Viktorov:

Tomemos como ejemplo la matriz del buffer del indicador: Cuando se inicializa un indicador, el buffer tiene una longitud cero. ¿Qué hay que inicializar con ceros? Cuando se añade otro índice, ¿se obliga a ponerlo a cero y luego a rellenarlo con algún valor? ¿Para qué sirve esta puesta a cero o relleno con EMPTY_VALUE? Y si es necesario asignar PLOT_EMPTY_VALUE y no 0 o EMPTY_VALUE o forzar uno, pero necesitamos otro... Lo mires como lo mires, acabas perdiendo el tiempo...

Y una matriz personalizada... El array se declara para algún dato distinto de cero y EMPTY_VALUE. Entonces, ¿cuál es el propósito de inicializarlo forzosamente con algo?

Así que resulta que el rendimiento se ve afectado en la mayoría de los casos.

Es evidente que no estoy en contacto con la vida. En mi opinión, el buffer del indicador siempre tiene una longitud igual al número de barras. Y el rechazo de su inicialización en MT5 conduce a la visualización de basura en la pantalla. Resulta que la inicialización explícita es obligatoria. Y no está claro por qué se transfiere simplemente desde el núcleo (como era en MT4) al programador MQL. No he visto ningún argumento real de que de alguna manera se puede acelerar sin la inicialización y todavía obtener la pantalla de basura.

No estoy diciendo nada sobre una matriz dinámica personalizada - realmente hay una regla: el que la asignó, es responsable de la limpieza correcta. ArrayInitialize es útil en muchos casos. No es una cuestión de velocidad, sino de corrección del programa. Priorizar: rápido y/o correcto. Por lo general, algunas comprobaciones de corrección y preparación de datos requieren tiempo adicional (aunque sea mínimo), pero no se puede prescindir de ellas: los milagros nunca ocurren.

 
Stanislav Korotky:

No estoy diciendo nada sobre una matriz dinámica personalizada - la regla realmente se aplica allí: quien la asignó es responsable de limpiarla correctamente.

No insultes a las matrices.

#property strict

void OnStart()
{
  uchar Array[];
  
  const int Size = ArrayResize(Array, 10000);
  
  bool Res = false;
  
  for (int i = 0; (i < Size) && (!Res); i++)
    Res = Array[i];
    
  Print(Res);
}

En MT4 siempre devolverá false, porque sin basura - todo ceros. En MT5 es cierto.

Por lo tanto, el mismo código en el probador de MT4 siempre mostrará resultados idénticos de una ejecución a otra. En un probador de MT5 no lo hará.

 
fxsaber:

En MT4 siempre devolverá false, porque sin basura es todo ceros. En MT5 es cierto.

¿Es una prueba de que MT4 rellena la matriz con ceros? Entonces tenemos que tener en cuenta que si ArrayResize utiliza un tercer parámetro con reserva, entonces las reasignaciones posteriores dentro de la reserva no inicializarán nada. Habrá basura. Recomiendo hacer una inicialización explícita, para que no te sorprendas accidentalmente más tarde, como en el ejemplo de optimización que provocó esta discusión.

Para los que se preocupan por el frenado a causa de la inicialización, me atrevo a decir que suele haber muchos otros lugares y técnicas en los que se puede mejorar la eficiencia en mucha mayor medida.

 
Stanislav Korotky:

¿Es una prueba para MT4 llenando la matriz con ceros? Entonces tienes que tener en cuenta que si ArrayResize utiliza un tercer parámetro con una reserva, entonces las reasignaciones posteriores dentro de la reserva no inicializarán nada. Habrá basura.

No habrá basura.

Recomiendo hacer una inicialización explícita para que no te sorprendas accidentalmente más tarde, como en el ejemplo de optimización que provocó esta discusión.

Esto no salvará

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

Bichos, errores, preguntas

fxsaber, 2017.09.12 11:18

Incluso si escribiera perfectamente (sin cometer errores - que no lo hago), es normal tomar la biblioteca de otra persona (a veces sin código fuente - en el Marketplace) y usarla, esperando que esté escrita de manera competente. Y no hay seguridad de que después de eso te encuentres con resultados diferentes en el probador. Y encontrar la verdadera causa será MUY difícil. Y arreglarlo es a veces imposible.

El objetivo es que de una ejecución a otra el resultado sea reproducible, es decir, idéntico, incluso con un error.

 
fxsaber:

No habrá basura.



¿Debemos entonces corregir la documentación?

Lainicialización de un array con la expresiónArrayInitialize(array, init_val) no significa la inicialización de los elementos de la reserva, asignados para este array, con el mismo valor. Cuandola función ArrayResize() aumenta posteriormente el tamaño del array dentro de la reserva actual, se añaden al final del array los elementos cuyos valores no están definidos y, en la mayoría de los casos, no son iguales ainit_val.

 
Stanislav Korotky:

¿Hay que corregir la documentación entonces?

Inicializar un array con la expresiónArrayInitialize(array, init_val) no significa que los elementos de la reserva, asignados para este array, se inicialicen con el mismo valor. CuandoArrayResize() aumenta posteriormente el tamaño de la matriz dentro de la reserva actual, se añaden al final de la matriz los elementos cuyos valores no están definidos y, la mayoría de las veces, no son iguales ainit_val.

No lo hace, porque simplemente no existe tal cosa en la documentación de MT4.


¡Es horroroso pensar que alguna librería matemática (Include\Math -7Mb de código fuente) no se ha inicializado en uno/dos lugares! ¿Y cómo desenterrar este error, que en MT5-tester da diferentes ejecuciones individuales, y en MT4 - el mismo?

 
Stanislav Korotky:

Debo estar atrasado. Me parece que el buffer del indicador siempre tiene una longitud igual al número de barras. Y el rechazo de su inicialización en MT5 lleva a mostrar basura en la pantalla. Resulta que la inicialización explícita es obligatoria. Y no está claro por qué se transfiere simplemente desde el núcleo (como era en MT4) al programador MQL. No he visto ningún argumento real de que de alguna manera se puede acelerar sin la inicialización y todavía obtener la pantalla de basura.

No estoy diciendo nada sobre una matriz dinámica personalizada - realmente hay una regla: el que la asignó, es responsable de la limpieza correcta. ArrayInitialize es útil en muchos casos. No es una cuestión de velocidad, sino de corrección del programa. Priorizar: rápido y/o correcto. Normalmente, algunas comprobaciones de corrección y preparación de datos requieren un tiempo adicional (aunque mínimo), pero no se puede prescindir de ellas: los milagros ocurren.

No prestaste atención a la frase

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

Bichos, errores, preguntas

Alexey Viktorov, 2017.09.12 10:50

Tomemos como ejemplo la matriz del buffer del indicador: Cuando se inicializa el indicador, el buffer tiene una longitud cero. ¿Qué hay que inicializar con ceros? Cuando se añade otro índice, se obliga a ponerlo a cero y luego se rellena con algún valor... ¿Para qué sirve esta puesta a cero o relleno con EMPTY_VALUE? Y si es necesario asignar PLOT_EMPTY_VALUE y no 0 o EMPTY_VALUE o forzar uno, pero necesitamos otro... Lo mires como lo mires, acabas perdiendo el tiempo...

Y una matriz personalizada... El array se declara para algún dato distinto de cero y EMPTY_VALUE. Entonces, ¿por qué habría que inicializarlo a la fuerza con algo?

Así que resulta que afecta al rendimiento en la mayoría de los casos.



Y no tiene sentido hacer esto en OnCalculate. ¿Por qué tendríamos que inicializar el array con algo y luego llenarlo con algunos valores de la fórmula? Cuando se añade una barra, respectivamente una celda de la matriz, ¿qué sentido tiene llenarla con algo y luego inmediatamente con un valor de la fórmula o un valor vacío?

 
Alexey Viktorov:

Y ya en OnCalculate no tiene sentido. ¿Por qué tendríamos que inicializar el array con algo y luego llenarlo inmediatamente con algunos valores de la fórmula? Cuando se añade una barra, y respectivamente una celda de la matriz, ¿qué sentido tiene llenarla con algo y luego inmediatamente con un valor de la fórmula o un valor vacío?

Sólo se inicializan los nuevos elementos del array. Y la cuestión sigue siendo la misma: resultados idénticos de una ejecución a otra, incluso si hay un error en el código (a menudo no es el tuyo). Más arriba di un ejemplo con la biblioteca de matemáticas.

La basura es mala.

 
fxsaber:

No lo hagas, porque simplemente no hay ninguno en la documentación de MT4.

¿De dónde lo saqué entonces? Vaya aquí.

ArrayInitialize - Операции с массивами - Справочник MQL4
ArrayInitialize - Операции с массивами - Справочник MQL4
  • docs.mql4.com
ArrayInitialize - Операции с массивами - Справочник MQL4
 
Stanislav Korotky:

¿De dónde saqué eso entonces? Vaya aquí.

Así que no se trata de ArrayResize, sino de ArrayInitialize. ArrayResize garantiza ceros en MT4.


Por el bien de interés, miré en todas mis fuentes para MT5 la frecuencia de uso de ArrayInitialize. Sólo unas pocas veces. Parece ser menos que un porcentaje de todas las matrices dinámicas. Y donde lo usé, tuve que usar nulos a propósito, así que usé una notación más corta en lugar de for.

Razón de la queja: