Indicar una nueva barra

 

Me pregunto cómo indicar cuando una nueva barra ve la luz del día.
Principalmente me preocupa el rendimiento. En algunos símbolos he visto ticks cada 20 ms. No hay mucho tiempo para reaccionar.

Una idea es rates.tick_volume

Mqlrates rates[1];

OnInit()
    {
    if(CopyRates(_Symbol,_Period,0,1,rates) < 1)
       if(rates[0].tick_volume == 1)
          {
          ... deal with new bar ...
          }

Otra idea podría ser la de comprobar si el número de barras se ha incrementado

OnInit()
  {
  if(BarsOld < Bars(_Symbol,_Period))
     {
     BarsOld = Bars(_Symbol,_Period);
     ... deal with new bar ...
     }

He comprobado también OnChartEvent, pero no he encontrado ninguna manera de diferenciar las nuevas barras de otras cosas.

Gracias por tu valoración

WIllbur

 

Las barras y el volumen no son fiables para detectar una nueva barra.

Un ordenador trabaja en nano segundos, por lo que un EA bien codificado puede hacer mucho en 20 ms.

The "New Bar" Event Handler
The "New Bar" Event Handler
  • 2010.10.11
  • Konstantin Gruzdev
  • www.mql5.com
MQL5 programming language is capable of solving problems on a brand new level. Even those tasks, that already have such solutions, thanks to object oriented programming can rise to a higher level. In this article we take a specially simple example of checking new bar on a chart, that was transformed into rather powerful and versatile tool. What tool? Find out in this article.
 
Ver este tema :
Improve your time execution by removing Bars function calls
Improve your time execution by removing Bars function calls
  • www.mql5.com
After a basic profiling I get the following results :. - - Category: trading systems
 

Gracias Alain,

muy interesante ... exactamente lo que supongo ... 10 veces más rápido ... hmmm.

Significa: TimeCurrent() es rápido y syncron a los bordes de las barras ?

Por qué .... hmmm ...

Necesito un tiempo para pensar en eso.

Willbur

 

Ok - para la gente que le gusta este tipo de cosas: Mi estudio sobre este tema.

Escribí una frase en un archivo en cada evento "OnTick".

TimeLocal (PC CLock), TimeCurrent(), usando SymbolInfoTick() alguna información sobre el último tick que entró y - usando CopyRates() - alguna información sobre la Barra actual.


Un ejemplo de "USD/JPY" - El periodo es "M1":

Son las 19:43:01 en el Reloj PC cuando entra el primer tick del minuto 43, al mismo tiempo que surge una nueva barra.
Aparte del hecho de que el volumen de ticks no es 1, este es el flujo normal de las cosas.



A veces no es tan fácil - Como en este caso:

El PC muestra ya 19:42:00 cuando llegaron tres ticks más de la barra de 41min. Todavía tienen una marca de tiempo de 19:41:59.

Ahora el mundo toma una respiración profunda - 8.150 mseg de quietud total.

Entonces - el PC muestra ya 19:42:09 - el primer tick de la nueva barra - la barra de 42 min - entra.
El Tick está marcado con 19:42:07 y - porque es la barra de 19:42 que viene con ella - el timestamp de la barra es 19:42:00


Ahora .... hmmm ....

1. ¿Es TimeCurrent() siempre igual a la marca de tiempo del tick?

He comprobado 40.000 registros y sólo he encontrado cinco casos en los que el TimeCurrent ya está cambiado mientras que la marca de tiempo del último tick no lo está.

2. ¿Está el último tick siempre por delante de la apertura de la nueva barra?

(continuará)

 

TimeCurrent() es el tiempo del último tick del servidor, depende de tu código si es de tu símbolo del gráfico o no.

No entiendo tu asunto del "último tick", deberías mostrar el código que produjo esta salida.

 

Hola Alain

Compruebo el TimeCurrent() en OnTick() que debería asegurar, que pertenece al símbolo que trato.

Bueno, esto debería ser mi "Nuevo identificador de barra" - pequeño y rápido - ¿qué te parece?

//---  New Bar           
bool   NewBar = false;
long   currPeriodSeconds;
double currPeriodProgress = 0;

int OnInit(void)  //-----------------------------------------------
{
      currPeriodSeconds = PeriodSeconds();
      return(INIT_SUCCEEDED);
}

void OnTick()  //--------------------------------------------------
{
      if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
           NewBar = true;
      else NewBar = false;
     

      currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);

Voy a comprobarlo con esta secuencia:

//---  Just for testing
int    ExtHdlFile1=0;
       MqlRates rates[1];
        
//---  New Bar           
bool   NewBar = false;
long   currPeriodSeconds;
double currPeriodProgress = 0;

int OnInit(void) // -------------------------------------------------------
{
      currPeriodSeconds = PeriodSeconds();

      ExtHdlFile1=FileOpen("NewBarTest.csv",FILE_READ|FILE_WRITE|FILE_CSV);
      FileSeek (ExtHdlFile1,0,SEEK_END); 
      FileWrite(ExtHdlFile1,  "TimeLocal",
                              "TimeCurrent",
                              "rates[0].time",
                              "rates[0].tick");
      return(INIT_SUCCEEDED);
}

void OnTick() // -----------------------------------------------------------
{
      if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
           NewBar = true;
      else NewBar = false;
     
      currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);

//--- lets check this

      if(NewBar)
         {
         // last Time Stamp of old Bar
         FileWrite(ExtHdlFile1, " ",
                                " ",
                                TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
                                IntegerToString(rates[0].tick_volume));
         // get the new bar                     
         if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return;
         // first Time Stamp of new Bar       
         FileWrite(ExtHdlFile1,TimeToString(TimeLocal(),TIME_MINUTES|TIME_SECONDS),
                               TimeToString(TimeCurrent(), TIME_MINUTES|TIME_SECONDS),
                               TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
                               IntegerToString(rates[0].tick_volume));
         }

      if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return; // != clean code - just a test
}

void OnDeinit(const int reason)
{
      FileClose(ExtHdlFile1);
      return;
}

 
Willbur:

Hola Alain

Compruebo el TimeCurrent() en OnTick() que debería asegurar, que pertenece al símbolo que trato.

Bueno, esto debería ser mi "Nuevo identificador de barra" - pequeño y rápido - ¿qué te parece?

Interesante, pero no creo que sea universal (que funcione en todos los casos)... Lo comprobaré, no tengo tiempo actualmente.
 
 

Aquí está mi versión final.

De hecho, estoy un poco preocupado porque es muy fácil.

Alain: Estaría bien que dieras la bendición.

// -----------------------------------------------------------------------
bool NewBar(void)
{
bool iNewBar = false;
static double currPeriodProgress = 0;

   if(MathMod(TimeCurrent(),PeriodSeconds()) < currPeriodProgress) iNewBar = true;

   currPeriodProgress = MathMod(TimeCurrent(),PeriodSeconds());

   return(iNewBar);
}
// ------------------------------------------------------------------------
void OnTick()
{
    if(NewBar())     PlaySound("tick.wav");


Saludos desde Colonia
Willbur

 

La forma más fácil:

static datetime tlastbar=0;

datetime tnewbar=iTime(NULL,PERIOD_CURRENT,0);

bool isnewbar=tnewbar!=tlastbar;

tlastbar=tnewbar;