Indiquer une nouvelle barre

 

Je me demande comment indiquer quand une nouvelle barre voit la lumière du jour.
Je m'inquiète avant tout des performances. Sur certains symboles, je vois des ticks toutes les 20 ms. Pas beaucoup de temps pour réagir.

Une idée est 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 ...
          }

Une autre idée pourrait être de vérifier si le nombre de barres a été incrémenté.

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

J'ai également vérifié OnChartEvent, mais je n'ai trouvé aucun moyen de différencier les nouvelles barres des autres.

Merci pour votre évaluation

WIllbur

 

Les barres et le volume ne sont pas fiables pour détecter une nouvelle barre.

Un ordinateur travaille en nanosecondes, donc un EA bien codé peut faire beaucoup 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.
 
Voir ce sujet :
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
 

Merci Alain,

Très intéressant... exactement ce que je pensais... 10 fois plus rapide ... hmmm.

C'est à dire : TimeCurrent() est rapide et synchrone avec les bords des barres ?

Pourquoi .... hmmm ...

J'ai besoin d'un peu de temps pour y réfléchir.

Willbur

 

Ok - pour les gens qui aiment ce genre de choses : Mon étude sur ce problème.

J'ai écrit une phrase dans un fichier dans chaque événement "OnTick".

TimeLocal (PC CLock), TimeCurrent(), en utilisant SymbolInfoTick() quelques informations sur le dernier tick qui est arrivé et - en utilisant CopyRates() - quelques informations sur la barre actuelle.


Un exemple de "USD/JPY" - La période est "M1" :

Il est 19:43:01 sur l'horloge du PC lorsque le premier tick de la 43ème minute est entré, en même temps qu'une nouvelle barre est apparue.
A part le fait que le tick-volume n'est pas 1, c'est le cours normal des choses.



Parfois, ce n'est pas si facile - comme dans ce cas :

Le PC montre déjà 19:42:00 quand trois ticks supplémentaires de la barre 41min sont arrivés. Ils ont toujours un horodatage de 19:41:59.

Maintenant le monde prend une profonde respiration - 8.150 msec de silence total.

Puis - le PC affiche déjà 19:42:09 - le premier tick de la nouvelle barre - la barre de 42 min - arrive.
Le tick est marqué 19:42:07 et - parce que c'est la barre de 19:42 qui entre en jeu - l'horodatage de la barre est 19:42:00.


Maintenant .... hmmm ....

1. Est-ce que TimeCurrent() est toujours égal à l'horodatage du tick ?

J'ai vérifié 40.000 enregistrements et j'ai trouvé seulement cinq cas dans lesquels le TimeCurrent est déjà commuté alors que l'horodatage du dernier tick ne l'est pas.

2. Le dernier tick est-il toujours en avance sur l'ouverture de la nouvelle barre ?

(à suivre)

 

TimeCurrent() est l'heure du dernier tick du serveur, cela dépend de votre code si c'est le symbole de votre graphique ou non.

Je ne comprends pas votre problème de "dernier tick", vous devriez montrer le code qui produit cette sortie.

 

Bonjour Alain

Je vérifie le TimeCurrent() dans OnTick(), ce qui devrait garantir qu'il appartient au symbole que je traite.

Eh bien, cela devrait être mon "New Bar Identifier" - petit et rapide - qu'en pensez-vous ?

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

Je vais le vérifier avec cette séquence :

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

Bonjour Alain

Je vérifie le TimeCurrent() dans OnTick(), ce qui devrait garantir qu'il appartient au symbole que je traite.

Eh bien, ceci devrait être mon "Nouvel identifiant de barre" - petit et rapide - qu'en pensez-vous ?

Intéressant, mais je ne pense pas que ce soit universel (fonctionne dans tous les cas)... Je vais vérifier, pas le temps actuellement.
 
 

Voici ma version finale.

En fait, je suis un peu inquiet parce que c'est si facile.

Alain : Ce serait bien si tu pouvais donner ta bénédiction.

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


Salutations de Cologne
Willbur

 

La méthode la plus simple :

static datetime tlastbar=0 ;

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

bool isnewbar=tnewbar!=tlastbar ;

tlastbar=tnewbar ;