Preguntas de los principiantes MQL5 MT5 MetaTrader 5 - página 984

 
Ihor Herasko:


Pero el hecho es que. El sueño no debería afectar al recálculo de los datos en el indicador. Algo falla en el llenado del buffer. ¿Tal vez haya un trozo de código reproducible?

El indicador fue escrito por encargo - es un OOP salvaje, no lo entiendo :(

Pasé toda la noche con este problema, mientras que encontré la razón de la divergencia entre el probador y la cuenta real, tal vez después de dormir voy a eliminar algo de la lógica secreta y publicarlo para su revisión.

 
Aleksey Vyazmikin:

Me enfrenté a un problema, el EA basado en el indicador funciona correctamente en una cuenta real, pero está mintiendo en el probador, en los modos de generación de ticks tanto por OHLC como por todos los ticks - el resultado es el mismo. El resultado del error es el búfer vacío del indicador en la barra cero (sólo cuando hay una nueva barra en la TF superior, que se utiliza para el cálculo del indicador). Sin embargo, he logrado hacer que el indicador se calcule añadiendo Sleep a mi Expert Advisor. Pero he descubierto que dependiendo del modo de generación de ticks este Sleep debe ser diferente - para la generación a partir de todos los ticks Sleep(15000) es suficiente, mientras que para OHLC Sleep(30000) es necesario.

Entonces surge la pregunta: ¿es normal la situación con Sleep, porque lógicamente parece que allí se modelan diferentes tiempos de retardo dependiendo del modo de generación de ticks?

Estimados desarrolladores, por favor expliquen la situación con el indicador, porque yo mismo no entiendo cuál es la razón - ¡un error en el código o en el probador!

Estoy dispuesto a darte el indicador y el Expert Advisor en el MP, pero dime a quién.

Si quieres copiar el precio a un array, tienes que comprobar si el historial está disponible y comprobar si el precio no ha cambiado. Para ello hay que comprobar si el historial de TF está disponible, si no, hay que intentar copiarlo de nuevo y esperar a que se cargue en el bucle.

esto es una mala mano del programador, si no lo sabía

el deslizamiento no es normal
 
void OnChartEvent(            const int id,        // идентификатор события   
                              const long& lparam,  // параметр события типа long 
                              const double& dparam,// параметр события типа double 
                              const string& sparam // параметр события типа string 
                              )
   {
   Print(My_Name, " ---  ", id, "    lparam = ", lparam, "    dparam = ", dparam, "    sparam = ", sparam, "    ChartID() = ", ChartID() );        // <<|+|+|+<<  // 

   }                              

Por favor, explique...

Presiono la tecla = obtengo el id de evento = 0. Esto puede repetirse muchas veces. El resultado es el mismo siempre que no se pulse la barra espaciadora.

Presionando la barra espaciadora = obtengo el id de evento = 0. Después de eso, todas las manipulaciones en el teclado no dan lugar a ningún evento.

Para salir del estupor, pulso el botón del ratón = obtengo el id de evento = 4. Después puedes volver a hacer clic en el teclado = los eventos vienen por cada clic. Siempre que no se pulse la barra espaciadora = con el mismo resultado.

Pregunta: ¿soy un tonto que no entiende algo o no debería ser así? Por favor, proporcione un enlace.

 
Nikita Chernyshov:

Hola colegas.

Pregunta: En mql4, para calcular el número de posiciones, se puede escribir la función así

¿Cómo se implementa en mql5? ¿Cómo puedo calcular las posiciones por número mágico o por tipo?

Añade esta línea antes de la función MQL4

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

y funcionará en MT5.

 
Maxim Dmitrievsky:

Lo que pasa con los indicadores es que las series de tiempo pueden no estar listas todavía, es decir, no puede copiar el precio a una matriz de una vez. Para ello, debemos comprobar si el historial de TF está disponible, si no, debemos intentar copiarlo de nuevo y esperar a que se cargue en el bucle.

Esto es una mala mano del programador si no lo sabe.

el deslizamiento no está bien

¿Cómo es posible en el probador? Entiendo que si el problema está en el real o en el probador no hay historial... Sin embargo, ¿cómo debería ser esta prueba?

Los desarrolladores están ignorando mi mensaje, lamentable.

 
Aleksey Vyazmikin:

¿Cómo es posible en el probador? Entiendo que si el problema está en el real o en el probador no hay historia allí... Sin embargo, ¿cómo debería ser esta prueba?

Los desarrolladores están ignorando mi mensaje, lamentable.

comprobar si los precios se copian, si Copyclose o lo que sea devuelve -1 entonces no se copian

 
Maxim Dmitrievsky:

comprobar si los precios se copian, si Copyclose o lo que sea devuelve -1 entonces no se copian

El indicador se calcula una vez en la aparición de una nueva barra, que se implementa, si entiendo correctamente, de esta manera:

//+------------------------------------------------------------------+
//| 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[])
  {
   static int counted_bars=0;
   if(rates_total==prev_calculated) return(rates_total);

también se confirma con una simple impresión.

Por eso la situación no es clara, si suponemos que no hay precio que calcular, el indicador se calculará 1 vez y el buffer se quedará sin llenar, pero no es así - se llenará si añadimos sleep al EA y esperamos. ¿Tal vez, el indicador es lento en el cálculo y el probador simplemente no lo espera? Pero, ¿cómo comprobarlo?

 
Aleksey Vyazmikin:

El indicador se calcula 1 vez cuando aparece una nueva barra, que se implementa, si entiendo bien, de esta manera:

esto también se confirma con una simple impresión.

Por eso la situación no es clara, si suponemos que no hay precios que calcular, el indicador se calculará una vez y el buffer se quedará sin llenar, pero no es el caso - se llenará si añadimos el sueño al EA y esperamos. ¿Tal vez, el indicador es lento en el cálculo y el probador simplemente no lo espera? Pero, ¿cómo comprobarlo?

Tal vez debería ser cronometrado entonces

 
Maxim Dmitrievsky:

Tal vez deberíamos usar un temporizador entonces.

Sí, con el temporizador en el EA la prueba va un poco más allá que sin el temporizador, pero peor que con Sleep, y el temporizador es esencialmente lo mismo que Sleep.

Creo que entiendo cuál es el problema, el indicador se calcula utilizando los datos de otros dos indicadores y el código pide el número de barras calculadas de otros indicadores

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CChannel::BarsCalculated(void)
  {
   int upchbars=BarsCalculated(m_upch);
   int dnchbars=BarsCalculated(m_dnch);
   if(upchbars<=dnchbars) return(upchbars);
   return(dnchbars);
  }

y el número calculado esperado de barras

int barsch=(InpChPeriod==PERIOD_CURRENT?rates_total:Bars(_Symbol,InpChPeriod));

Si estos dos valores no coinciden, el buffer no se llena.

   if(!channel.CreateChannel() || barsch<=0 || barsch!=channel.BarsCalculated() || channel.FillChBuffers(rates_total,calculated,time)==0)
     {
      for(;counted_bars<rates_total;counted_bars++)
        {
         ZigzagBuffer[counted_bars]=0.0;
         ZigzagStepBuffer[counted_bars]=0.0;
         UpChBuffer[counted_bars]=0.0;
         DnChBuffer[counted_bars]=0.0;
         InfoZigzagBuffer[counted_bars]=0.0;
         InfoUpChBuffer[counted_bars]=0.0;
         InfoDnChBuffer[counted_bars]=0.0;
         InfoDirectBuffer[counted_bars]=0.0;
         InfoBegPriceBuffer[counted_bars]=0.0;
         InfoEndPriceBuffer[counted_bars]=0.0;
         InfoBegTimeBuffer[counted_bars]=0.0;
         InfoEndTimeBuffer[counted_bars]=0.0;
         InfoStartPriceBuffer[counted_bars]=0.0;
         InfoStartTimeBuffer[counted_bars]=0.0;
         InfoZigzagTotal[counted_bars]=InfoZigzagTotal[counted_bars-1];
        }
      if(InpInfEnd) CopyInfoBuffers(rates_total-1,(int)InfoZigzagTotal[rates_total-1]);
      return(calculated);
     }

Si entiendo bien, los indicadores se ejecutan en un hilo y su prioridad se distribuye por el momento de su creación, es decir, resulta que el indicador al que me dirijo desde el EA tiene la mayor prioridad y realiza su cálculo primero y después pasa el hilo a aquellos indicadores que deben realizar el cálculo (en base a los datos de los buffers).

En la impresión podemos ver que si pongo Sleep de un tamaño suficiente, el recálculo se realiza en el indicador (aún no entiendo cómo) y ¿por qué sólo después de 13 segundos?

2019.01.22 19:50:16.992 2019.01.21 23:45:00   barsch=6275
2019.01.22 19:50:16.992 2019.01.21 23:45:00   BarsCalculated=6274

2019.01.22 19:50:16.993 2019.01.21 23:45:13   barsch=6275
2019.01.22 19:50:16.993 2019.01.21 23:45:13   BarsCalculated=6275

No hay temporizador en el indicador.

Y qué debo hacer para obtener el cálculo correcto, tratando de usar mientras en EA antes de esperar el valor en el buffer no ayuda - cuelga.

 
Hola, quería implementar un trailing stop con paso en mi EA. No he podido encontrar nada más que la plantilla en Kodobase y Macd Sample. ¿Tal vez haya otras opciones?
Razón de la queja: