Errores, fallos, preguntas - página 577

 
papaklass:

...

De acuerdo. Su posición es clara.
 

Incluso es difícil imaginar un Asesor Experto de este tipo que carezca de la potencia de un núcleo en la vida real. Por ejemplo, si en el probador el Asesor Experto hace una pasada de un símbolo por día en el historial de un año (¡es demasiado! ¡Tal vez deberíamos reescribir el código!), entonces en la vida real, cargará la CPU en un promedio de 1/250 de potencia = 0,4%.

Para un EA en diez símbolos - se obtiene una carga media del 4%. No tiene mucho sentido cargar los otros núcleos.

 

En cuanto a la idea de Konstantin(Lizar), me parece buena. Pero para este tipo de solución necesitamos separar los eventos que provienen directamente del gráfico y los que se generan de forma personalizada. Para los eventos personalizados, podemos tener dos colas de eventos y dos manejadores de eventos, algo así como OnUserEvents.

Y una adición interesante a los eventos personalizados sería la capacidad de especificar explícitamente su prioridad (digamos de 0 a 9), lo que podría permitir al usuario controlar la anticipación y el manejo de ciertos eventos. Por ejemplo, una función de este tipo permitiría ejecutar eventos con un valor más bajo, y eliminarlos de la cola con un valor más alto (si la cola está llena de eventos más importantes, no se pondría en cola ninguno nuevo).

papaklass:

Nunca he desarrollado software, así que no puedo hablar el lenguaje técnico de los desarrolladores de software. Voy a describir lo que me gustaría obtener de mi ordenador de 4 núcleos y MT5. En general se ve así:


El manejo de varias herramientas es ahora posible y los desarrolladores crearon una solución perfectamente viable.

2. Sobre el trabajo del probador y un montón de núcleos. Es un caso especial y no es correcto comparar este mecanismo con el comercio real. La esencia de la solución del problema del probador es que teniendo varias variantes de Asesor Experto (o más bien un Asesor Experto + un montón de conjuntos únicos de parámetros) es razonable distribuir los cálculos entre todos los núcleos/agentes disponibles. De este modo, obtenemos asincronía para todo el conjunto de tareas, pero desde el punto de vista de un agente individual todo está sincronizado.

3. Cuando se trata de multithreading, no estamos hablando de procesar múltiples herramientas al mismo tiempo, sino de procesar múltiples eventos al mismo tiempo (y dentro de un único agente específico). Eso no estaba presente en ninguna versión del terminal.

Los desarrolladores también son comprensibles: demasiada sobrecarga, mezcla demasiado "variopinta" de usuarios, demasiados problemas con la sincronización de los datos a los que tendrá acceso un Asesor Experto "multihilo", etc.

Por otro lado, la idea con los eventos no se lleva a su conclusión lógica. Vale, es caro y problemático implementar el "multithreading" pero es posible paralelizar al máximo los procesos y flujos de información dentro del propio terminal + crear un conjunto de manejadores suficientes para resolver el máximo número de tareas (y con un conjunto normal de parámetros).

 
papaklass:

Mi Asesor Experto en M5, en el período 04.01.2010 - 01.09.2011 en 12 monedas hace una sola pasada en 1436 seg (24 minutos) y al mismo tiempo hace 5687 operaciones. Sólo un núcleo está cargado, los otros tres están inactivos. Es decir, en cada pase individual pierdo 3/4 del tiempo porque la plataforma no utiliza la energía del ordenador. Este es un inconveniente importante de la plataforma a la hora de depurar una estrategia. Los núcleos se utilizan completamente sólo durante la optimización. Pero la optimización es mucho más rara que las carreras individuales. Y se pierde mucho tiempo en carreras individuales.

El planteamiento de "perder 3/4 del tiempo" indica que crees que: usar el multithreading es sólo una oportunidad perdida y un claro fallo de los desarrolladores.

Desgraciadamente, el multithreading en las tareas secuenciales (y una sola pasada del probador es una tarea secuencial) no es gratuito. En realidad, el multihilo tiene enormes pérdidas (a veces múltiples) para la sincronización de procesos. De hecho, todos los accesos a los recursos compartidos tienen que estar ligados a los sincronizadores.

Hemos movido deliberadamente el probador fuera de la terminal a un proceso separado sólo para permitirle trabajar en un solo hilo sin ningún tipo de bloqueo durante el 99% del tiempo de prueba. El resultado fue un aumento significativo de la velocidad.

La sugerencia de "metamos la multitarea en cada EA" proviene de una completa incomprensión del coste (ralentización total) del multithreading en este caso y de las consecuencias (ralentización + volar el techo del 99% de los desarrolladores no profesionales).


Hemos resuelto eficazmente los problemas de aplicación de la multitarea en el terminal, en el probador y hemos permitido un escalado casi ilimitado de la potencia en los modos de agente remoto y de red en la nube MQL5.


Si abro 12 gráficos y pongo un indicador en cada uno de ellos, entonces puedo ver cómo el terminal se retrasa en ciertos momentos. A juzgar por los mensajes del foro, no sólo me ocurre a mí. Entonces, son 12 instrumentos con un indicador. Y si necesito aumentar el número de instrumentos e indicadores, el terminal se bloquea. Y un núcleo se utilizará, mientras que el resto descansará. Entonces, ¿tiene sentido cargar otros núcleos? Si distribuimos los procesos terminales entre los núcleos, es decir, si utilizamos plenamente la potencia del ordenador, podremos resolver tareas a otro nivel. Eso es lo que quiero decir.

Si hay 12 cartas diferentes con distintos personajes, significa que cada personaje de cada carta está obviamente funcionando en su propio hilo sin afectar a los demás.

Si los gráficos empiezan a ralentizarse, la razón es banal: uno de los indicadores es muy poco económico. En este caso, ninguna multitarea ayudará, porque la raíz es obra del programador, que escribe indicadores en la cabeza, sin preocuparse por la eficiencia.

 

No puedo conseguir el gráfico inverso, algo está mal, la nueva barra de glitches en esta variante

se adjunta el indicador original con el que he estado jugueteando

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[])
  {
//---- проверка количества баров на достаточность для расчета
   for(int numb=0; numb<8; numb++) if(BarsCalculated(RSI_Handle[numb])<rates_total) return(RESET);
   if(rates_total<min_rates_total) return(RESET);

//---- объявления локальных переменных 
   int to_copy;

//---- расчеты необходимого количества копируемых данных
   if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчета индикатора
      to_copy=rates_total-1;                   // стартовый номер для расчета всех баров
   else to_copy=rates_total-prev_calculated+1; // стартовый номер для расчета новых баров
   
//---- копируем вновь появившиеся данные в массивы
   if(CopyBuffer(RSI_Handle[0],0,0,to_copy,Buffer1)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[1],0,0,to_copy,Buffer2)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[2],0,0,to_copy,Buffer3)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[3],0,0,to_copy,Buffer4)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[4],0,0,to_copy,Buffer5)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[5],0,0,to_copy,Buffer6)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[6],0,0,to_copy,Buffer7)<=0) return(RESET);
   if(CopyBuffer(RSI_Handle[7],0,0,to_copy,Buffer8)<=0) return(RESET);
   
   //мой кусок отсель   
   if (Reverse)
      {
         int start=prev_calculated;
         for(int i=start;i<rates_total;i++)
            {
               Buffer1[i]=100-Buffer1[i];
               Buffer2[i]=100-Buffer2[i];
               Buffer3[i]=100-Buffer3[i];
               Buffer4[i]=100-Buffer4[i];
               Buffer5[i]=100-Buffer5[i];
               Buffer6[i]=100-Buffer6[i];
            }
         Buffer1[0]=100-Buffer1[0];
         Buffer2[0]=100-Buffer2[0];
         Buffer3[0]=100-Buffer3[0];
         Buffer4[0]=100-Buffer4[0];
         Buffer5[0]=100-Buffer5[0];
         Buffer6[0]=100-Buffer6[0];
       }  
   //досель    

//----     
   return(rates_total);
  }
//+------------------------------------------------------------------+

Archivos adjuntos:
Multi_RSI.mq5  15 kb
 

Por favor, indíqueme cuál es el problema.

Estoy escribiendo un programa multidivisa

Obtengo la manija del indicador MA

maHandle_EURUSD=iMA("EURUSD",PERIOD_H1,MA_Period_EURUSD,MA_Shift_EURUSD,MODE_SMA,PRICE_CLOSE);

maHandle_GBPUSD=iMA("GBPUSD",PERIOD_H1,MA_Period_GBPUSD,MA_Shift_GBPUSD,MODE_SMA,PRICE_CLOSE); 

Estoy haciendo lo mismo para las 10 monedas restantes permitidas en el Campeonato, pero me da error 4801 durante las pruebas, las 12 monedas están en el historial (creo)

Estoy probando en el gráfico EURUSD

el Asesor Experto está probando GBPUSD (lo he puesto así en la configuración, para optimizarlo)

 
Lazarev:

Por favor, indíqueme cuál es el problema.

Estoy escribiendo un programa multidivisa

Obtengo la manija del indicador MA

Estoy haciendo lo mismo para las 10 monedas restantes permitidas en el Campeonato, pero me da error 4801 durante las pruebas, las 12 monedas están en el historial (creo)

Estoy probando en el gráfico EURUSD

el Asesor Experto está probando GBPUSD (lo he puesto así en la configuración, para optimizarlo)

Necesito añadir símbolos aSymbolSelect Market Watch
 

papaklass:

Ahora contéstame a una pregunta tan simple ....

Responderé de forma aún más sencilla, aunque no sea cortés.

Desgraciadamente, te sales completamente del tema y haces afirmaciones que sólo muestran ideas superficiales sobre los procesos.

Me temo que la mayoría de nuestros argumentos técnicos no se entenderán, ni siquiera el problema básico de la sincronización y la pérdida en su prestación.

Por lo tanto, no es necesario hacer peticiones de "dinos tus argumentos y nosotros especularemos", la situación está perfectamente clara

 

No encuentro respuestas a estas preguntas para un novato:

1) Cuando se añade un elemento más a un array dinámico, ¿es necesario ampliarlo mediante ArrayResize?

2) ¿Existe una función en MQL5 para eliminar un elemento (uno en medio de un array, por ejemplo) de un array dinámico i? Si no, ¿cuál es la mejor manera de hacerlo?

Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
Документация по MQL5: Основы языка / Типы данных / Объект динамического массива
  • www.mql5.com
Основы языка / Типы данных / Объект динамического массива - Документация по MQL5
 
Fia:

Como novato, no encuentro respuestas a estas preguntas:

1) Cuando añades otro elemento a un array dinámico, ¿tienes que ampliarlo con ArrayResize?

Haces el tamaño del array con cierta reserva, cuando te acercas al límite aumentas el tamaño. No hay un cambio de tamaño automático ni se añade al final. Mira el ejemplo de la función ArrayInitialize()