Análogo a iBarShift - página 3

 
Vasiliy Pushkaryov:

Este es el guión.

Sólo se cuelga. Si se elimina a la fuerza del gráfico, se obtiene el resultado.

Así que lo probé, por eso te lo recomendé. Pero como lo has usado y te viene bien, no voy a cambiar de opinión.

Lo siento, Vassili. Te he entendido mal. Acabo de leer tu post rápidamente mientras conducía. Pensé que se trataba del último parámetro, donde tengo32000000000, resulta que te referías al parámetro t. Sí, efectivamente, es el único caso en el que el resultado es diferente al del MQL4 iBarShift() original. Sin embargo, es muy extraño intentar utilizar esta función para obtener el número de barras (o índice de barras) desde el punto de tiempo actual, es decir,TimeCurrent(), cuando está claro que la barra es cero. En general, es extraño que la funciónBars() enTimeCurrent() produzca 0, y no 1. Formalmente es un error de los desarrolladores, aunque depende. Pero algo no puede colgarse por usar la función estándar Bars(), sobre todo porque el script comprobóPrint(), es decir, todo está bien.
Entiende, Vasily, no quiero menospreciar otras implementaciones de iBarShift analógico, es sólo que yo personalmente uso exactamente esta construcción(Bars(NULL,0,t,32000000000)-1;), porque es la más rápida. Y esta construcción se utiliza no como sustituto de iBarShift, sino simplemente como función de encontrar un índice de una barra en un momento determinado, y no entiendo a qué te refieres con universalidad. Y no creo que sea razonable utilizar todas las funciones anteriores por el mayor coste de tiempo. (Recuerda los anuncios de polvos Dosya). La cuestión es que el uso de esta función se produce muy a menudo en ciclos grandes, lo que aumenta significativamente el tiempo de ejecución del programa, y yo soy terriblemente codicioso para el tiempo de ejecución. He hecho experimentos calculando el tiempo de ejecución de varias funciones (y no sólo yo, ver post anterior) y esta opción es definitivamente la más rápida. Incluso esta variante, que se posiciona como la más rápida, es la misma, pero la construcción(Bars(NULL,0,t,32000000000)-1;) es aún más sencilla. Por supuesto, depende de cada uno lo que utilice.

En cualquier caso, gracias por su sustancioso comentario.

 
Nikolai Semko:

Pero es muy extraño intentar utilizar esta función para recibir el número de barras (o el índice de una barra) desde el momento actual, es decir,TimeCurrent(), cuando ya está claro que la barra es cero. Es extraño que la funciónBars() dé 0 en lugar de 1 enTimeCurrent().

TimeCurrent() era sólo un caso especial que tenía a mano.

Ahora leo con más atención esta nota a la función Bars():

"Cuando se solicita el número de compases en un rango de fechas determinado , sólo se tienen en cuenta los compases cuya hora de apertura se encuentra dentro de ese rango. Por ejemplo, si el día actual de la semana es el sábado, al solicitar el número de barras semanales con start_time=lastTuesday y stop_time=lastFriday, la función devuelve 0 porque la hora de apertura del marco temporal semanal siempre cae en domingo y ninguna barra semanal cae en el rango especificado".

Dado que TimeCurrent() es casi todo el tiempo posterior a la hora de apertura de la barra actual, la función Bars( ) devuelve 0. Por lo tanto, si pasamos la hora correspondiente a las 02:05 en el timeframe horario como parámetro start_time , y queremos que se valide la barra que comenzó a las 2, debemos obtener la hora de apertura de la barra (02:00:00) a través de CopyTime() . De lo contrario, la función Bars() ignorará esta barra.

Por ejemplo, si la hora es 3:30, entiendo que en la TF horaria, la hora 2:05 se refiere a la barra con índice 1. Ninguna de las funciones de la 2ª página devolverá este índice. Con esta corrección, la función de Renat Akhtyamov ha devuelto lo que esperaba.

int iBarShift2(string symbol, ENUM_TIMEFRAMES timeframe, datetime time)
{
  datetime tm0[1], tm1[1];      
  CopyTime(symbol, timeframe, 0, 1, tm0);             // время открытия 0-го бара
  CopyTime(symbol, timeframe, time, 1, tm1);          // время открытия бара, в который попадает указанный time

  return Bars(symbol, timeframe, tm0[0], tm1[0])-1;
}

Adjunto un script, con 4 opciones de funciones de búsqueda de índices, que he utilizado como prueba.

Archivos adjuntos:
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

ElTimeCurrent() es sólo un caso especial encontrado.

Ahora leo con más atención esta nota a la función Bars():

"Cuando se solicita el número de compases en un rango de fechas determinado , sólo se tienen en cuenta los compases cuya hora de apertura se encuentra dentro de ese rango. Por ejemplo, si el día actual de la semana es el sábado, al solicitar el número de barras semanales con start_time=lastTuesday y stop_time=lastFriday, la función devuelve 0 porque la hora de apertura del marco temporal semanal siempre cae en domingo y ninguna barra semanal cae en el rango especificado".

Dado que TimeCurrent() es casi todo el tiempo posterior a la hora de apertura de la barra actual, la función Bars( ) devuelve 0. Por lo tanto, si pasamos la hora correspondiente a las 02:05 en el timeframe horario como parámetro start_time y queremos que se valide la barra que comenzó a las 2, debemos obtener la hora de apertura de la barra (02:00:00) mediante CopyTime() . De lo contrario, la función Bars() ignorará esta barra.

Por ejemplo, si la hora es ahora las 3:30, entiendo que en el marco temporal horario, las 2:05 se refieren a la barra con índice 1. Este índice no será devuelto por ninguna función de la 2ª página. Con esta corrección, la función de Renat Akhtyamov ha devuelto lo que esperaba.

Adjunto un script, con 4 opciones de funciones de búsqueda de índices, que he utilizado como prueba.

Por supuesto, tengo que pasar el tiempo de la barra. Me olvidé de especificar.
 
No entiendo por qué esta función no existe todavía en SB
 
transcendreamer:
No entiendo por qué esta función todavía no está disponible en el SB

Probadas todas las variantes, la más correcta es la de Alain Verleyen.
(probado en un indicador complejo con muchos objetos)
 
Taras Slobodyanik:

Probadas todas las variantes, la más correcta es la de Alain Verleyen.
(probado en un indicador complejo con muchos objetos)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • votos: 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

En mi opinión, el uso de la funciónSeriesInfoInteger es redundante, porque no es gratuita.

Era:

int iBarShift3( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, const bool Exact = false )
{
  static int Res = -1;
  static string LastSymb = NULL;
  static ENUM_TIMEFRAMES LastTimeFrame = 0;
  static datetime LastTime = 0;
  static bool LastExact = false;

  time -= time % ::PeriodSeconds(TimeFrame);

  if ((time != LastTime) || (Symb != LastSymb) || (TimeFrame != LastTimeFrame) || (Exact != LastExact))
  {
    datetime LastBar;

     if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
     {
        if (time > LastBar)
          Res = 0;
        else
        {
          const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);

          if (Shift > 0)
            Res = Shift - 1;
        }
      }

    LastTime = time;
    LastSymb = Symb;
    LastTimeFrame = TimeFrame;
    LastExact = Exact;
  }

  return(Res);
}

Se convirtió:

int iBarShift3(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,const bool Exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static bool LastExact=false;
   static int PerSec=::PeriodSeconds(LastTimeFrame);
   
   if (LastTimeFrame!=TimeFrame) PerSec=::PeriodSeconds(TimeFrame);
   time-=time%PerSec;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame) || (Exact!=LastExact))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
      LastExact=Exact;
     }

   return(Res);
  }

La ganancia de velocidad es de aproximadamente una vez y media.

Y parece ser la opción más rápida. Verdadero, el último parámetroExact es falso, y puede ser eliminado. Pero en mi opinión no es necesario. Personalmente nunca me he encontrado con tareas en las que necesitáramosExact= true.

Pero si alguien lo necesita, no puede prescindir de CopyTime y es mejor utilizar lavariante de @Alain Verleyen.

SZY: He omitido las llamadas superfluas a la funciónPeriodSeconds, si TF no ha cambiado desde la última llamada. Sin embargo, la ganancia es escasa: un pequeño porcentaje, pero aún así.

Y una observación más: la construcción

time-=time%PerSec;
no funcionará correctamente con PERIOD_W1 y PERIOD_MN1 porque comienza el 1 de enero de 1970, que no es un lunes, sino un jueves. Y cada mes tiene un número diferente de segundos.
 
Nikolai Semko:

En mi opinión, el uso de la funciónSeriesInfoInteger es redundante, porque no es gratuita.

Era:

Se convirtió:

La ganancia de velocidad es de aproximadamente una vez y media.

Y parece ser la opción más rápida. Verdadero, el último parámetroExacto es falso. Pero si me preguntas, no lo necesitas.

¿O me equivoco?

SZY: También he omitido las llamadas superfluas a la funciónPeriodSeconds, si TF no ha cambiado desde la última llamada. La ganancia es realmente leve -un poco de porcentaje, pero aún así.

No entiendo lo inteligente que es este código, por eso quiero hacerte una pregunta. ¿Funcionará el código si el gráfico no es de día completo?

 
Aleksey Vyazmikin:

Lo abstruso del código no me queda claro, así que preguntaré. ¿Funcionará el código si el gráfico no es de día completo?

No entiendo la esencia de la pregunta. Pongámoslo de otra manera.

El gráfico no es siempre un día completo, excepto el primer segundo del día.

¿De qué plazo estamos hablando? ¿Un día?

¿Y qué le impide comprobarlo?

El código no es mío, sólo lo simplifiqué y lo hice más rápido.

En mi mensaje anterior hice un añadido sobrePERIOD_W1 y PERIOD_MN1.

Todos los algoritmos anteriores, incluido el de @Alain Verleyen, tienen situaciones anormales.

Se puede crear un análogo completo de iBarShift MQL4, pero el código será bastante engorroso, y no le veo ningún sentido.

 
Nikolai Semko:

No entiendo el sentido de la pregunta. Pongámoslo de otra manera.

El gráfico no es siempre un día completo, excepto el primer segundo del día.

¿De qué TF estamos hablando? ¿Un día?

¿Y qué le impide comprobarlo?

El código no es mío, sólo lo simplifiqué y lo hice más rápido.

En mi mensaje anterior hice un añadido sobrePERIOD_W1 y PERIOD_MN1.

Todos los algoritmos anteriores, incluido el de @Alain Verleyen, tienen situaciones anormales.

Se puede crear un análogo completo de iBarShift MQL4, pero el código será muy engorroso, y no veo el punto en eso.

No lo he probado porque hay que saber con certeza si el código funcionará para una determinada situación, de lo contrario no es correcto culpar a otra persona si se ha equivocado.

Me refiero a situaciones como esta: supongamos que tenemos 14 horas en un día (o menos, si no hubiera cotizaciones cada hora), tengo un gráfico M1 y necesito saber el desplazamiento de una barra en M15 del día anterior. Es decir, ¿funcionará todo correctamente si tengo 45 minutos en una hora o 14 horas en un día, o cualquier otra caída de tiempo/conmutación?