Características del lenguaje mql5, sutilezas y técnicas - página 33

 
Artyom Trishkin:

Lo resaltado puede devolver 0. BCS se topó con.

Sí, corredores de bolsa corruptos. También pondrían números negativos.

Sería bueno que los desarrolladores tuvieran un límite del rango de valores posibles de cada parámetro cuando los corredores establecen símbolos.

 
Artyom Trishkin:

¿Qué ocurre exactamente? Esa era la pregunta: ¿qué estoy haciendo mal para obtener datos de indicadores de un marco temporal no nativo?

Ejemplo: El indicador se ejecuta en M1, y los datos de AO deben obtenerse de M5. Así, mientras tenemos límite>1 (hay que recalcular el historial), AO de M5 devuelve ceros con ausencia de error en los datos. En cuanto se calcula el historial (límite==0), los datos empiezan a llegar desde AO con M5.

Para empezar, no hace falta que hagas esas entradas:

periodForWork=PeriodForWork;

Al principio pensé que estabas asignando una variable a su propio valor.

Siguiente:

size_ao=CopyBuffer(handle_ao,0,0,count,array_ao);

No es necesario copiar durante la inicialización. La inicialización no es para este propósito. Además, este registro no tendrá sentido cuando se soliciten datos de TFs más antiguos, que en el momento de la solicitud de OnInit() no estarán calculados todavía.

ArraySetAsSeries(BufferAO,true);

Pero este registro es suficiente para hacerlo una sola vez en la etapa de inicialización.

Además... um... subjetivamente, no es así como yo lo haría.

Me gusta dividir el programa en:

1. Primera ejecución (análisis de la historia);

2. Las carreras posteriores:

2.1. cada garrapata;

2.2. La barra formada;

Es decir

if( prev_calculated > 0 )             // Не первый запуск
{
 if( rates_total <= prev_calculated ) // Новый бар не сформирован
  {
  }
 else                                 // Новый бар сформирован
  {
  }
}
else                                  // Первый запуск
{
}

Y sólo después - ciclo de cálculo principal (función).

Sus funciones de copia dan errores poco informativos. El código no es muy bueno.

No se comprueba la sincronización de los datos del TF más antiguo.

Y lo más importante aquí es entender la secuencia. Aconsejo crear un indicador de prueba, para que sólo pida los datos del TF mayor en el primer arranque y para entender cómo se hace la copia. Es decir, eliminar esto del principio del código:

ArraySetAsSeries(array_ao,true);

Y desmarca el primer y el último elemento del array. Y sólo entonces, si es necesario, cambiar la dirección de la indexación.

 
De todos modos, empieza por ahí:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input   ENUM_TIMEFRAMES inpTimeframe=PERIOD_M5;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int _handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   _handle=iAO(_Symbol,inpTimeframe);
   if(_handle==INVALID_HANDLE)
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),"! Хэндл индикатора iAO ТФ "+EnumToString(inpTimeframe)+" не получен!");
      return( INIT_FAILED );
     }
//---
   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[])
  {
//--- Массив-приемник значений индикатора
   double ao[];
//---
   if(prev_calculated>0)
     {

     }
   else                                        // Если первый запуск
     {
      //--- Количество просчитанных баров старшего ТФ
      int bars;
      if(( bars=BarsCalculated(_handle))<0 || !(bool)SeriesInfoInteger(_Symbol,inpTimeframe,SERIES_SYNCHRONIZED))
         return( 0 );
      //--- 
      int num=CopyBuffer(_handle,0,0,bars,ao);
      //---
      if(num<0)
        {
         Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Запрашиваемая таймсерия еще не построена!");
         return( 0 );
        }
      else if(num!=bars)
        {
         Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Скопированы не все данные (",num," из ",bars,")");
         return( 0 );
        }
      //---
      Print(__FUNCTION__,": Успех! Скопировано ",num," из ",bars," значение индикатора АО ТФ "+EnumToString(inpTimeframe));
     }
//---
   return( rates_total );
  }
//+------------------------------------------------------------------+
 
Alexey Kozitsyn:

Para empezar, no es necesario hacer esas entradas:

Primero pensé que estaba asignando a una variable su propio valor.

Siguiente:

No es necesario copiar durante la inicialización. La inicialización no es para este propósito. Además, este registro no tendrá sentido cuando se soliciten datos de TFs más antiguos, que en el momento de la solicitud de OnInit() no estarán calculados todavía.

Pero este registro es suficiente para hacerlo una sola vez en la etapa de inicialización.

Además... um... subjetivamente, no es así como yo lo haría.

Me gusta dividir el programa en:

1. Primera ejecución (análisis de la historia);

2. Las carreras posteriores:

2.1. cada garrapata;

2.2. La barra formada;

Es decir

Y sólo después - ciclo de cálculo principal (función).

Sus funciones de copia dan errores poco informativos. El código no es muy bueno.

No se comprueba la sincronización de los datos de la TF más antigua.

Y lo más importante aquí es entender la secuencia. Aconsejo crear un indicador de prueba, para que sólo pida los datos del TF mayor en el primer arranque y para entender cómo se hace la copia. Es decir, eliminar esto del principio del código:

Y desmarca el primer y el último elemento del array. Y sólo entonces, si es necesario, cambiar la dirección de la indexación.

Hago variables que me resultan claras a simple vista. Si no los entiendes, hazlos de forma que los entiendas ;).

Siempre empiezo a escribir las variables no globales con minúscula - la razón es sencilla: la inteligencia de las mayúsculas...

Este es el código de prueba, ya que el código que no es de prueba es lo suficientemente grande, y en MT4 vuela al cambiar el traf, y no hay errores de falta de datos - todo está siempre allí. Pero MT5 cuando cambio mtf sólo durante medio minuto carga la historia, y luego no funciona con los datos no es su TF - dice acerca de su ausencia.

Por eso discutí lo que estaba haciendo mal. Resulta que es necesario solicitar los datos de todos los clientes utilizados en el init. Creo que si no se sabe de antemano el número estimado de teléfonos usados, hay que solicitarlos todos. Sólo cuenta uno por medio minuto. Hay 21 en total...

¿Algo va mal otra vez?

 
Esto es muy útil para losprincipiantes:

En MT5 sólo se tarda medio minuto en descargar el historial al cambiar un etf


escribió sobre ello

я правильно понимаю тогда, что подготовив кэш,терминал при последующих обращениях (начиная со 2 обращения) затрачивает на порядки меньше времени?

можно ли как-то уменьшить время первого обращения после перезагрузки терминала,чтобы было как в МТ4?
Теперь выводы:

    Разница только в скорости начальной инициализации кеша чарта 0.6 мс МТ4 против 113 мс у МТ5

más detalles aquí

https://www.mql5.com/ru/forum/1111/page1871#comment_4866969

https://www.mql5.com/ru/forum/1111/page1871#comment_4867939

Esto es y será. Cuanto más TF o símbolos solicite, más lento será el inicio.

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • www.mql5.com
Форум алго-трейдеров MQL5
 
kaus_bonus:


escribió sobre ello

más detalles aquí

https://www.mql5.com/ru/forum/1111/page1871#comment_4866969

https://www.mql5.com/ru/forum/1111/page1871#comment_4867939

Cuantos más TFs o personajes se consulten, más lento será el inicio.

Creo que sería bueno si sólo cuando el indicador se pone en marcha por primera vez. Tengo que cambiar de plazo y tarda medio minuto en cargar el historial. Sé que no debería ser así, pero... Estoy haciendo algo mal... Y sólo en un indicador ocurre - cuando intento acceder a un marco temporal no nativo.
 
Artyom Trishkin:
Estaría bien si sólo cuando arranque el indicador por primera vez. Tengo medio minuto cargando el historial cada vez que cambio de marco temporal. Sé que no debería ser así, pero... Estoy haciendo algo mal... Estoy intentando acceder a un marco temporal no nativo en un solo indicador.

Pues bien, mida la velocidad de copia de datos de otro marco temporal y vea dónde está el cuello de botella.
 
Artyom Trishkin:

Si necesita utilizar varios indicadores de diferentes TFs para los cálculos - necesita obtener el mango de cada TF.

Si quieres que sea más rápido, reduce el tamaño del historial en el terminal.

¿Has ejecutado mi indicador de prueba? ¿Recoge datos?

 
Alexey Kozitsyn:

Si necesita utilizar varios indicadores de diferentes TFs para los cálculos - necesita obtener el mango de cada TF.

Si quieres que sea más rápido, reduce el tamaño del historial en el terminal.

¿Has ejecutado mi indicador de prueba? ¿Recoge datos?

No, no lo he hecho.

Resulta que si necesito TODOS los plazos, debo crear 21 asas del indicador AO? ¿No es un despilfarro?

 
Artyom Trishkin:

No, aún no lo he ejecutado.

Resulta que si necesitas TODOS los marcos temporales, tienes que crear 21 asas de indicadores AO? ¿No es un despilfarro?

¿Cómo puedo obtener los datos del símbolo/TF correcto? CopyBuffer sólo funciona con asas.
Razón de la queja: