[SERVICE DESK] ¡Error al obtener la hora de la TF superior en el temporizador! - página 6

 
Me gustaría mucho escuchar la opinión de los desarrolladores al respecto.
 
 ResetLastError();
      if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
 
Alexey Kozitsyn:

Parece que la solución más fiable es realmente esperar a la llamada de OnCalculate() con la comprobación obligatoria de la conexión al servidor de comercio. Si no comprobamos la conexión (IsConnected()), entonces incluso en OnCalculate() la obtendremos en la carga del terminal:

Sin embargo, no elimina todos los interrogantes:

1. ¿Por qué no está escrito en la documentación de IsConnected() que debe ser llamado necesariamente antes de recibir los datos (al menos) del TF superior en OnCalculate()?

2. ¿Por qué no funciona IsConnected() en OnTimer()? ¿No se supone que el hecho de establecer la conexión con un servidor comercial nos indica que se pueden obtener datos?

3. Una vez que hemos establecido una conexión con el servidor de operaciones y estamos intentando recibir datos en OnTimer(), ¿no deberían las funciones iTime(), iBarShift(), SeriesInfoInteger() y funciones similares a ellas devolver errores si los datos de este servidor de operaciones en particular, del que toman la información, aún no están sincronizados? De lo contrario, resulta alguna tontería, como que te devolvemos el error 4066 una vez y luego puedes usar los datos que tienes.

He hablado con los promotores y con uno de mis amigos de allí y les digo lo siguiente: 1 ¿Qué hago?

1 Tonterías, puedes llamar cuando quieras y desde cualquier lugar.

2 IsConnected se puede llamar desde cualquier parte del código y funciona, pero es una función que no escribe nada en la pila de errores devuelve true/false y ya está. Teniendo en cuenta que el procedimiento de conexión es bastante largo (mínimo 1 segundo) y que IsConnected se activa en el momento de la conexión, es necesario comprobar el estado de la conexión y esperar el inicio del flujo de citas al iniciar el terminal.

3 Estas funciones no escriben nada en la pila de errores, sino que devuelven ellas mismas el resultado.

¿Por qué obtuvimos 4066? Ese error fue causado por la función TimeCurrent. Terminal conectado y el tiempo solicitado desde el servidor, dependiendo de la calidad de la conexión también toma algún tiempo, así que no se olvide de nuestro temporizador rápido. Y luego obtuvimos 4066 en nuestra solicitud de TimeCurrent. Y entonces conseguimos el tiempo y nuestras funciones empezaron a trabajar normalmente y ellas mismas devuelven un error como resultado de su trabajo saltándose la pila de errores.

Como recomendación en tal situación, el temporizador rápido y el inicio de la terminal, asegúrese de comprobar que empezamos a recibir datos del servidor. Mi versión es un poco muleta, sería correcto recibir una señal de OnCalculate para empezar a recibir datos.

 
Es más sencillo que eso.
 
Alexey Kozitsyn:

¿Qué sugieres para resolver el problema (existe, en tu opinión)? ¿Esperar hasta que OnCalculate() sea llamado 1-2 veces?

Sí, exactamente. En OnInit() simplemente llame a los TFs requeridos sin comprobar el resultado (no puede confiar en él), y en OnCalculate llame a la función IsTFDataReady(). Tan pronto como se devuelva true para todos los TFs solicitados, se puede empezar a ejecutar el algoritmo del indicador.

 
Alexey Kozitsyn:

1. ¿Por qué la documentación de IsConnected() no dice que debe llamarse siempre antes de recibir los datos (al menos) del TF superior en OnCalculate()?

IsConnected() es una función bastante complicada. Devuelve el estado de una sola conexión con el servidor. Pero el terminal utiliza más de una conexión. Hay 8 hilos comerciales por sí mismo. Por lo tanto, aunque IsConnected() devuelva verdadero, no está muy claro qué significa. Al menos, no podemos esperar que se soliciten y construyan series de tiempo. Pero si IsConnected() devuelve false, entonces podemos estar seguros de que el terminal sigue desconectado.

¿Cuál es la tarea para la que la presencia de la conexión del terminal es tan crucial? Según tengo entendido, el indicador es una herramienta de visualización de datos. Los datos que están disponibles. Cuando lleguen nuevos datos, se actualizará la visualización. No debería exigirse la comprobación de la pertinencia de los datos. Esa es la tarea del terminal.

 
Igor Makanu:

Supongo que estamos hablando de MQL5, la preparación de OHLC no es la misma que en MT4

Estoy hablando de MT4. Hace unos 2 ó 3 años me encontré con un error con Time[0]. Los desarrolladores parecen haberlo solucionado, pero luego, con el tiempo, volvió a aparecer. El problema es que es imposible reproducir inequívocamente este fallo.

 
Ihor Herasko:

IsConnected() es una función bastante complicada. Sólo devuelve el estado de una de las conexiones con el servidor. Pero el terminal utiliza más de una conexión. Sólo hay 8 hilos comerciales. Por lo tanto, aunque IsConnected() devuelva verdadero, no está muy claro qué significa. Al menos, no podemos esperar que se soliciten y construyan series de tiempo. Pero si IsConnected() devuelve false, entonces podemos estar seguros de que el terminal sigue desconectado.

¿Cuál es la tarea para la que la presencia de la conexión del terminal es tan crucial? Según tengo entendido, el indicador es una herramienta de visualización de datos. Los datos que están disponibles. Cuando lleguen nuevos datos, se actualizará la visualización. No debería ser necesario comprobar si los datos están actualizados. Esta es la tarea del terminal.

Para los indicadores no recuerdo la necesidad de comprobar la conexión con el servidor, lo que tenemos en el historial se dibuja, cuando se carga el historial significa que se recalculan todos los buffers de los indicadores

He desarrollado y utilizado la siguiente función en mi EA. En general es satisfactoria y comprueba la conexión con el servidor correctamente:

bool ServerDisable(int count=10){
   if(IsTesting()||IsOptimization())return(false);
   for(int i=0;i<count;i++){
      if(IsConnected())
         if(IsTradeAllowed())
            if(!IsTradeContextBusy()){RefreshRates(); return(false);}
      Sleep(157);
   }
   Print(__FUNCTION__," Торговый сервер не отвечает");
return(true);}

Específicamente uso Sleep() en él para transmitir el control a la terminal y luego comprobar la conexión con el servidor y la posibilidad de operar

 
Ihor Herasko:

Estoy hablando de MT4. Hace unos 2 ó 3 años me encontré con un error con Time[0]. Los desarrolladores parecían haberlo solucionado, pero luego, con el tiempo, volvió a aparecer. El problema es que es imposible reproducir inequívocamente este fallo.

Si no es demasiado problema, aquí está el tema del tema - la descarga correcta de la historia de la mayor TF, aquí está el indicador: "Tengo que dibujar la MA" de la mayor TF en las barras de la menor TF, lo hice dentro de 5 minutos, funcionará para el 98% correctamente, donde en este código 2% "trampas" que causará errores?

Estoy interesado en el código correcto para MT4

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot line1
#property indicator_label1  "line1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input ENUM_TIMEFRAMES   TimeFrame   =  PERIOD_H4;
input int               MAPeriod    =  25;
//--- indicator buffers
double         BufMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   double cl[];
//--- indicator buffers mapping
   SetIndexBuffer(0,BufMA);
   IndicatorDigits(Digits);
// запускаем подгрузку истории и выходим, даже не проверяя подгружена она или нет, история тут еще не нужна
   CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),cl);
//---
   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 i,limit,resultcopy;
   double closetf[];
   if(prev_calculated==0)
     {
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-1;
        }else{
      resultcopy=CopyClose(_Symbol,TimeFrame,0,iBars(_Symbol,TimeFrame),closetf);
      if(resultcopy<0)
        {
         Print("Подгрузка истории....");
         return(0);
        }
      if(resultcopy<MAPeriod)
        {
         Comment("Большой период МА!!!, в истории доступно ", resultcopy," баров");
         return(resultcopy);
        }
      limit=resultcopy-prev_calculated+1;
     }
   limit = fmin(rates_total-1,limit);
// основной цикл расчета индикатора
   for(i=limit; i>=0 && !IsStopped(); i--)
     {
      BufMA[i]=iMA(_Symbol,TimeFrame,MAPeriod,0,MODE_SMA,PRICE_CLOSE,i);
     }
//---
   return(resultcopy);

  }
 
Vitaly Gorbunov:

He hablado con los desarrolladores y con un amigo que conozco allí, y te diré una cosa a la vez.

1 Tonterías, puedes llamar cuando quieras y desde cualquier lugar.

2 IsConnected se puede llamar desde cualquier parte del código y funciona, pero es una función que no pone nada en la pila de errores, devuelve true/false y ya está. Teniendo en cuenta que el procedimiento de conexión es bastante largo (mínimo 1 segundo) y que IsConnected se activa en el momento de la conexión, es necesario comprobar el estado de la conexión y esperar el inicio del flujo de citas al iniciar el terminal.

3 Estas funciones no escriben nada en la pila de errores, sino que devuelven el resultado ellas mismas.

¿Por qué obtuvimos 4066? Ese error fue causado por la función TimeCurrent. Terminal conectado y el tiempo solicitado desde el servidor, dependiendo de la calidad de la conexión también toma algún tiempo, así que no se olvide de nuestro temporizador rápido. Y luego obtuvimos 4066 en nuestra solicitud de TimeCurrent. Y entonces conseguimos el tiempo y nuestras funciones empezaron a trabajar normalmente y ellas mismas devuelven un error como resultado de su trabajo saltándose la pila de errores.

Como recomendación en esta situación, el temporizador rápido y el inicio de la terminal, asegúrese de comprobar que empezamos a recibir los datos del servidor. Mi variante es un poco muletilla, sería correcto recibir una señal de OnCalculate para empezar a recibir datos.

1. Lee atentamente lo que escribo. ¡No es la primera vez que te lo digo! ¡No he dicho nada de no llamar a ningún sitio!

¿Estás diciendo que todas las funciones iBarShift(), iTime(), SeriesInfo...() solicitan TimeCurrent()?