Indicar uma nova barra

 

Eu fervo como indicar quando uma nova barra vê a luz do dia.
Preocupo-me principalmente com o desempenho. Em alguns símbolos eu vi carrapatos a cada 20 ms. Não tenho muito tempo para reagir.

Uma idéia é o volume.tick_volume

Mqlrates rates[1];

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

Outra idéia poderia ser a verificação se o número de barras foi aumentado.

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

Verifiquei também a OnChartEvent, mas não encontrei nenhuma maneira de diferenciar as barras novas de outras coisas.

Obrigado por sua avaliação

WIllbur

 

As barras e o volume não são confiáveis para detectar novas barras.

Um computador está trabalhando em nano segundos, então um EA bem codificado pode fazer muito em 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.
 
Veja este tópico :
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
 

Obrigado, Alain,

muito interessante ... exatamente o que eu acho ... 10 vezes mais rápido . ... hmmm.

Significa ..: TimeCurrent() é rápido e sincronizado com as bordas das barras ?

Por que .... hmmm ...

Preciso de um tempo para pensar sobre isso.

Willbur ...

 

Ok - para pessoas que gostam de coisas como esta: Meu estudo sobre este assunto.

Eu escrevi uma frase em um arquivo em cada evento "OnTick".

TimeLocal (PC CLock), TimeCurrent(), usando SymbolInfoTick() algumas informações sobre o último tick que chegou e - usando CopyRates() - algumas informações sobre a barra atual.


Um exemplo de "USD/JPY" - Período é "M1":

São 19:43:01 no PC-Clock quando o primeiro tick do 43º minuto chega, ao mesmo tempo em que surge uma nova barra.
Além do falso, que o volume do tique não é 1. este é o fluxo normal das coisas.



Às vezes não é tão fácil - como neste caso:

O PC já mostra 19:42:00 quando mais três tiquetaques do bar de 41min entraram. Eles ainda têm um carimbo da hora de 19:41:59.

Agora o mundo respira profundamente - 8.150 msec de quietude total.

Então - o PC já mostra 19:42:09 - o primeiro tique da nova barra - a barra de 42 minutos - entra.
O Tick é marcado com 19:42:07 e - porque é a barra de 19:42 que aparece com ele - o timestamp das barras é 19:42:00


Agora .... hmmm ....

1. O TimeCurrent() é sempre igual ao carimbo de tempo do tick?

Verifiquei o registro de 40.000 e encontrei apenas cinco casos em que o TimeCurrent já está trocado enquanto o carimbo de tempo do último carimbo não está.

2. O último_marcador está sempre à frente da abertura da nova barra?

(a ser continuado)

 

TimeCurrent() é a hora do último tick do servidor, depende do seu código se é ou não do seu símbolo gráfico.

Eu não entendo seu "último tick", você deve mostrar o código que produziu esta saída.

 

Oi Alain

Eu verifico o TimeCurrent() em OnTick() que deve garantir que ele pertence ao símbolo com o qual eu lido.

Bem, este deve ser meu "New Bar Identifier" - pequeno e rápido - o que você acha?

//---  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);

Vou verificá-lo com esta sequência:

//---  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:

Oi Alain

Eu verifico o TimeCurrent() em OnTick() que deve garantir que ele pertence ao símbolo com o qual eu lido.

Bem, este deve ser meu "New Bar Identifier" - pequeno e rápido - o que você acha?

Interessante, mas não acho que seja universal (trabalhando em todos os casos)...vou verificar, não há tempo atualmente.
 
 

Aqui está minha versão final.

Na verdade, estou um pouco preocupado porque é tão fácil.

Alain: Seria bom se você emitisse a bênção.

// -----------------------------------------------------------------------
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");


Saudações de Colônia
Willbur

 

A maneira mais fácil:

data/hora estática tlastbar=0;

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

bool isewbar=tnewbar!=tlastbar;

tlastbar=tnewbar=tnewbar;

Razão: