Download MetaTrader 5
To add comments, please log in or register
Search in documentation is available via MetaTrader 5. Search and learn!
Willbur
198
Willbur 2016.04.19 15:55 

I wounder how to indicate when a new bar sees the light of day.
Primarily I worry about performance. On some Symbols I saw ticks every 20 ms. Not so much time to react.

One idea is 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 ...
          }

Another idea could be the check wether the number of bars has been incremented

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

I checked also OnChartEvent, but I found no way to differentiate new bars from other stuff.

Thanks for you rating

    WIllbur

Alain Verleyen
Moderator
30295
Alain Verleyen 2016.04.19 16:25  

Bars and Volume are unreliable to detect new bar.

A computer is working in nano seconds, so a well coded EA can do a lot in 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.
Alain Verleyen
Moderator
30295
Alain Verleyen 2016.04.19 16:47  
See this topic :
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
Willbur
198
Willbur 2016.04.20 12:24  

Thank you Alain,

very interesting ... exactly what I guess . . . 10 times faster  . ..  hmmm.

Means: TimeCurrent() is fast and syncron to the bars borders ?

Why .... hmmm ...

I need a while to thing about that.

Willbur

Willbur
198
Willbur 2016.04.27 23:59  

Ok - for people who like stuff like this:     My study  about this issue.

I wrote a sentence into a file in every "OnTick" Event.

        TimeLocal (PC CLock), TimeCurrent(),  using SymbolInfoTick() some information about the last tick which came in and - using CopyRates() - some information about the current Bar.


An example from "USD/JPY" -  Period is  "M1":

It's 19:43:01 on the PC-Clock when the first tick of the 43th minute cames in , same time a new bar arose.
Beside the fakt, that the tick-volume is not 1. this is the normal flow of things.



Sometimes it is not so easy -  Like in this case:

The PC shows already 19:42:00 when three more ticks of the 41min bar came in. They still have a timestamp of 19:41:59.

Now the world takes a deep breath - 8.150 msec of total stillness.

Then - the PC shows already 19:42:09 - the first tick of the new bar - the 42 min bar - cames in.
The Tick is marked with 19:42:07 and - because it is the 19:42 bar which cames with it - the bars timestamp is 19:42:00


Now .... hmmm ....

1. Is TimeCurrent() always equal to the time stamp of the tick?

     I checked 40.000 record and found only five cases in which TimeCurrent is alredy switched over while the time stamp of the last tick is not.

2. Is last_tick always ahead of the opening of the new bar?

(to be continued)

Alain Verleyen
Moderator
30295
Alain Verleyen 2016.04.28 08:28  

TimeCurrent() is the time of the last tick from the server, it depends of your code if it's from your chart symbol or not.

I don't understand your "last tick" issue, you should show the code that produced this output.

Willbur
198
Willbur 2016.04.28 09:03  

Hi Alain

I check the TimeCurrent() in OnTick() which should ensure, it belongs to the symbol I deal with.

Well,  this should be my "New Bar Identifier" - small and fast - what do you think?

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

I am going to check it with this sequenz:

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

Alain Verleyen
Moderator
30295
Alain Verleyen 2016.04.28 09:25  
Willbur:

Hi Alain

I check the TimeCurrent() in OnTick() which should ensure, it belongs to the symbol I deal with.

Well,  this should be my "New Bar Identifier" - small and fast - what do you think?

Interesting, but I don't think it's universal (working in all cases)...I will check, no time currently.
Willbur
198
Willbur 2016.04.28 09:29  
Willbur
198
Willbur 2016.04.30 10:00  

Here is my final version.  

In fact I'm a bit worried becuase it is so easy.

Alain: It would be nice if you would issue the blessing.

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


Greetings from Cologne
    Willbur

Doerk Hilger
1120
Doerk Hilger 2016.04.30 12:53  

The easiest way:

static datetime tlastbar=0;

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

bool isnewbar=tnewbar!=tlastbar;

tlastbar=tnewbar; 

/ /1234
To add comments, please log in or register