Analogue à iBarShift - page 14

 
fxsaber:

Alors je ne comprends pas pourquoi Bars pense que 18:00:01 appartient à M1-bar 18:01 et non 18:00.

Et la logique ici est la même que le fait que ma fille en soit à son deuxième anniversaire, alors qu'elle n'a eu qu'un an il y a une semaine. Ou encore, aujourd'hui, nous sommes le 09.04.2018, alors que le 01 janvier 00, c'était il y a 2017 ans, 3 mois et 8 jours .

À propos, TimeCurrent doit être remplacé par SYMBOL_TIME.

Merci ! Je ne savais vraiment pas qu'il existait un tel identifiant.

 

Au fait, lorsque j'ai testé l'exactitude de l'algorithme iBars en le comparant à la référence Bars dans MQL4, en essayant différentes variantes au hasard, j'ai trouvé un bug dans Bars :

Print(Bars(_Symbol,PERIOD_MN1,D'2005.08.31 00:00:00',D'2005.08.31 23:00:00')); // 1  должен быть 0, т.к. временной диапазон находиться внутри одного бара.
Print(Bars(_Symbol,PERIOD_MN1,D'2006.08.31 00:00:00',D'2006.08.31 23:00:00')); // 0

Un tel bogue n'existe pas dans MQL5.

Bien sûr, ce n'est pas significatif, puisqu'il n'apparaît que dans TF = MN1, aux dates 30 et 31, stop_time = 23 et seulement avant 2005 :))))

Voici le script pour MQL4 qui l'attrape, et iBars s'est avéré être plus de référence que les Bars natives.

Dossiers :
TestiBars.mq4  10 kb
 
fxsaber:


Au fait, TimeCurrent devrait être remplacé par SYMBOL_TIME.

Non, vous n'en avez pas besoin.
Cela n'ajoutera pas de correction, car TimeCurrent() est universel pour tous les symboles, car il renvoie la dernière heure d'arrivée de la cotation pour tous les symboles, et non l'heure actuelle.

En même temps, SymbolInfoInteger(symbol_name,SYMBOL_TIME) est très lent comparé à TimeCurrent(), et ce temps est nécessaire à chaque appel de iBars

 

Pour ceux qui sont intéressés.

Version modifiée d'iBars (similaire aux barres intégrées, mais sans les problèmes et plus rapide).

Correction de quelques bogues.

Si vous avez remarqué que votre code MQL5 se bloque pendant 10-20 secondes tout à coup et a la fonction Bars, qui peut retourner 0, alors je recommande fortement de le remplacer par cette version.
Il fonctionnera plus rapidement et sans accrocs.

int iBars(string symbol_name,ENUM_TIMEFRAMES  timeframe,datetime start_time,datetime stop_time)
  {
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static datetime LastTime0=0;
   static int PerSec=0;
   static int PreBars=0;
   static datetime LastBAR=0;
   static datetime LastTimeCur=0;
   datetime TimeCur;
   if(stop_time<start_time) {TimeCur=stop_time; stop_time=start_time; start_time=TimeCur; }
   TimeCur=TimeCurrent();
   if(LastTimeFrame!=timeframe) if(timeframe==PERIOD_MN1) PerSec=2419200; else PerSec=::PeriodSeconds(timeframe);
   if(timeframe<PERIOD_W1) TimeCur-=TimeCur%PerSec;
   if(start_time>TimeCur) {LastSymb=NULL; return(0);}
   if(LastTimeFrame!=timeframe || LastSymb!=symbol_name || ((TimeCur-LastBAR)>0 && TimeCur!=LastTimeCur))
      LastBAR=(datetime)SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE);

   LastTimeCur=TimeCur;
   if(PerSec==0) return(0);
   if(start_time>LastBAR)
     {LastTimeFrame=timeframe; LastSymb=symbol_name; return(0);}

   datetime tS,tF=0;
   bool check=true;
   if(timeframe<PERIOD_W1) tS=start_time-(start_time-1)%PerSec-1;
   else if(timeframe==PERIOD_W1) tS=start_time-(start_time-259201)%PerSec-1;
   else
     {
      PerSec=2678400;
      MqlDateTime dt;
      TimeToStruct(start_time-1,dt);
      tS=dt.year*12+dt.mon;
     }
   if(stop_time<=LastBAR)
     {
      if(timeframe<PERIOD_W1) tF=stop_time-(stop_time)%PerSec;
      else if(timeframe==PERIOD_W1) tF=stop_time-(stop_time-259200)%PerSec;
      else
        {
         MqlDateTime dt0;
         TimeToStruct(stop_time,dt0);
         tF=dt0.year*12+dt0.mon;
        }
      if(tS==tF) {PreBars=0; check=false;}
     }
   if((LastTimeFrame!=timeframe || LastSymb!=symbol_name || tS!=LastTime || tF!=LastTime0) && check)
      PreBars=Bars(symbol_name,timeframe,start_time,stop_time);
   LastTime=tS; LastTime0=(datetime)tF;
   LastTimeFrame=timeframe;
   LastSymb=symbol_name;
   return(PreBars);
  }
 
Nikolai Semko:

Version modifiée de iBars(similaire aux barres intégrées, mais sans problèmes et plus rapide).

Correction de quelques bogues.

La fonction intégrée Bars() est surchargée :

1. int Bars(const string symbol_name,ENUM_TIMEFRAMES timeframe)
2. int Bars(const string symbol_name,ENUM_TIMEFRAMES timeframe,datetime start_time,datetime stop_time)

Vous n'avez qu'un seul formulaire d'appel.

 
Artyom Trishkin:

La fonction intégrée Bars() est surchargée :

Vous n'avez qu'un seul formulaire à appeler.

si vous avez besoin d'un formulaire court, vous pouvez utiliser le formulaire intégré. Il n'y a pratiquement aucun problème.

 
Nikolai Semko:

Non, ce n'est pas nécessaire.
Cela n'ajoutera pas de correction, car TimeCurrent() est universel pour tous les symboles, car il renvoie la dernière heure d'arrivée de la cotation pour tous les symboles, et non l'heure actuelle.

SymbolInfoInteger(symbol_name,SYMBOL_TIME) est très lent comparé à TimeCurrent(), et ce temps est nécessaire chaque fois que iBars est appelé

Les cotypes peuvent aller pour tous les personnages sauf celui qui nous intéresse.

Ok, j'ai regardé la nouvelle source. J'ai vu que les modifications, qui ont été discutées, n'ont pas été faites. Je me retire.

 
Pourquoi les développeurs ne le font-ils pas eux-mêmes ?
 
Il serait beaucoup plus pratique pour les utilisateurs d'appeler une fonction et d'obtenir un tableau synchronisé (aligné dans le temps) de rangées sur plusieurs instruments.
 
Au fait, à propos de la fonction Bars(). C'est peut-être la cause de l'accrochage.
Raison: