Analogue à iBarShift - page 3

 
Vasiliy Pushkaryov:

Voici le script.

Ça se bloque. En le retirant de force du tableau, on obtient le résultat.

Je l'ai donc essayé, c'est pourquoi je vous l'ai recommandé. Mais puisque vous l'avez utilisé et qu'il vous convient, je ne changerai pas d'avis.

Je suis désolé, Vassili. Je vous ai mal compris. Je viens de lire votre message rapidement alors que je conduisais. Je pensais que c'était à propos du dernier paramètre, où j'ai32000000000, il s'avère que vous vouliez parler du paramètre t. Oui, en effet - c'est le seul cas où le résultat est différent de l'iBarShift() original du MQL4. Cependant, il est très étrange d'essayer d'utiliser cette fonction pour obtenir le nombre de barres (ou l'indice de barre) à partir du point de temps actuel, c'est-à-direTimeCurrent(), lorsqu'il est clair que la barre est nulle. En général, il est étrange que la fonctionBars() àTimeCurrent() produise 0, et non 1. Formellement, c'est un bug des développeurs, bien que cela dépende. Mais quelque chose ne peut pas se bloquer à cause de l'utilisation de la fonction standard Bars(), d'autant plus que le script a vérifiéPrint(), c'est-à-dire que tout est OK.
Comprenez, Vasily, je ne veux pas déprécier les autres implémentations de l'analogique iBarShift, j'utilise juste personnellement exactement cette construction(Bars(NULL,0,t,32000000000)-1;), car c'est la plus rapide. Et cette construction n'est pas utilisée comme un substitut de iBarShift, mais simplement comme une fonction permettant de trouver l'indice d'une barre à un moment donné, et je ne comprends pas ce que vous entendez par universalité. Et je ne pense pas qu'il soit raisonnable d'utiliser toutes les fonctions ci-dessus en raison du coût en temps plus élevé. (Rappelez-vous les publicités pour la poudre Dosya). Le problème est que l'utilisation de cette fonction se fait très souvent dans des cycles importants, ce qui augmente considérablement le temps d'exécution du programme, et je suis terriblement gourmand en temps d'exécution. J'ai fait des expériences en calculant le temps d'exécution de diverses fonctions (et pas seulement moi, voir le post précédent) et cette option est certainement la plus rapide. Même cette variante, qui se positionne comme la plus rapide, est la même, mais la construction(Bars(NULL,0,t,32000000000)-1;) est encore plus simple. Bien sûr, c'est à chacun de décider ce qu'il veut utiliser.

En tout état de cause, je vous remercie pour votre remarque de fond.

 
Nikolai Semko:

Mais il est très étrange d'essayer d'utiliser cette fonction pour recevoir le nombre de barres (ou l'indice d'une barre) à partir du moment actuel, c'est-à-direTimeCurrent(), lorsqu'il est déjà clair que la barre est nulle. Il est étrange que la fonctionBars() donne 0 au lieu de 1 àTimeCurrent().

TimeCurrent() était juste un cas particulier que j'avais sous la main.

Je lis maintenant plus attentivement cette note sur la fonction Bars():

"Lorsque l'on demande le nombre de bars dans une plage de dates donnée , seuls les bars dont l'heure d'ouverture se situe dans cette plage sont pris en compte. Par exemple, si le jour actuel de la semaine est le samedi, lorsque l'on demande le nombre de barres hebdomadaires avec start_time=lastTuesday et stop_time=lastFriday, la fonction renvoie 0 parce que l'heure d'ouverture du cadre hebdomadaire tombe toujours le dimanche et qu'aucune barre hebdomadaire ne tombe dans la plage spécifiée".

Comme TimeCurrent() est presque toujours postérieur à l'heure d'ouverture de la barre actuelle, la fonction Bars() renvoie 0. Donc, si nous passons le temps correspondant à 02:05 sur le TF horaire comme paramètre start_time , et que nous voulons que la barre qui a commencé à 2 heures soit valide, alors nous devons obtenir l'heure d'ouverture de la barre (02:00:00) par CopyTime() . Sinon, la fonction Bars() ignorera cette barre.

Par exemple, si l'heure est 3:30, je comprends que dans le TF horaire, l'heure 2:05 se réfère à la barre avec l'indice 1. Aucune des fonctions de la 2ème page ne retournera cet indice. Avec cette correction la fonction de Renat Akhtyamov a retourné ce que j'attendais.

int iBarShift2(string symbol, ENUM_TIMEFRAMES timeframe, datetime time)
{
  datetime tm0[1], tm1[1];      
  CopyTime(symbol, timeframe, 0, 1, tm0);             // время открытия 0-го бара
  CopyTime(symbol, timeframe, time, 1, tm1);          // время открытия бара, в который попадает указанный time

  return Bars(symbol, timeframe, tm0[0], tm1[0])-1;
}

Je joins un script, avec 4 options pour les fonctions de recherche d'index, que j'ai utilisé comme test.

Dossiers :
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

LeTimeCurrent() est juste un cas particulier rencontré.

Je lis maintenant plus attentivement cette note sur la fonction Bars():

"Lorsque l'on demande le nombre de bars dans une plage de dates donnée , seuls les bars dont l'heure d'ouverture se situe dans cette plage sont pris en compte. Par exemple, si le jour actuel de la semaine est le samedi, lorsque l'on demande le nombre de barres hebdomadaires avec start_time=lastTuesday et stop_time=lastFriday, la fonction renvoie 0 parce que l'heure d'ouverture du cadre hebdomadaire tombe toujours le dimanche et qu'aucune barre hebdomadaire ne tombe dans la plage spécifiée".

Comme TimeCurrent() est presque toujours postérieur à l'heure d'ouverture de la barre actuelle, la fonction Bars() renvoie 0. Donc, si nous passons le temps correspondant à 02:05 sur le timeframe horaire comme paramètre start_time , et que nous voulons que la barre qui a commencé à 2 heures soit valide, alors nous devons obtenir l'heure d'ouverture de la barre (02:00:00) par CopyTime() . Sinon, la fonction Bars() ignorera cette barre.

Par exemple, si l'heure est maintenant 3:30, je comprends qu'en temps horaire, 2:05 se réfère à la barre avec l'index 1. Cet index ne sera pas retourné par une fonction de la 2ème page. Avec cette correction la fonction de Renat Akhtyamov a retourné ce que j'attendais.

Je joins un script, avec 4 options pour les fonctions de recherche d'index, que j'ai utilisé comme test.

Bien sûr, je dois passer l'examen du barreau. J'ai oublié de préciser.
 
Je ne comprends pas pourquoi cette fonction n'existe pas encore dans SB
 
transcendreamer:
Je ne comprends pas pourquoi cette fonction n'est toujours pas disponible dans le SB.

J'ai essayé toutes les variantes, la plus correcte est celle d'Alain Verleyen.
(testé sur un indicateur complexe avec beaucoup d'objets)
 
Taras Slobodyanik:

J'ai essayé toutes les variantes, la plus correcte est celle d'Alain Verleyen.
(testé sur un indicateur complexe avec beaucoup d'objets)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • votes : 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

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

C'était :

int iBarShift3( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, const bool Exact = false )
{
  static int Res = -1;
  static string LastSymb = NULL;
  static ENUM_TIMEFRAMES LastTimeFrame = 0;
  static datetime LastTime = 0;
  static bool LastExact = false;

  time -= time % ::PeriodSeconds(TimeFrame);

  if ((time != LastTime) || (Symb != LastSymb) || (TimeFrame != LastTimeFrame) || (Exact != LastExact))
  {
    datetime LastBar;

     if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
     {
        if (time > LastBar)
          Res = 0;
        else
        {
          const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);

          if (Shift > 0)
            Res = Shift - 1;
        }
      }

    LastTime = time;
    LastSymb = Symb;
    LastTimeFrame = TimeFrame;
    LastExact = Exact;
  }

  return(Res);
}

Devenu :

int iBarShift3(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,const bool Exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static bool LastExact=false;
   static int PerSec=::PeriodSeconds(LastTimeFrame);
   
   if (LastTimeFrame!=TimeFrame) PerSec=::PeriodSeconds(TimeFrame);
   time-=time%PerSec;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
      LastExact=Exact;
     }

   return(Res);
  }

Le gain de vitesse est d'environ une fois et demie.

Et cela semble être l'option la plus rapide. Vrai, le dernier paramètreExact est faux, et il peut être supprimé. Mais à mon avis, ce n'est pas nécessaire. Personnellement, je n'ai jamais rencontré de tâches où nous avions besoin deExact= true.

Mais si quelqu'un en a besoin, il ne peut pas se passer de CopyTime et il est préférable d'utiliser lavariante de@Alain Verleyen.

SZY : J'ai contourné les appels superflus à la fonctionPeriodSeconds, si TF n'a pas changé depuis le dernier appel. Le gain est faible, cependant - quelques pour cent, mais quand même.

Et une autre remarque : Construction

time-=time%PerSec;
ne fonctionnera pas correctement avec PERIOD_W1 et PERIOD_MN1 car il commence le 1er janvier 1970, qui n'est pas un lundi, mais un jeudi. Et chaque mois a un nombre différent de secondes.
 
Nikolai Semko:

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

C'était :

Devenu :

Le gain de vitesse est d'environ une fois et demie.

Et cela semble être l'option la plus rapide. Vrai, le dernier paramètreExact est faux. Mais si tu me demandes, tu n'en as pas besoin.

Ou ai-je tort ?

SZY : J'ai également contourné les appels superflus à la fonctionPeriodSeconds, si TF n'a pas changé depuis le dernier appel. Le gain est vraiment léger - quelques pour cent, mais quand même.

Je ne comprends pas l'intelligence de ce code, c'est pourquoi je veux vous poser une question. Le code fonctionnera-t-il si le graphique n'est pas à jour ?

 
Aleksey Vyazmikin:

La complexité du code n'est pas claire pour moi, alors je vais demander. Le code fonctionnera-t-il si le graphique n'est pas un jour complet ?

Je ne comprends pas l'essence de la question. Dit d'une manière différente.

Le tableau n'est jamais complet, sauf pour la première seconde de la journée.

De quel délai parlons-nous ? Un jour ?

Et qu'est-ce qui vous empêche de vérifier ?

Le code n'est pas le mien, je l'ai juste simplifié et rendu plus rapide.

Dans mon message précédent, j'ai fait un ajout surPERIOD_W1 et PERIOD_MN1.

Tous les algorithmes précédents, y compris celui d'@Alain Verleyen, présentent des situations anormales.

Vous pouvez créer un analogue complet de iBarShift MQL4, mais le code sera assez lourd, et je n'y vois aucun intérêt.

 
Nikolai Semko:

Je ne comprends pas le sens de la question. Dit d'une manière différente.

Le tableau n'est jamais complet, sauf pour la première seconde de la journée.

De quel TF parlons-nous ? Un jour ?

Et qu'est-ce qui vous empêche de vérifier ?

Le code n'est pas le mien, je l'ai juste simplifié et rendu plus rapide.

Dans mon message précédent, j'ai fait un ajout surPERIOD_W1 et PERIOD_MN1.

Tous les algorithmes précédents, y compris celui d'@Alain Verleyen, présentent des situations anormales.

Vous pouvez créer un analogue complet de iBarShift MQL4, mais le code sera très lourd, et je n'en vois pas l'intérêt.

Je ne l'ai pas testé car il faut savoir avec certitude si le code fonctionnera dans une certaine situation, sinon il n'est pas correct de blâmer quelqu'un d'autre s'il a fait une erreur.

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 ?