Analogue à iBarShift - page 4

 
Nikolai Semko:

À mon avis, l'utilisation de la fonctionSeriesInfoInteger est redondante, car elle n'est pas libre.

C'était :

Devenu :

Gain de vitesse d'environ un facteur et demi.

Gain de 2 %. Note.

ne fonctionnera pas correctement avec PERIOD_W1 et PERIOD_MN1, parce qu'il est compté à partir du 1er janvier 1970 et qu'il s'agit du jeudi et non du lundi. Et chaque mois a un nombre différent de secondes.

Ceci doit être ajouté à la documentation de PeriodSeconds.

 
Aleksey Vyazmikin:

Je ne l'ai pas vérifié - parce que j'ai besoin de savoir avec certitude si le code fonctionnera ou non dans une situation spécifique, car il n'est pas correct de blâmer quelqu'un d'autre si j'ai fait une erreur moi-même.

Je parle de situations comme celle-ci : supposons que nous ayons 14 heures dans une journée (ou moins, s'il n'y avait pas de cotations toutes les heures), j'ai un graphique M1 et j'ai besoin de connaître le décalage d'une barre sur M15 pour le jour précédent. C'est-à-dire que tout fonctionnera correctement si j'ai 45 minutes dans une heure ou 14 heures dans un jour, ou toute autre baisse de temps/de commutation ?

Je pense personnellement qu'il est approprié d'utiliser une telle fonctionnalité :

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1; 
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }

Mais il faut noter que ce n'est pas un analogue complet de la fonctioniBarShift de MQL4, au moins en raison du fait qu'elle n'a pas le paramètreExact.

Sinon, il est identique.

Je colle un simple script MQL4 qui montre l'identité complète de la fonction standard avec celle-ci.

Si les valeurs de la fonction standardiBarShift et de ma fonction ne sont pas égales, alors Print. Ça n'a rien imprimé pour moi.

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime t=TimeCurrent()+1000;
   const ENUM_TIMEFRAMES tf[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
   while(!IsStopped())
     {
      for(int i=0; i<9;i++)
        {
         int i1=iBarShift(NULL,tf[i],t);
         int i2=iBarShift2(NULL,tf[i],t);
         if(i1!=i2) Print(EnumToString(tf[i]),"   ",TimeToString(t),"   ",i1,"   ",i2);
        }
      t-=10;
      Comment(TimeToString(t));
     }

  }
//+------------------------------------------------------------------+
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
 
fxsaber:

Taux de gain de 2 %. Note.

Quoi, vraiment ?

J'étais trop paresseux pour mettre GetMicrosecondCount(), alors j'ai fait confiance au profilage.

 
Nikolai Semko:

Vraiment ?

J'étais trop paresseux pour configurer GetMicrosecondCount(), alors j'ai fait confiance au profilage.

Le profilage concerne autre chose. 2% est le gain maximum que vous pouvez obtenir.

250 millions d'appels dans le Tester sur ma machine donnent une économie de 1 seconde.

Votre option est définitivement la meilleure ! Mais je ne peux même pas imaginer pourquoi dans MT5 vous devez travailler avec des barres.

 
fxsaber:

Mais je ne sais pas pourquoi je dois travailler avec des barres dans MT5.

Je l'utilise quand je contrôle la souris. Par exemple ici.

 
Nikolai Semko:

Je l'utilise pour contrôler la souris. Ici, par exemple.

Oui, c'est ce que je ne comprends pas.

 
fxsaber:

Oui, c'est ce que je ne comprends pas.

Et je ne comprends pas le malentendu ;))

Par exemple, j'ai un canal dont l'une des caractéristiques est l'heure de début (bord gauche). Et je dois construire ce canal sur différents TFs. Eh bien, quelle autre alternative ai-je que de trouver le numéro de barre dans un nouveau TF ?

J'ai beaucoup d'autres choses.

Par exemple, quand je combine toutes les TF en une seule avec une échelle logarithmique. C'est un sujet très cool. On ne peut pas non plus se passer de l'analogue iBarShift ici.

 
Nikolai Semko:

Je pense personnellement qu'il est raisonnable d'utiliser une telle fonction :

Mais il faut noter qu'il ne s'agit pas d'un analogue complet de la fonctioniBarShift standard de MQL4, au moins parce qu'elle n'a pas le paramètreExact

Sinon, il est identique.

Je colle un simple script MQL4 qui montre l'identité complète de la fonction standard avec celle-ci.

Si les valeurs de la fonction standardiBarShift et de ma fonction ne sont pas égales, alors Print. Je n'ai rien imprimé.

Non, ce n'est pas le cas à cause de Comment().

Si on l'enlève, il y a un décalage de 1, mais je ne pense pas que ce soit une erreur, car en fait la nouvelle barre est définie en deux algorithmes avec un décalage d'une demi-barre. Ma version de la détection des nouvelles barres me semble plus logique que la version standard.

 
Nikolai Semko:

Et je ne comprends pas le malentendu ;))

Je ne comprends pas l'intérêt d'utiliser des barres. CopyRates, etc.

 

Pourquoi le script est-il si lent ?

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:20:49.300 Scripts script BS (Si Splice,H4) loaded successfully

2018.03.30 09:21:20.209 Scripts script BS (Si Splice,H4) removed

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs

input ENUM_TIMEFRAMES TF=PERIOD_D1;
input int Bar=3;
input int calcN=1;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("1 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("1 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }



   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift2(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("2 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("2 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }
   return;

  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+  
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+   
int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
   if(index < 0) return(-1);
   datetime Arr[];
   if(CopyTime(symbol,tf,index,1,Arr)>0)
      return(Arr[0]);
   else return(-1);
  }
//+------------------------------------------------------------------+
Raison: