English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Les bases de la programmation MQL5 : Temps

Les bases de la programmation MQL5 : Temps

MetaTrader 5Exemples | 13 janvier 2022, 09:36
1 071 0
Dmitry Fedoseev
Dmitry Fedoseev

Contenu


Introduction

MQL5 offre un certain nombre de fonctions simples pour travailler avec le temps et vous ne devriez pas avoir de difficulté à vous familiariser avec elles. La gamme de tâches qui nécessitent l’utilisation de la date et de l’heure est assez petite. Les tâches principales sont les suivantes :

  • Pour effectuer certaines actions à un moment donné (Fig. 1). Il peut s’agir d’actions effectuées à la même heure chaque jour ou à une heure donnée de la journée et d’un jour donné de la semaine sur une base hebdomadaire ou simplement effectuées à une date et une heure données.

    Fig. 1. Point de temps.
    Fig. 1. Point de temps.

  • Pour activer ou désactiver certaines actions dans une plage de temps donnée (session de temps). Cela peut inclure une session de temps dans la journée (tous les jours d’un point de temps à un autre), l’activation / désactivation de certaines actions à des jours particuliers de la semaine, des sessions de temps d’un moment donné un jour de la semaine à un moment donné un autre jour de la semaine et juste des actions se situant dans une plage de dates et heures spécifiée.

    Fig. 2. Plage de temps.
    Fig. 2. Plage de temps.

En pratique, l’utilisation du temps est assez complexe. Les difficultés sont associées aux particularités de la mesure du temps et à l’environnement dans lequel les Expert Advisors et les indicateurs opèrent :

  • Des barres manquées sur le graphique en raison de l’absence de changements de prix. Ils sont particulièrement évidents sur des cadres temporel plus courts : M1, M5 et même M15. Les barres manquées peuvent également être observées sur des cadres temporels plus longs.

  • Les cotations de certains centres de traitement incluent des barres du dimanche qui devraient en fait appartenir au lundi.

  • Les Week-ends. Le jour de la semaine précédant le lundi est le vendredi et non le dimanche. Le vendredi est suivi du lundi, plutôt que du samedi.

  • Outre les barres du dimanche, certains centres de négociation fournissent des cotations en continu, y compris pendant tout le week-end. L’activité des prix, bien qu’assez faible par rapport aux jours de semaine, est présente tout au long du week-end.

  • Différence de fuseaux horaires entre le serveur de trading et un ordinateur local (ordinateur du trader et terminal de trading). Le temps de serveur des différents centres de négociation peut varier.

  • L’heure avancée.

L’article commencera par une théorie générale concernant le temps. Ensuite, nous passerons en revue les fonctions MQL5 standard pour travailler avec le temps et examinerons simultanément certaines techniques de programmation, en les complétant par la gestion des problèmes pratiques.

L’article est sorti très longtemps, donc les programmeurs novices qui n’ont commencé que récemment à explorer MQL5 ne réussiront guère tout cela en une seule fois. Il serait préférable de le consacrer au moins trois jours.


Particularités de la mesure du temps

Faisons une digression du sujet pendant un petit moment et tournons-nous vers l’astronomie. C’est un fait connu que la Terre tourne autour du Soleil, tout en tournant sur son axe. L’axe de la Terre est légèrement incliné par rapport à son orbite autour du Soleil. Le temps nécessaire pour une rotation complète de la Terre sur son axe en coordonnées astronomiques (célestes, globales) est appelé jour astronomique ou sidéral.

Le jour sidéral n’intéresse pas les gens ordinaires sur Terre (contrairement aux astronomes). Plus important est l’alternance du jour et de la nuit. Le temps nécessaire pour un cycle jour-nuit est appelé jour solaire. En regardant le système solaire au-dessus du pôle Nord de la Terre (Fig. 3), vous pourrez voir que la Terre tourne sur son axe et tourne autour du Soleil dans le sens inverse des aiguilles d’une montre. Par conséquent, afin de faire une rotation complète sur son axe par rapport au Soleil, la Terre doit tourner un peu plus de 360 degrés. Par conséquent, une journée solaire est légèrement plus longue qu’une journée sidérale.

Fig. 3. Direction de la rotation de la Terre sur son axe et autour du Soleil (vue d’au-dessus du pôle Nord de la Terre).
Fig. 3. Direction de la rotation de la Terre sur son axe et autour du Soleil (vue d’au-dessus du pôle Nord de la Terre).

Pour plus de commodité et de précision, un jour solaire est pris comme base des mesures de temps. Une journée solaire est divisée en 24 parties faisant une heure qui dure 60 minutes, etc. Une journée sidérale dure 23 heures 56 minutes et 4 secondes. Une légère inclinaison de l’axe de la Terre par rapport à son plan orbital entraîne des changements de saisons perceptibles par les êtres vivants sur la Terre.

Le nombre de jours solaires dans une année n’est pas entier. En fait, c’est juste un peu plus - 365 jours et 6 heures. C’est pourquoi le calendrier est ajusté périodiquement, une fois tous les quatre ans (dans le multiple d’année de 4) en ajoutant un jour de plus, le 29 février (année bissextile). Cependant, cet ajustement n’est pas tout à fait précis (un peu de temps supplémentaire est ajouté), de sorte que certaines années, bien qu’étant multiples de 4, ne sont pas des années bissextiles. Aucun ajustement du calendrier n’a lieu dans les années se terminant par "00" (un multiple de 100). Mais ce n’est pas tout.

Si une année est un multiple de 100 et 400 en même temps, cette année est considérée comme une année bissextile et le calendrier doit être ajusté. L’année 1900 est un multiple de 4 et 100, mais n’est pas un multiple de 400, c’est pourquoi ce n’est pas une année bissextile. L’an 2000 est un multiple de 4, 100 et 400, ce qui en fait une année bissextile. L’année suivante, qui est un multiple de 4 et 100, est l’année 2100. Mais comme il ne s’agit pas d’un multiple de 400, ce ne sera pas une année bissextile. Il s’avère que les lecteurs de cet article partent à l’époque où chaque année qui est un multiple de 4 est une année bissextile. L’année suivante, c’est un multiple de 100 et en même temps une année bissextile est l’année 2400.


Fuseaux horaires

La Terre tourne sur son axe, ce qui entraîne l’alternance du jour et de la nuit. Il peut être le jour ou la nuit, ou plutôt, n’importe quel moment de la journée à la même heure dans différents endroits de la Terre. Comme un jour a 24 heures, la circonférence de la Terre est divisée en 24 sections de 15 degrés chacune appelées fuseaux horaires. Pour plus de commodité, les limites des fuseaux horaires ne suivent pas toujours les lignes de longitude, mais s’exécutent plutôt conformément aux limites de la division territoriale administrative: frontières des pays, des régions, etc.

Le point de référence est le méridien principal appelé méridien de Greenwich. Il traverse le quartier londonien de Greenwich d’où il tire son nom. Le temps moyen de Greenwich s’étend de 7,5 degrés de chaque côté du méridien de Greenwich. Il y a 12 fuseaux horaires mesurés à l’est de l’heure moyenne de Greenwich (de +1 à +12) et 12 fuseaux horaires mesurés à l’ouest de l’heure moyenne de Greenwich (de -1 à -12). En fait, les fuseaux horaires -12 et +12 ne font que 7,5 degrés de large au lieu de 15. Les fuseaux horaires -12 et +12 sont situés à droite et à gauche du méridien 180, appelé ligne de date internationale.

Supposons, quand il est midi à Greenwich (12h00), il est 00h00, c’est-à-dire le début de la journée au fuseau horaire -12 et - 24h00, c’est-à-dire 00h00 du lendemain au fuseau horaire +12. Il en va de même pour toute autre heure - alors que l’heure sur l’horloge est identique, les dates dans le calendrier sont différentes. Le fuseau horaire -12 n’est en fait pas utilisé et est remplacé par +12. Il en va de même pour le fuseau horaire -11 qui est remplacé par le fuseau horaire +13. Cela a probablement à voir avec les particularités des relations économiques: par exemple, l’État indépendant du Samoa situé dans le fuseau horaire +13 a de fortes relations économiques avec le Japon, de sorte que le moment qui est plus proche de l’heure du Japon est considéré comme plus pratique.

En outre, il existe des fuseaux horaires inhabituels comme -04h30, +05h45, etc. Les curieux peuvent trouver la liste de tous les fuseaux horaires disponibles dans les paramètres d’heure Windows.


L’heure avancée

De nombreux pays du monde avancent leur horloge d’une heure en tant que pratique de l’heure avancée dans le but d’une exploitation plus efficace de la lumière du jour et des économies d’énergie. Environ 80 pays du monde observent l’heure avancée, tandis que d’autres ne le font pas. Certains pays qui utilisent l’heure avancée à grande échelle ont des parties de celle-ci qui se retirent de la pratique (y compris les États-Unis). L’heure avancée est observée dans les principaux pays et régions économiquement développés: presque tous les pays européens (y compris l’Allemagne, le Royaume-Uni, la Suisse), les États-Unis (New York, Chicago), l’Australie (Sydney) et la Nouvelle-Zélande (Wellington). Le Japon ne respecte pas l’heure avancée. Le 27 mars 2011, la Russie a décalé ses horloges d’une heure pour la dernière fois et n’est jamais revenue à l’heure normale en octobre. Depuis lors, la Russie a été officiellement hors de la pratique de l’heure avancée.

La procédure de passage à l’heure avancée varie d’un pays à l’autre. Aux États-Unis, le changement se produit à 02h00 heure locale le deuxième dimanche de mars et l’horloge saute en arrière à 02h00 le premier dimanche de novembre. En Europe, les horloges passent à l’heure avancée à 02h00 le dernier dimanche de mars et reviennent à l’heure normale à 03h00 le dernier dimanche d’octobre. Au lieu d’être réglé à l’heure locale, le décalage se produit d’un seul coup dans tous les pays européens : quand il est 02h00 à Londres, 03h00 à Berlin, etc., selon les fuseaux horaires. Les horloges sautent en arrière à l’heure normale quand il est 03h00 à Londres, 04h00 à Berlin, etc.

L’Australie et la Nouvelle-Zélande sont situées dans l’hémisphère sud où l’été commence lorsque l’hiver arrive dans l’hémisphère nord. Par conséquent, l’Australie change d’heure pour l’heure avancée le premier dimanche d’octobre et revenir à l’heure normale le premier dimanche d’avril. Il est difficile d’être plus précis en ce qui concerne l’heure avancée en Australie, car les dates de début et de fin ne conviennent pas toujours dans différentes parties du pays. En Nouvelle-Zélande, le passage à l’heure avancée a lieu à 02h00 le dernier dimanche de septembre et saute en arrière à 03h00 le premier dimanche d’avril.


Norme de temps

Comme mentionné précédemment, un jour solaire est pris comme base des mesures de temps et l’heure moyenne de Greenwich est prise comme norme de temps sur la base de laquelle l’heure est déterminée dans tous les autres fuseaux horaires. L’heure moyenne de Greenwich est souvent abrégée en GMT.

Cependant, depuis qu’il a été établi que la rotation de la Terre est légèrement non uniforme, une horloge atomique a été utilisée pour mesurer le temps et UTC (temps universel coordonné) est devenu la nouvelle norme de temps. Actuellement, UTC sert de norme d’heure principale pour le monde entier sous-jacente aux mesures de l’heure dans tous les fuseaux horaires, avec les ajustements nécessaires effectués pour l’heure avancée. UTC n’est pas soumis à l’heure avancée.

En raison du fait que GMT basé sur l’énergie solaire n’est pas complètement conforme à UTC qui est basé sur des horloges atomiques, il y a une différence entre UTC et GMT qui s’accumule jusqu’à environ 1 seconde tous les 500 jours. À cet égard, un ajustement d’une seconde est effectué de temps à autre le 30 juin ou le 31 décembre.


Formats de date et d’heure

Les formats de date varient d’un pays à l’autre. En Russie, par exemple, il est d’usage d’écrire d’abord le jour, suivi du mois et de l’année. Les nombres dans les dates sont séparés par des points, par exemple du 01.12.2012 au 1er décembre 2012. Aux États-Unis, le format de date est mois/jour/année, où les nombres dans les dates sont séparés par une barre oblique "/". En plus des points et des barres obliques "/", certaines normes de format peuvent utiliser un tiret "-" pour séparer les nombres dans une date. Lors de l’affichage du temps, les heures, les minutes et les secondes sont séparées par un signe de deux-points ":", par exemple 12:15:30 - 12 heures, 15 minutes, 30 secondes.

Il existe un moyen simple de spécifier le format de date et d’heure. Par exemple, "jj.mm.aaaa" signifie que nous écrivons d’abord le jour (le jour du mois composé de deux chiffres; si le jour est un nombre de 1 à 9, nous ajoutons 0 au début), puis le mois (doit être composé de deux chiffres) et l’année composée de quatre chiffres. "j-m-aa" signifie que le jour (il peut s’agir d’un nombre à un chiffre) va en premier, suivi du mois (un nombre à un chiffre est autorisé) et de l’année composée de deux chiffres, par exemple 1/12/12 - 1er décembre 2012. Les valeurs du jour, du mois et de l’année sont séparées par un tiret "-" .

L’heure est séparée de la date à l’aide d’un espace. Le format de l’heure utilise "h" pour les heures, "m" pour les minutes et "s" pour les secondes, tout en spécifiant le nombre de chiffres requis. Par exemple, « hh:mi:ss » signifie que nous écrivons d’abord des heures (0 doit être ajouté devant les valeurs de 1 à 9), puis des minutes (2 chiffres nécessaires) et des secondes (2 chiffres), où les valeurs des heures, des minutes et des secondes sont séparées par un deux-points.

Le format de date et d’heure considéré comme le plus précis du point de vue d’un programmeur est "aaaa.mm.jj hh:mi:ss". Lors du tri des chaînes de caractères avec des dates écrites à l’aide de cette notation, elles sont facilement organisées dans l’ordre chronologique. Supposons que vous stockiez des informations dans des fichiers texte tous les jours et que vous les conserviez dans le même dossier. Si vous nommez vos fichiers en utilisant ce format, les fichiers du dossier seront facilement triés et organisés dans l’ordre.

Maintenant que nous en avons fini avec la partie théorique, passons à la mise en œuvre.


Temps en MQL5

Dans MQL5, le temps est mesuré en secondes écoulées depuis le début de l’époque dite Unix qui a commencé le 1er janvier 1970. Pour stocker l’heure, nous utilisons des variables du type de datetime. La valeur minimale d’une variable de type datetime est 0 (correspondant à la date de début de l’époque), tandis que la valeur maximale est 32 535 244 799 (correspondant à 23:59:59 le 31 décembre 3000).


Détermination de l’heure actuelle du serveur

Pour déterminer l’heure actuelle, nous utilisons la fonction TimeCurrent(). Il renvoie la dernière heure de serveur connue :

datetime tm=TimeCurrent();
//--- output result
Alert(tm);

La même heure de serveur est utilisée pour spécifier l’heure des barres dans le graphique. La dernière heure de serveur connue est l’heure de la dernière modification du prix de l’un des symboles ouverts dans la fenêtre Market Watch. S’il n’y a que de l’EURUSD dans la fenêtre Market Watch, la fonction TimeCurrent() renvoie la dernière modification de prix de l’EURUSD. Étant donné que la fenêtre Market Watch, en règle générale, affiche un nombre considérable de symboles, la fonction renvoie essentiellement l’heure actuelle du serveur. Cependant, comme les prix ne changent pas le week-end, la valeur renvoyée par la fonction sera très différente de l’heure réelle du serveur.

Si vous avez besoin de connaître l’heure du serveur par un certain symbole (heure du dernier changement de prix), vous pouvez utiliser la fonction SymbolInfoInteger() avec les SYMBOL_TIME identifiant :

datetime tm=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
//--- output result
Alert(tm);


Détermination de l’heure locale actuelle

L’heure locale (affichée par l’horloge PC de l’utilisateur) est déterminée par la fonction TimeLocal() :

datetime tm=TimeLocal();
//--- output result
Alert(tm);

En pratique, lors de la programmation des CA et des indicateurs, vous pouvez principalement utiliser le temps du serveur. L’heure locale est pratique dans les alertes et les entrées de journal: il est plus pratique pour un utilisateur de comparer un message ou un horodatage d’entrée avec l’heure affichée par l’horloge du PC pour voir depuis combien de temps ce message ou cette entrée a été enregistré. Cependant, le terminal MetaTrader 5 ajoute automatiquement un horodatage aux messages et aux entrées de journal qui sont générés à l’aide des fonctions Alert() et Print(). Par conséquent, la nécessité d’utiliser la fonction TimeLocal() peut ne se poser que très rarement.


Sortie de temps

Veuillez noter que la valeur de la variable tm dans le code ci-dessus est générée à l’aide de la fonction Alert(). Cela dit, la valeur est affichée dans un format facile à lire, par exemple : "2012.12.05 22:31:57". Cela est dû au fait que la fonction Alert() convertit les arguments qui lui sont transmis en type String (il en va de même lors de l’utilisation des fonctions Print() et Comment() et lors de la sortie vers des fichiers texte et csv). Lors de la génération d’un message texte contenant la valeur d’une variable de type datetime, il est de votre responsabilité d’effectuer la conversion de type. Convertissez vers le type string (chaîne de caractères) si vous devez obtenir l'heure formatée ou vers les types long suivis du type string si vous avez besoin d'une valeur numérique :

datetime tm=TimeCurrent();
//--- output result
Alert("Formatted: "+(string)tm+", in seconds: "+(string)(long)tm);

Étant donné que les plages de valeurs des variables de type long et ulong couvrent la plage de valeurs de la variable de type datetime, elles peuvent également être utilisées pour stocker l’heure, mais dans ce cas, pour générer l’heure formatée, vous devez convertir le type long en type datetime, puis en type string ou en type string seul si vous souhaitez générer une valeur numérique:

long tm=TimeCurrent();
//--- output result
Alert("Formatted: "+(string)(datetime)tm+", in seconds: "+(string)tm);


Formatage de l’heure

Le formatage de l'heure a été examiné dans l'article intitulé "Bases de la programmation MQL5 : Strings" dans la section consacrée à la conversion de diverses variables en chaîne de caractères (string). Décrivons brièvement les points clés ici. En plus de convertir les types, MQL5 offre une fonction qui vous permet de spécifier le format de date et d’heure lors de leur conversion en chaîne de caractère (string) - la fonction TimeToString() :

datetime tm=TimeCurrent();
string str1="Date and time with minutes: "+TimeToString(tm);
string str2="Date only: "+TimeToString(tm,TIME_DATE);
string str3="Time with minutes only: "+TimeToString(tm,TIME_MINUTES);
string str4="Time with seconds only: "+TimeToString(tm,TIME_SECONDS);
string str5="Date and time with seconds: "+TimeToString(tm,TIME_DATE|TIME_SECONDS);
//--- output results
Alert(str1);
Alert(str2);
Alert(str3);
Alert(str4);
Alert(str5);

La fonction TimeToString() peut être appliquée aux variables du type datetime, ainsi qu’aux variables de type long et ulong et à d’autres types de variables entières, mais elles ne doivent pas être utilisées pour stocker le temps.

Lors de la mise en forme d’un message texte à l’aide de la fonction StringFormat(), vous devez vous occuper de la conversion de type.

  • Lors du stockage de l’heure dans une variable de type datetime :

    datetime tm=TimeCurrent();
    //--- generating a string
    string str=StringFormat("Formatted: %s, in seconds: %I64i",(string)tm,tm);
    //--- output result
    Alert(str);
  • Lors du stockage du temps dans une variable de type long :

    long tm=TimeCurrent();
    //--- generating a string
    string str=StringFormat("Formatted: %s, in seconds: %I64i",(string)(datetime)tm,tm);
    //--- output result
    Alert(str);
  • Ou en utilisant la fonction TimeToString() :

    datetime tm=TimeCurrent();
    //--- generating a string
    string str=StringFormat("Date: %s",TimeToString(tm,TIME_DATE));
    //--- output result
    Alert(str);


Conversion du temps en nombres. Ajout et soustraction du temps

Pour convertir une date mise en forme (string) en nombre (nombre de secondes écoulées depuis le début de l’époque), la fonction StringToTime() est utilisée :

datetime tm=StringToTime("2012.12.05 22:31:57");
//--- output result
Alert((string)(long)tm);

À la suite du code ci-dessus, le temps de sortie en secondes sera « 1354746717 » correspondant à la date suivante « 2012.12.05 22:31:57 ».

Lorsque l’heure est représentée sous forme de nombre, diverses opérations deviennent faciles et pratiques, par exemple vous pouvez trouver la date et l’heure dans le passé ou dans le futur. Étant donné que le temps est mesuré en secondes, vous devez ajouter une période de temps exprimée en secondes. Sachant qu’une minute est de 60 secondes et qu’une heure est de 60 minutes ou 3600 secondes, il ne faudra pas beaucoup d’efforts pour calculer la durée d’une période de temps.

Soustrayez ou ajoutez une heure (3600 secondes) de ou à l’heure actuelle et vous obtiendrez l’heure qui était il y a une heure ou sera dans une heure:

datetime tm=TimeCurrent();
datetime ltm=tm-3600;
datetime ftm=tm+3600;
//--- output result
Alert("Current: "+(string)tm+", an hour ago: "+(string)ltm+", in an hour: "+(string)ftm);

La date transmise à la fonction StringToTime() n’a pas besoin d’être complète. De plus, vous pouvez passer la date sans l’heure ou l’heure sans la date. Si vous passez la date sans l’heure, la fonction renvoie la valeur à 00:00:00 de la date spécifiée :

datetime tm=StringToTime("2012.12.05");
//--- output result
Alert(tm);

Si vous ne transmettez que l’heure, la fonction renvoie la valeur correspondant à l’heure spécifiée de la date actuelle :

datetime tm=StringToTime("22:31:57");
//--- output result
Alert((string)tm);

Le temps peut également être passé sans secondes. Si vous passez la date, le seul composant de temps qui peut être passé est heures. Cela ne sera presque jamais nécessaire dans la pratique. Cependant, si vous êtes curieux, n’hésitez pas à l’expérimenter par vous-même.


Composants de date et d’heure

Pour déterminer les valeurs des différents composants de la date et de l'heure (année, mois, date, etc.), nous utilisons la fonction TimeToStruct() et la MqlDateTime. La structure est transmise à la fonction par référence. Après l’exécution de la fonction, la structure sera remplie avec les valeurs des composants de la date qui lui a été transmise :

datetime    tm=TimeCurrent();
MqlDateTime stm;
TimeToStruct(tm,stm);
//--- output date components
Alert("Year: "        +(string)stm.year);
Alert("Month: "      +(string)stm.mon);
Alert("Day: "      +(string)stm.day);
Alert("Hour: "        +(string)stm.hour);
Alert("Minute: "     +(string)stm.min);
Alert("Second: "    +(string)stm.sec);
Alert("Day of the week: "+(string)stm.day_of_week);
Alert("Day of the year: "  +(string)stm.day_of_year);

Notez qu’en plus des composants de date, la structure contient également quelques champs supplémentaires: jour de la semaine (le champ day_of_week) et jour de l’année (day_of_year). Les jours de la semaine sont comptés à partir de 0 (0 - dimanche, 1 - lundi, etc.). Les jours de l’année sont également comptés à partir de zéro. Les autres valeurs suivent l’ordre de comptage généralement accepté (les mois sont comptés à partir de 1, ainsi que les jours).

Il existe une autre façon d’appeler la fonction TimeCurrent(). Une structure du type MqlDateTime est transmise à la fonction par référence. Après l’exécution de la fonction, la structure sera remplie avec les composants de date actuels:

MqlDateTime stm;
datetime tm=TimeCurrent(stm);
//--- output date components
Alert("Year: "        +(string)stm.year);
Alert("Month: "      +(string)stm.mon);
Alert("Day: "      +(string)stm.day);
Alert("Hour: "        +(string)stm.hour);
Alert("Minute: "     +(string)stm.min);
Alert("Second: "    +(string)stm.sec);
Alert("Day of the week: "+(string)stm.day_of_week);
Alert("Day of the year: "  +(string)stm.day_of_year);

La fonction fonction TimeLocal() peut également être appelée de cette manière.


Date de génération à partir de ses composants

Vous pouvez également inverser la transformation de la structure MqlDateTime en type datetime. À cette fin, nous utilisons la fonction StructToTime().

Déterminons l’époque qui était il y a exactement un mois. Le nombre de jours dans un mois varie. Il y a des mois qui ont 30 ou 31 jours et février peut être de 28 ou 29 jours. La méthode de soustraction et d’addition temporelle que nous avons considérée plus tôt n’est donc pas tout à fait appropriée. Nous allons donc décomposer les dates en leurs composantes, diminuer la valeur du mois de 1 et si la valeur du mois est 1, nous la définirons sur 12 et diminuerons la valeur de l’année de 1:

datetime tm=TimeCurrent();
MqlDateTime stm;
TimeToStruct(tm,stm);
if(stm.mon==1)
  {
   stm.mon=12;
   stm.year--;
  }
else
  {
   stm.mon--;
  }
datetime ltm=StructToTime(stm);
//--- output result
Alert("Current: "+(string)tm+", a month ago: "+(string)ltm);


Détermination de l’heure de barre

Lors du développement d’un indicateur, MetaEditor crée automatiquement l’une des deux versions de la fonction OnCalculate().

Version 1:

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   return(rates_total);
  }

Version 2:

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   return(rates_total);
  }

Les paramètres de la première version de la fonction incluent le tableau time[] dont les éléments contiennent l’heure de toutes les barres.

Lors de l’utilisation de la deuxième version, ainsi qu’à tout moment lors de la programmation des EAs et de l’organisation de l’accès des indicateurs à l’heure des barres sur d’autres cadres temporels, nous utilisons la fonction CopyTime(). Cette fonction existe en trois versions. Dans toutes les versions, les deux premiers paramètres de fonction définissent le symbole et le cadre temporel du graphique sur laquelle l’heure de la barre est déterminée. Le dernier paramètre définit un tableau qui stocke les valeurs renvoyées et les deux paramètres intermédiaires dépendent de la version de fonction utilisée.

CopyTime - Version 1. Vous devez spécifier l’index de la barre et le nombre d’éléments à copier :

//--- variables for function parameters
int start = 0; // bar index
int count = 1; // number of bars
datetime tm[]; // array storing the returned bar time
//--- copy time 
CopyTime(_Symbol,PERIOD_D1,start,count,tm);
//--- output result
Alert(tm[0]);

Cet exemple illustre l’implémentation de la copie de l’heure de la dernière barre sur le cadre temporel D1. La version de la fonction que nous utilisons dépend du type de paramètres qui lui sont transmis. L’exemple ci-dessus présente l’utilisation des variables de type int, ce qui signifie que nous devons obtenir l’heure par le numéro de barre pour le nombre spécifié de barres.

Lorsque vous utilisez la fonction CopyTime(), les barres sont comptées de zéro de droite à gauche. Un tableau dynamique utilisé pour les valeurs obtenues (le dernier paramètre) est mis à l’échelle à la taille requise par la fonction CopyTime() elle-même. Vous pouvez également utiliser un tableau statique mais dans ce cas la taille du tableau doit correspondre strictement au nombre d’éléments demandés (la valeur du 4ème paramètre).

Il est important de comprendre l’ordre des éléments dans le tableau renvoyé lorsque le temps est obtenu à partir de plusieurs barres à la fois. Alors que les barres du graphique sont comptées de droite à gauche en commençant par la barre spécifiée, les éléments de tableau sont disposés de gauche à droite :

//--- variables for function parameters
int start = 0; // bar index
int count = 2; // number of bars
datetime tm[]; // array storing the returned bar time
//--- copy time 
CopyTime(_Symbol,PERIOD_D1,start,count,tm);
//--- output result
Alert("Today: "+(string)tm[1]+", yesterday: "+(string)tm[0]);

En raison de ce code, l’heure de la barre d’hier sera stockée dans l’élément 0 du tableau tm, tandis que le 1er élément contiendra l’heure de la barre d’aujourd’hui.

Dans certains cas, il peut sembler plus pratique d’avoir du temps dans le tableau organisé dans le même ordre que l’ordre des barres de comptage dans le graphique. Et ici, la fonction ArraySetAsSeries() peut faire l’affaire:

//--- variables for function parameters
int start = 0; // bar index
int count = 2; // number of bars
datetime tm[]; // array storing the returned bar time
ArraySetAsSeries(tm,true); // specify that the array will be arranged in reverse order
//--- copy time 
CopyTime(_Symbol,PERIOD_D1,start,count,tm);
//--- output result
Alert("Today: "+(string)tm[0]+", yesterday: "+(string)tm[1]);

Maintenant, l’heure de la barre d’aujourd’hui est dans l’élément avec l’indice 0 et l’heure de la barre d’hier est dans l’élément avec l’index 1.

CopyTime - Version 2. Ici, lors de l’appel de la fonction CopyTime(), nous devons spécifier l’heure de la barre à partir de laquelle la copie commence et le nombre de barres à copier. Cette version sera appropriée pour déterminer le temps d’un cadre temporel plus élevé qui contient une barre d’un cadre temporel inférieur :

//--- get the time of the last bar on M5
int m5_start=0; 
int m5_count=1;
datetime m5_tm[];
CopyTime(_Symbol,PERIOD_M5,m5_start,m5_count,m5_tm);
//--- determine the bar time on H1 that contains the bar on M5
int h1_count=1;
datetime h1_tm[];
CopyTime(_Symbol,PERIOD_H1,m5_tm[0],h1_count,h1_tm);
//--- output result
Alert("The bar on М5 with the time "+(string)m5_tm[0]+" is contained in the bar on H1 with the time "+(string)h1_tm[0]);

Cela devient plus compliqué si vous devez déterminer l’heure de la barre sur un cadre temporel inférieur, étant le début de la barre sur un cadre temporel plus long. Une barre avec la même heure que l’heure de la barre sur un cadre temporel plus long peut être manquante sur un cadre temporel inférieur. Dans un tel cas, nous obtiendrons l’heure de la dernière barre sur un cadre temporel inférieur qui est contenue dans la barre précédente du cadre temporel supérieur. Nous devons donc déterminer le numéro de la barre d’un cadre temporel inférieur et obtenir l’heure de la barre suivante.

Vous trouverez ci-dessous l’implémentation de ce qui précède sous la forme d’une fonction prête à être utilisée:

bool LowerTFFirstBarTime(string aSymbol,
                         ENUM_TIMEFRAMES aLowerTF,
                         datetime aUpperTFBarTime,
                         datetime& aLowerTFFirstBarTime)
  {
   datetime tm[];
//--- determine the bar time on a lower time frame corresponding to the bar time on a higher time frame 
   if(CopyTime(aSymbol,aLowerTF,aUpperTFBarTime,1,tm)==-1)
     {
      return(false);
     }
   if(tm[0]<aUpperTFBarTime)
     {
      //--- we got the time of the preceding bar
      datetime tm2[];
      //--- determine the time of the last bar on a lower time frame
      if(CopyTime(aSymbol,aLowerTF,0,1,tm2)==-1)
        {
         return(false);
        }
      if(tm[0]<tm2[0])
        {
         //--- there is a bar following the bar of a lower time frame  that precedes the occurrence of the bar on a higher time frame
         int start=Bars(aSymbol,aLowerTF,tm[0],tm2[0])-2;
         //--- the Bars() function returns the number of bars from the bar with time tm[0] to
         //--- the bar with time tm2[0]; since we need to determine the index of the bar following 
         //--- the bar with time tm2[2], subtract 2
         if(CopyTime(aSymbol,aLowerTF,start,1,tm)==-1)
           {
            return(false);
           }
        }
      else
        {
         //--- there is no bar of a lower time frame contained in the bar on a higher time frame
         aLowerTFFirstBarTime=0;
         return(true);
        }
     }
//--- assign the obtained value to the variable 
   aLowerTFFirstBarTime=tm[0];
   return(true);
  }

Les paramètres de fonction :

  • aSymbol - symbole ;
  • aLowerTF - un cadre temporel plus court ;
  • aUpperTFBarTime - barre de temps sur un cadre temporel plus long ;
  • aLowerTFFirstBarTime - valeur renvoyée d’un cadre temporel inférieur.

Tout au long du code, la fonction vérifie si l’appel de la fonction CopyTime() réussit et en cas d’erreur, la fonction renvoie false. L’heure de la barre est renvoyée par référence via le paramètre aLowerTFFirstBarTime.

Un exemple d’utilisation de la fonction est illustré ci-dessous :

//--- time of the bar on the higher time frame H1
   datetime utftm=StringToTime("2012.12.10 15:00");
//--- variable for the returned value
   datetime val;
//--- function call
   if(LowerTFFirstBarTime(_Symbol,PERIOD_M5,utftm,val))
     {
      //--- output result in case of successful function operation
      Alert("val = "+(string)val);
     }
   else
     {
      //--- in case of an error, terminate the operation of the function from which the LowerTFFirstBarTime() function is called
      Alert("Error copying the time");
      return;
     }

Une situation où il n’y a pas de barre sur un cadre temporel inférieur contenu dans une barre d’un cadre temporel plus élevé peut se produire si la fonction reçoit le temps d’une barre inexistante d’un cadre temporel plus élevé. Dans ce cas, la fonction renvoie true (vrai) et la valeur de temps de 0 est écrite dans la variable aLowerTFFirstBarTime. S’il existe une barre d’un cadre temporel plus élevé, il y aura toujours au moins une barre correspondante dans chacun des cadre temporels inférieurs.

Il est légèrement plus facile de trouver l'heure de la dernière barre d'un cadre temporel inférieur qui est contenue dans une barre d'un cadre temporel supérieur. Nous calculons l’heure de la barre suivante sur un cadre temporel plus élevé et utilisons la valeur obtenue pour déterminer l’heure de la barre correspondante sur un cadre temporel inférieur. Si le temps résultant est égal au temps calculé d’un laps de temps plus élevé, nous devons déterminer le temps de la barre précédente sur un cadre temporel inférieur. Si le temps résultant est inférieur, alors nous avons le bon moment.

Vous trouverez ci-dessous l’implémentation de ce qui précède sous la forme d’une fonction prête à être utilisée:

bool LowerTFLastBarTime(string aSymbol,
                        ENUM_TIMEFRAMES aUpperTF,
                        ENUM_TIMEFRAMES aLowerTF,
                        datetime aUpperTFBarTime,
                        datetime& aLowerTFFirstBarTime)
  {
//--- time of the next bar on a higher time frame
   datetime NextBarTime=aUpperTFBarTime+PeriodSeconds(aUpperTF);
   datetime tm[];
   if(CopyTime(aSymbol,aLowerTF,NextBarTime,1,tm)==-1)
     {
      return(false);
     }
   if(tm[0]==NextBarTime)
     {
      //--- There is a bar on a lower time frame corresponding to the time of the next bar on a higher time frame.
      //--- Determine the time of the last bar on a lower time frame
      datetime tm2[];
      if(CopyTime(aSymbol,aLowerTF,0,1,tm2)==-1)
        {
         return(false);
        }
      //--- determine the preceding bar index on a lower time frame
      int start=Bars(aSymbol,aLowerTF,tm[0],tm2[0]);
      //--- determine the time of this bar
      if(CopyTime(aSymbol,aLowerTF,start,1,tm)==-1)
        {
         return(false);
        }
     }
//--- assign the obtain value to the variable 
   aLowerTFFirstBarTime=tm[0];
   return(true);
  }

Les paramètres de fonction :

  • aSymbol - symbole ;
  • aUpperTF - cadre temporel plus élevé ;
  • aLowerTF - cadre temporel plus court ;
  • aUpperTFBarTime - barre de temps sur un cadre temporel plus long ;
  • aLowerTFFirstBarTime - valeur renvoyée d’un cadre temporel inférieur.

Tout au long du code, la fonction vérifie si l’appel de la fonction CopyTime() réussit et en cas d’erreur, la fonction renvoie false. L’heure de la barre est renvoyée par référence via le paramètre aLowerTFFirstBarTime.

Un exemple d’utilisation de la fonction est illustré ci-dessous :

//--- time of the bar on the higher time frame H1
datetime utftm=StringToTime("2012.12.10 15:00");
//--- variable for the returned value
datetime val;
//--- function call
if(LowerTFLastBarTime(_Symbol,PERIOD_H1,PERIOD_M5,utftm,val))
  {
//--- output result in case of successful function operation
   Alert("val = "+(string)val);
  }
else
  {
//--- in case of an error, terminate the operation of the function from which the LowerTFFirstBarTime() function is called
   Alert("Error copying the time");
   return;
  }

Attention ! On suppose que le temps passé à la fonction est le temps exact d’un cadre temporel plus élevé. Si l’heure exacte de la barre est inconnue et que nous ne connaissons que l’heure d’une certaine coche sur cette barre ou d’une barre sur un cadre temporel inférieur contenue dans la barre sur un cadre temporel plus long, une normalisation du temps sera nécessaire. Les cadres temporels utilisés dans le terminal MetaTrader 5 décomposent la journée en un nombre intégral de barres. Nous déterminons le nombre de barres depuis le début de l’époque et le multiplions par la longueur de la barre en secondes:

datetime BarTimeNormalize(datetime aTime,ENUM_TIMEFRAMES aTimeFrame)
  {
   int BarLength=PeriodSeconds(aTimeFrame);
   return(BarLength*(aTime/BarLength));
  }

Les paramètres de fonction :

  • aTime - temps ;
  • aTimeFrame - cadre temporel.

Un exemple d’utilisation de la fonction est illustré ci-dessous :

//--- the time to be normalized
datetime tm=StringToTime("2012.12.10 15:25");
//--- function call
datetime tm1=BarTimeNormalize(tm,PERIOD_H1);
//--- output result
Alert(tm1);

Cependant, il ne s’agit pas seulement de la méthode de normalisation du temps, mais aussi d’une autre méthode pour déterminer le temps d’un cadre temporel plus élevé par le temps d’un cadre temporel inférieur.

CopyTime - Version 3. Dans ce cas, lors de l’appel de la fonction CopyTime(), nous spécifions la plage de temps par rapport aux barres à partir de laquelle l’heure doit être copiée. Cette méthode nous permet d’obtenir facilement toutes les barres d’un cadre temporel inférieur contenues dans la barre d’un cadre temporel plus élevé :

//--- time of the bar start on H1
datetime TimeStart=StringToTime("2012.12.10 15:00");
//--- the estimated time of the last bar on
//--- M5
datetime TimeStop=TimeStart+PeriodSeconds(PERIOD_H1)-PeriodSeconds(PERIOD_M5);
//--- copy time
datetime tm[];
CopyTime(_Symbol,PERIOD_M5,TimeStart,TimeStop,tm);
//--- output result 
Alert("Bars copied: "+(string)ArraySize(tm)+", first bar: "+(string)tm[0]+", last bar: "+(string)tm[ArraySize(tm)-1]);


Détermination de l’heure de début du jour et de la quantité de temps écoulé depuis le début du jour

Le moyen le plus évident de déterminer l’heure de début de la journée à une heure donnée est de décomposer le temps en ses composants, de réduire à zéro les heures, les minutes et les secondes et de les additionner à nouveau. Cependant, il existe un moyen plus simple. Un jour, c’est 86400 secondes. Nous devons obtenir un entier à la suite de la division du temps par le nombre de secondes en une journée et le multiplier par le nombre de secondes en une journée:

datetime tm=TimeCurrent();
tm=(tm/86400)*86400;
//--- output result
Alert("Day start time: "+(string)tm);

Attention ! Cette astuce n’est efficace qu’avec des variables entières. Si des variables de type double et float apparaissent dans l’un de vos calculs, vous devez tronquer la partie fractionnaire à l’aide de la fonction MathFloor() :

MathFloor(tm/86400)*86400

Après la multiplication, les valeurs doivent être normalisées à l’aide de la fonction NormalizeDouble() . Puisque la valeur résultante doit être un entier, vous pouvez utiliser une fonction d’arrondi, MathRound() :

MathRound(MathFloor(tm/86400)*86400)

Lorsque vous utilisez des variables entières, le reste est automatiquement supprimé. Dans la gestion du temps, il n’y aura guère besoin de variables de type double ou float et leur utilisation indiquera très probablement une approche fondamentalement erronée.

Pour déterminer le nombre de secondes écoulées depuis le début de la journée, il suffit de prendre le reste de la division du temps par 86400:

datetime tm=TimeCurrent();
long seconds=tm%86400;
//--- output result
Alert("Time elapsed since the day start: "+(string)seconds+" sec.");

Des méthodes similaires peuvent être utilisées pour convertir le temps obtenu en secondes en heures, minutes et secondes. Mise en œuvre en tant que fonction :

int TimeFromDayStart(datetime aTime,int &aH,int &aM,int &aS)
  {
//--- Number of seconds elapsed since the day start (aTime%86400),
//--- divided by the number of seconds in an hour is the number of hours
   aH=(int)((aTime%86400)/3600);
//--- Number of seconds elapsed since the last hour (aTime%3600),
//--- divided by the number of seconds in a minute is the number of minutes 
   aM=(int)((aTime%3600)/60);
//--- Number of seconds elapsed since the last minute 
   aS=(int)(aTime%60);
//--- Number of seconds since the day start
   return(int(aTime%86400));
  }

Le premier paramètre passé est le temps. D’autres paramètres sont utilisés pour les valeurs renvoyées : aH - heures, aM - minutes, aS - secondes. La fonction elle-même renvoie le nombre total de secondes depuis le début de la journée. Vérifions la fonction :

datetime tm=TimeCurrent();
int t,h,m,s;
t=TimeFromDayStart(tm,h,m,s);
//--- output result
Alert("Time elapsed since the day start ",t," s, which makes ",h," h, ",m," m, ",s," s ");

Vous pouvez également calculer le nombre de jours à utiliser dans les indicateurs pour déterminer la barre du début de la journée :

bool NewDay=(time[i]/86400)!=(time[i-1]/86400);

On suppose que les barres sont indexées de gauche à droite, où time[i] est l’heure de la barre actuelle et time[i-1] est l’heure de la barre précédente.


Détermination de l’heure de début de la semaine et de la quantité de temps écoulé depuis le début de la semaine

Déterminer l’heure de début de la semaine est un peu plus complexe que de déterminer le début de la journée. Bien que le nombre de jours dans une semaine soit constant et que nous puissions calculer la durée d’une semaine en secondes (604800 secondes), il ne suffit pas de simplement calculer le nombre intégral de semaines qui se sont écoulées depuis le début de l’époque et de le multiplier par la durée de la semaine.

Le fait est que dans la majorité des pays, la semaine commence le lundi, tandis que dans d’autres pays (États-Unis, Canada, Israël et autres), elle commence le dimanche. Mais comme nous nous en souvenons, l’époque de la mesure du temps commence jeudi. Si le jeudi avait été le premier jour de la semaine, ces simples calculs auraient suffi.

Pour plus de commodité, nous examinerons les particularités de la détermination du début de la semaine à travers l’exemple du premier jour d’époque correspondant à la valeur de 0. Nous devons trouver une telle valeur qui, ajoutée à l’heure, changerait le premier jour de l’époque (1970.01.01 00:00), compté de zéro, au quatrième jour, c’est-à-dire que nous devons ajouter la durée de quatre jours. Si la semaine commence le lundi, le jeudi devrait être le quatrième jour, nous devons donc ajouter la durée de trois jours. Si toutefois la semaine commence le dimanche, le jeudi devrait être le cinquième jour, nous devons donc ajouter la durée de quatre jours.

Écrivons une fonction pour le calcul du nombre d’une semaine :

long WeekNum(datetime aTime,bool aStartsOnMonday=false)
  {
//--- if the week starts on Sunday, add the duration of 4 days (Wednesday+Tuesday+Monday+Sunday),
//    if it starts on Monday, add 3 days (Wednesday, Tuesday, Monday)
   if(aStartsOnMonday)
     {
      aTime+=259200; // duration of three days (86400*3)
     }
   else
     {
      aTime+=345600; // duration of four days (86400*4)  
     }
   return(aTime/604800);
  }

Cette fonction peut être utile dans les indicateurs pour déterminer la première barre de la nouvelle semaine :

bool NewWeek=WeekNum(time[i])!=WeekNum(time[i-1]);

On suppose que les barres sont indexées de gauche à droite, où time[i] est l’heure de la barre actuelle et time[i-1] est l’heure de la barre précédente.

Maintenant, nous pouvons calculer l’heure du début de la semaine. Étant donné que pour calculer le nombre de la semaine, il a été supposé que l’époque commence trois (ou quatre) jours plus tôt, nous devons maintenant effectuer une correction de temps inverse:

long WeekStartTime(datetime aTime,bool aStartsOnMonday=false)
  {
   long tmp=aTime;
   long Corrector;
   if(aStartsOnMonday)
     {
      Corrector=259200; // duration of three days (86400*3)
     }
   else
     {
      Corrector=345600; // duration of four days (86400*4)
     }
   tmp+=Corrector;
   tmp=(tmp/604800)*604800;
   tmp-=Corrector;
   return(tmp);
  }  

La fonction renvoie une valeur de type long car la valeur de la toute première semaine peut être négative (trois à quatre jours avant le début de l’époque). Le deuxième paramètre de la fonction peut déterminer si la semaine commence le dimanche ou le lundi.

Maintenant que nous avons l’heure du début de la semaine, nous pouvons calculer le nombre de secondes qui se sont écoulées depuis le début de la semaine:

long SecondsFromWeekStart(datetime aTime,bool aStartsOnMonday=false)
  {
   return(aTime-WeekStartTime(aTime,aStartsOnMonday));
  }

Les secondes peuvent être converties en jours, heures, minutes et secondes. Bien qu’il n’ait pas été difficile de calculer les heures, les minutes et les secondes depuis le début de la journée, dans ce cas, il sera plus facile d’utiliser la fonction TimeToStruct() :

long sfws=SecondsFromWeekStart(TimeCurrent());
MqlDateTime stm;
TimeToStruct(sfws,stm);
stm.day--;
Alert("Time elapsed since the week start "+(string)stm.day+" d, "+(string)stm.hour+" h, "+(string)stm.min+" m, "+(string)stm.sec+" s");

Veuillez noter que la valeur stm.day est diminuée de 1. Les jours du mois sont comptés à partir de 1 car nous devons déterminer le nombre de jours entiers. Certains d’entre vous pourraient trouver les fonctions de cette section inutiles d’un point de vue pratique, mais votre compréhension de ces fonctions sera d’une grande valeur en tant qu’expérience de travail avec le temps.


Détermination du numéro de semaine depuis une date donnée, le début de l’année ou le début du mois

En regardant les champs de la structure MqlDateTime, en particulier le champ day_of_year, on a l’impression de créer des fonctions qui détermineront le nombre de la semaine depuis le début de l’année et le début du mois. Il est préférable d’écrire une fonction générale pour déterminer le nombre de la semaine depuis une date donnée. Le principe du fonctionnement de la fonction est similaire à celui utilisé pour déterminer le nombre de la semaine depuis le début de l’époque:

long WeekNumFromDate(datetime aTime,datetime aStartTime,bool aStartsOnMonday=false)
  {
   long Time,StartTime,Corrector;
   MqlDateTime stm;
   Time=aTime;
   StartTime=aStartTime;
//--- determine the beginning of the reference epoch
   StartTime=(StartTime/86400)*86400;
//--- determine the time that elapsed since the beginning of the reference epoch
   Time-=StartTime;
//--- determine the day of the week of the beginning of the reference epoch
   TimeToStruct(StartTime,stm);
//--- if the week starts on Monday, numbers of days of the week are decreased by 1,
//    and the day with number 0  becomes a day with number 6
   if(aStartsOnMonday)
     {
      if(stm.day_of_week==0)
        {
         stm.day_of_week=6;
        }
      else
        {
         stm.day_of_week--;
        }
     }
//--- calculate the value of the time corrector 
   Corrector=86400*stm.day_of_week;
//--- time correction
   Time+=Corrector;
//--- calculate and return the number of the week
   return(Time/604800);
  }

Sur la base de cette fonction, écrivons deux fonctions pour déterminer le nombre de la semaine depuis le début de l’année et depuis le début du mois. Pour ce faire, nous devons d’abord déterminer la période de début de l’année et la période de début du mois. Décomposez le temps en ses composants, ajustez les valeurs de certains champs et convertissez les composants en notation temporelle.

  • La fonction de détermination de l’heure de début de l’année :

    datetime YearStartTime(datetime aTime)
          {
           MqlDateTime stm;
           TimeToStruct(aTime,stm);
           stm.day=1;
           stm.mon=1;
           stm.hour=0;
           stm.min=0;
           stm.sec=0;
           return(StructToTime(stm));
          }
  • La fonction permettant de déterminer l’heure du début du mois :

    datetime MonthStartTime(datetime aTime)
          {
           MqlDateTime stm;
           TimeToStruct(aTime,stm);
           stm.day=1;
           stm.hour=0;
           stm.min=0;
           stm.sec=0;
           return(StructToTime(stm));
          }

Maintenant, voici les fonctions pour déterminer le nombre de la semaine depuis le début de l’année et le début du mois.

  • Depuis le début de l’année :

    long WeekNumYear(datetime aTime,bool aStartsOnMonday=false)
          {
           return(WeekNumFromDate(aTime,YearStartTime(aTime),aStartsOnMonday));
          }
  • Depuis le début du mois :

    long WeekNumMonth(datetime aTime,bool aStartsOnMonday=false)
          {
           return(WeekNumFromDate(aTime,MonthStartTime(aTime),aStartsOnMonday));
          }

Enfin, nous passons à des tâches purement pratiques.


Création d’un ensemble d’outils expérimentaux

Comme déjà mentionné, il existe des centres de négociation dont les cotations incluent les barres du dimanche et qui fournissent des cotations en continu tout au long du week-end. Nous devons nous assurer que les fonctions nécessaires fonctionnent correctement dans tous les cas. Nous pouvons bien sûr trouver les centres de négociation appropriés sur Internet et tester le fonctionnement des fonctions à l’aide de cotations sur des comptes de démonstration. Cependant, en plus de rechercher un bon centre de négociation, nous devrons rechercher des endroits appropriés dans le graphique pour exécuter les tests requis.

Créons notre propre zone de test pour tester les fonctions. Le vendredi, le week-end et le lundi sont d’un intérêt particulier. Nous allons créer un tableau contenant l’heure des barres du vendredi, du lundi et du week-end, selon les besoins. Il y aura un total de quatre options:

  1. Pas de barres le week-end.
  2. Certains barres à la fin du dimanche, disons, 4.
  3. Les cotations continues du week-end.
  4. Les barres du samedi mais pas de barres du dimanche.

Pour éviter que le réseau ne s’agrandisse, nous utiliserons le cadre temporel H1. La taille maximale du tableau sera de 96 éléments (24 barres par jour par 4 jours) et le tableau lui-même s’adaptera au graphique lorsqu’il sera dessiné à l’aide d’objets graphiques. Nous obtiendrons donc quelque chose comme un tampon d’indicateur avec le temps et itérons sur le tableau dans une boucle de la manière similaire à la première exécution de la fonction OnCalculate() lors du démarrage d’un indicateur. Ainsi, nous pourrons visualiser le fonctionnement de la fonction.

Cet outil est implémenté sous la forme d’un script joint à cet article (le fichier sTestArea.mq5). La préparation est effectuée dans la fonction OnStart() du script. La variable Variant au tout début du code de fonction vous permet de sélectionner l’une des quatre options répertoriées ci-dessus. Sous la fonction OnStart(), vous pouvez voir la fonction LikeOnCalculate() similaire à la fonction OnCalculate() des indicateurs. Cette fonction a deux paramètres : rates_total - nombre de barres et temps[] - tableau avec le temps des barres.

De plus, nous continuons à travailler dans cette fonction comme si nous écrivions un indicateur. Vous pouvez définir un marqueur à partir de la fonction en appelant la fonction SetMarker(). Les paramètres transmis à la fonction SetMarker() sont les suivants : index de barre, index de tampon (ligne où le marqueur est affiché) et couleur de marqueur.

La Fig. 4 montre les résultats des performances du script, la variable Variant étant égale à 2 et deux lignes de marqueurs étant définies sous chaque barre (les barres sont marquées avec des horodatages pertinents). Le jeu de couleurs de tous les éléments du graphique est invisible.

Fig. 4. Performances du script sTestArea.mq5.
Fig. 4. Performances du script sTestArea.mq5.

Les horodatages de barre prennent de la couleur en fonction du jour de la semaine : Vendredi - rouge, Samedi - magenta, Dimanche - vert, Lundi - bleu. Maintenant, nous pouvons procéder à l’écriture de diverses fonctions qui nécessitent une approche spéciale des barres de week-end, en étant en mesure de surveiller visuellement leur travail.


Indicateur pivot - Option 1

Essayons d’abord de créer un indicateur Pivot simple. Pour calculer la ligne pivot, nous devons connaître le cours de clôture d’hier, ainsi que les prix maximum et minimum d’hier. La valeur de l’indicateur est calculée comme la moyenne de ces trois valeurs. Nous identifierons les nouveaux hauts et bas au cours de la journée, calculerons la valeur pivot au début du nouveau jour et dessinerons et afficherons le niveau tout au long de la journée.

Nous fournirons deux versions de l’opération de l’indicateur :

  1. Le pivot est calculé chaque nouveau jour (on suppose qu’il n’y a pas de barres de week-end). S’il y a des barres du week-end, les barres du samedi et du dimanche seront traités différemment.
  2. Les barres du samedi appartiendront au vendredi, tandis que les barres du dimanche appartiendront au lundi (cela s’applique aux cas où les cotations sont fournis en continu tout au long du week-end et où il n’y a que des barres du dimanche). Ici, vous devez garder à l’esprit qu’il se peut qu’il n’y ait pas de barres le week-end.

Dans la première version, il suffit de déterminer uniquement le début de la nouvelle journée. Nous passons l’heure actuelle (aTimeCur) et l’heure précédente (aTimePre) à la fonction, calculons les nombres de jours depuis le début de l’époque et s’ils ne correspondent pas, nous en déduisons que le nouveau jour a commencé:

bool NewDay1(datetime aTimeCur,datetime aTimePre)
  {
   return((aTimeCur/86400)!=(aTimePre/86400));
  }

La deuxième version. Si le samedi a commencé, le début de la journée doit être ignoré. Si le dimanche a commencé, nous définissons le début de la journée (ce n’est naturellement qu’un autre jour). Si le lundi a commencé après le dimanche, sautez le début de la journée. Si le lundi a été précédé d’un autre jour de la semaine, par exemple le samedi ou le vendredi, définissez le jour de début. Ce que nous obtenons est une fonction comme suit:

bool NewDay2(datetime aTimeCur,datetime aTimePre)
  {
   MqlDateTime stm;
//--- new day
   if(NewDay1(aTimeCur,aTimePre))
     {
      TimeToStruct(aTimeCur,stm);
      switch(stm.day_of_week)
        {
         case 6: // Saturday
            return(false);
            break;
         case 0: // Sunday
            return(true);
            break;
         case 1: // Monday
            TimeToStruct(aTimePre,stm);
            if(stm.day_of_week!=0)
              { // preceded by any day of the week other than Sunday
               return(true);
              }
            else
              {
               return(false);
              }
            break;
         default: // any other day of the week
            return(true);
        }
     }
   return(false);
  }

Et voici la fonction générale en fonction de la version:

bool NewDay(datetime aTimeCur,datetime aTimePre,int aVariant=1)
  {
   switch(aVariant)
     {
      case 1:
         return(NewDay1(aTimeCur,aTimePre));
         break;
      case 2:
         return(NewDay2(aTimeCur,aTimePre));
         break;
     }
   return(false);
  }

Testons le fonctionnement de la fonction à l’aide de l’outil « sTestArea » (le fichier sTestArea_Pivot1.mq5 joint; le début de la journée est marqué en brun). Vous devrez exécuter huit tests : 2 versions de fonction pour quatre options de génération de barres. Après nous être assurés que les fonctions fonctionnent correctement, nous pouvons commencer à développer un indicateur en toute sécurité. Cependant, étant donné que le développement d’indicateurs n’est pas au centre de cet article, nous avons joint ici un indicateur prêt à l’emploi (le fichier Pivot1.mq5), la partie la plus difficile de son développement étant examinée en détail.


Détermination de la session de temps

Nous devons permettre à l’Expert Advisor de négocier dans la plage de temps spécifiée pendant la journée, tous les jours au même intervalle. Nous spécifions les heures et les minutes du début de la session de trading, ainsi que les heures et les minutes de la fin de la session de trading. Les heures et les minutes spécifiées séparément, plutôt que les variables de chaîne de caractère avec l’heure spécifiée comme "14:00" nous permettront d’effectuer des optimisations dans le testeur de stratégie (Strategy Tester) si la fonction est utilisée dans l’Expert Advisor.

Pour déterminer la session de temps, procédez comme suit :

  1. Calculez le temps en secondes depuis le début de la journée pour le point de départ et faites de même pour le point de fin.
  2. Calculez l’heure actuelle en secondes depuis le début de la journée.
  3. Comparez l’heure actuelle avec l’heure de début et l’heure de fin.

Il n’est pas impossible qu’une session de trading commence un jour et se termine un autre jour, c’est-à-dire lorsqu’une session de trading dépasse minuit, auquel cas l’heure de fin calculée depuis le début de la journée s’avère inférieure à l’heure de début. Par conséquent, nous devons faire deux vérifications. La fonction que nous obtenons est la suivante:

bool TimeSession(int aStartHour,int aStartMinute,int aStopHour,int aStopMinute,datetime aTimeCur)
  {
//--- session start time
   int StartTime=3600*aStartHour+60*aStartMinute;
//--- session end time
   int StopTime=3600*aStopHour+60*aStopMinute;
//--- current time in seconds since the day start
   aTimeCur=aTimeCur%86400;
   if(StopTime<StartTime)
     {
      //--- going past midnight
      if(aTimeCur>=StartTime || aTimeCur<StopTime)
        {
         return(true);
        }
     }
   else
     {
      //--- within one day
      if(aTimeCur>=StartTime && aTimeCur<StopTime)
        {
         return(true);
        }
     }
   return(false);
  }

Si la session dépasse minuit, l’heure actuelle doit être supérieure ou égale à l’heure de début de la session OU inférieure à l’heure de fin de la session. Si la session a lieu dans la journée, l’heure actuelle doit être supérieure ou égale à l’heure de début ET inférieure à l’heure de fin.

Un indicateur créé pour tester le fonctionnement de la fonction se trouve ci-joint à la fin de l’article (le fichier Session.mq5). Comme tout autre indicateur de l’application, il peut être utilisé non seulement pour les tests, mais aussi à d’autres fins pratiques.


Détermination d’un point de temps pendant la journée

Une simple vérification de l’égalité avec l’heure spécifiée ne fonctionnera pas correctement car les tiques ne se produisent pas à intervalles réguliers et il peut y avoir des retards de plusieurs secondes à plusieurs minutes. Il est très probable qu’il n’y aura tout simplement pas de coche avec le temps spécifié sur le marché. Nous devons vérifier l’intersection d’un horodatage donné.

L’heure actuelle doit être égale ou supérieure à l’heure spécifiée, tandis que l’heure précédente doit être inférieure à l’heure spécifiée. Comme il est nécessaire de déterminer un point de temps dans la journée, nous devons convertir l’heure actuelle (ainsi que l’heure précédente) en secondes depuis le début de la journée. De même, les paramètres de temps donnés (heures et minutes) doivent être convertis en secondes. Il se peut bien que l’heure précédente tombe la veille, c’est-à-dire qu’elle soit supérieure à l’heure actuelle, lorsqu’elle sera convertie en secondes depuis le début de la journée. Dans ce cas, nous procédons de la même manière que lors de la détermination de la session de temps - nous effectuons deux vérifications.

La fonction que nous obtenons est la suivante:

bool TimeCross(int aHour,int aMinute,datetime aTimeCur,datetime aTimePre)
  {
//--- specified time since the day start
   datetime PointTime=aHour*3600+aMinute*60;
//--- current time since the day start
   aTimeCur=aTimeCur%86400;
//--- previous time since the day start
   aTimePre=aTimePre%86400;
   if(aTimeCur<aTimePre)
     {
      //--- going past midnight
      if(aTimeCur>=PointTime || aTimePre<PointTime)
        {
         return(true);
        }
     }
   else
     {
      if(aTimeCur>=PointTime && aTimePre<PointTime)
        {
         return(true);
        }
     }
   return(false);
  }

Il existe un indicateur créé en fonction de cette fonction (le fichier TimePoint.mq5 joint à l’article).


Indicateur pivot - Option 2

Maintenant que nous avons appris comment déterminer un point dans le temps, nous allons affiner l'indicateur Pivot. Au lieu de 00h00 habituellement, la journée commencera maintenant à tout moment. Nous l’appellerons une journée définie par l’utilisateur. Pour déterminer le début d’une journée définie par l’utilisateur, nous utiliserons la fonction TimeCross() décrite précédemment. En raison des différentes options de génération de barres le week-end, certains jours devront être omis. Il est difficile de trouver toutes les règles de vérification à l’heure actuelle, alors nous allons le faire une étape à la fois. L’important est d’avoir quelque chose pour commencer et d’avoir des options sur la façon de procéder. Nous avons un script de test, sTestArea.mq5, afin que la bonne solution puisse même être trouvée expérimentalement.

Le cas "Pas de barres de week-end" est le plus simple : une nouvelle journée commence à l’intersection d’un horodatage donné par heure.

Dans le cas où il n’y a que quelques barres à la fin du dimanche, la fonction TimeCross() définira la première barre du dimanche comme le début du jour, compte tenu des paramètres de fonction. On suppose qu’il n’y a pas de cotations le week-end (les barres du dimanche appartiennent au lundi), donc le dimanche devrait être ignoré. Si une heure donnée tombe quelque part au milieu d’une série de barres du dimanche, elle doit également être ignorée car le nouveau début de la journée a déjà été enregistré le vendredi.

Les cotations continus du week-end : Si le début d’une journée définie par l’utilisateur tombe au milieu d’un jour calendaire (Fig. 5),

Fig. 5. Un jour défini par l’utilisateur commence au milieu d’un jour calendaire. Vendredi - rouge, Samedi - magenta, Dimanche - vert, Lundi - bleu.
Fig. 5. Un jour défini par l’utilisateur commence au milieu d’un jour calendaire.
Vendredi - rouge, Samedi - magenta, Dimanche - vert, Lundi - bleu.

la moitié du samedi peut être traitée comme le vendredi et la moitié du dimanche peut être traitée comme le lundi. Mais il y a quelques barres du milieu du samedi au milieu du dimanche qui n’ont leur place nulle part. Nous pourrions bien sûr diviser l’intervalle du samedi au dimanche en parties égales et traiter une moitié comme vendredi et l’autre moitié comme lundi. Cela compliquerait considérablement un indicateur très simple, même si les cotations du week-end ne sont pas si importants.

La solution la plus raisonnable sera de considérer tous les barres du samedi et du dimanche comme un jour défini par l’utilisateur qui dure du vendredi au lundi. Cela signifie que les jours définis par l’utilisateur qui commencent le samedi et le dimanche sont ignorés.

La fonction que nous obtenons est la suivante:

bool NewCustomDay(int aHour,int aMinute,datetime aTimeCur,datetime aTimePre)
  {
   MqlDateTime stm;
   if(TimeCross(aHour,aMinute,aTimeCur,aTimePre))
     {
      TimeToStruct(aTimeCur,stm);
      if(stm.day_of_week==0 || stm.day_of_week==6)
        {
         return(false);
        }
      else
        {
         return(true);
        }
     }
   return(false);
  }

Il existe un indicateur créé en fonction de cette fonction (le fichier Pivot2.mq5 joint à l’article).


Détermination des jours de trading de la semaine

Permettre à un Expert Advisor de trader uniquement certains jours est assez facile. Nous décomposons le temps en ses composants à l’aide de la fonction TimeToStruct() et déclarons des variables de type bool pour chacun des jours de la semaine dans les paramètres de l’Expert Advisor. Selon le jour de la semaine, la fonction renvoie la valeur de la variable correspondante.

Cela peut être fait d’une manière plus optimale. Lors de l’initialisation d’un Expert Advisor ou d’un indicateur, remplissez un tableau avec des valeurs de variables qui permettent ou non de trader certains jours. Vérifiez ensuite la valeur de l’élément de tableau correspondant au jour de la semaine. Nous obtenons deux fonctions: l’une est appelée lors de l’initialisation, tandis que l’autre est appelée selon les besoins.

Les variables :

input bool Sunday   =true; // Sunday
input bool Monday   =true; // Monday
input bool Tuesday  =true; // Tuesday 
input bool Wednesday=true; // Wednesday
input bool Thursday =true; // Thursday
input bool Friday   =true; // Friday
input bool Saturday =true; // Saturday

bool WeekDays[7];

La fonction d'initialisation :

void WeekDays_Init()
  {
   WeekDays[0]=Sunday;
   WeekDays[1]=Monday;
   WeekDays[2]=Tuesday;
   WeekDays[3]=Wednesday;
   WeekDays[4]=Thursday;
   WeekDays[5]=Friday;
   WeekDays[6]=Saturday;
  }

La fonction principale :

bool WeekDays_Check(datetime aTime)
  {
   MqlDateTime stm;
   TimeToStruct(aTime,stm);
   return(WeekDays[stm.day_of_week]);
  }

Un indicateur créé sur la base de cette fonction se trouve ci-joint à la fin de l’article (le fichier TradeWeekDays.mq5).


Détermination de l’heure de trading de la semaine

Nous devons déterminer les sessions de trading d’une heure donnée d’un jour de la semaine à une heure donnée d’un autre jour de la semaine. Cette fonction est similaire à la fonction TimeSession(), la seule différence étant que les calculs sont basés sur le temps écoulé depuis le début de la semaine. La fonction que nous obtenons est la suivante:

bool WeekSession(int aStartDay,int aStartHour,int aStartMinute,int aStopDay,int aStopHour,int aStopMinute,datetime aTimeCur)
  {
//--- session start time since the week start
   int StartTime=aStartDay*86400+3600*aStartHour+60*aStartMinute;
//--- session end time since the week start
   int StopTime=aStopDay*86400+3600*aStopHour+60*aStopMinute;
//--- current time in seconds since the week start
   long TimeCur=SecondsFromWeekStart(aTimeCur,false);
   if(StopTime<StartTime)
     {
      //--- passing the turn of the week
      if(TimeCur>=StartTime || TimeCur<StopTime)
        {
         return(true);
        }
     }
   else
     {
      //--- within one week
      if(TimeCur>=StartTime && TimeCur<StopTime)
        {
         return(true);
        }
     }
   return(false);
  }

Un indicateur créé sur la base de cette fonction se trouve ci-joint à la fin de l’article (le fichier SessionWeek.mq5).

Nous avons examiné pratiquement toutes les tâches les plus courantes liées au temps et examiné les techniques de programmation pertinentes et les fonctions MQL5 standard requises pour les résoudre.


Fonctions MQL5 supplémentaires

Il existe d’autres fonctions MQL5 pour travailler avec le temps : TimeTradeServer(), TimeGMT(), TimeDaylightSavings() et TimeGMTOffset(). La principale particularité de ces fonctions est qu’elles sont utilisées dans les paramètres d’horloge et d’heure du PC d’un utilisateur.

La fonction TimeTradeServer(). Il a été mentionné plus tôt dans l’article que la fonction TimeCurrent() affichera la mauvaise heure le week-end (l’heure du dernier changement de prix le vendredi). La fonction TimeTradeServer() calcule l’heure correcte du serveur :

datetime tm=TimeTradeServer();
//--- output result
Alert(tm);

La fonction TimeGMT(). La fonction calcule l’heure GMT en fonction des valeurs d’horloge et des paramètres d’heure de l’ordinateur d’un utilisateur: fuseau horaire et heure d’été :

datetime tm=TimeGMT();
//--- output result
Alert(tm);

Pour être plus précis, la fonction renvoie l’heure UTC.

La fonction TimeDaylightSavings(). La fonction renvoie la valeur de correction de l’heure avancée à partir des paramètres de l’ordinateur de l’utilisateur.

int val=TimeDaylightSavings();
//--- output result
Alert(val);

Pour obtenir l’heure sans la valeur de correction pour l’heure avancée, vous devez ajouter la valeur de correction à l’heure locale.

La fonction TimeGMTOffset(). La fonction vous permet d’obtenir le fuseau horaire de l’ordinateur d’un utilisateur. La valeur est renvoyée en secondes à ajouter à l’heure locale pour obtenir l’heure GMT.

int val=TimeGMTOffset();
//--- output result
Alert(val);

L’heure sur l’ordinateur d’un utilisateur sera TimeGMT()-TimeGMTOffset()-TimeDaylightSavings():

datetime tm1=TimeLocal();
datetime tm2=TimeGMT()-TimeGMTOffset()-TimeDaylightSavings();
//--- output result
Alert(tm1==tm2);


Quelques fonctions plus utiles pour gérer le temps

Fonction de détermination de l’année bissextile

bool LeapYear(datetime aTime)
  {
   MqlDateTime stm;
   TimeToStruct(aTime,stm);
//--- a multiple of 4 
   if(stm.year%4==0)
     {
      //--- a multiple of 100
      if(stm.year%100==0)
        {
         //--- a multiple of 400
         if(stm.year%400==0)
           {
            return(true);
           }
        }
      //--- not a multiple of 100 
      else
        {
         return(true);
        }
     }
   return(false);
  }

Le principe de détermination de l’année bissextile est décrit ci-dessus dans la section Particularités de la mesure du temps.

Fonction permettant de déterminer le nombre de jours dans un mois

int DaysInMonth(datetime aTime)
  {
   MqlDateTime stm;
   TimeToStruct(aTime,stm);
   if(stm.mon==2)
     {
      //--- February
      if(LeapYear(aTime))
        {
         //--- February in a leap year 
         return(29);
        }
      else
        {
         //--- February in a non-leap year 
         return(28);
        }
     }
   else
     {
      //--- other months
      return(31-((stm.mon-1)%7)%2);
     }
  }

La fonction vérifie si l’année est une année bissextile pour renvoyer la valeur appropriée de 28 ou 29 pour février et calcule le nombre de jours pour les autres mois. Le nombre de jours au cours des 7 premiers mois alterne comme suit: 31, 30, 31, 30, etc., ainsi que le nombre de jours des 5 mois restants. Par conséquent, la fonction calcule le reste de la division par 7. Ensuite, nous faisons le contrôle de parité impaire et la correction obtenue est soustraite de 31.


Particularités du fonctionnement de la fonction de temps dans le testeur de stratégie

Le testeur de stratégie génère son propre flux de guillemets et les valeurs de la fonction TimeCurrent() correspondent au flux de guillemets dans le testeur de stratégie. Les valeurs de la fonction TimeTradeServer() correspondent aux valeurs de TimeCurrent(). De même, les valeurs de la fonction TimeLocal() correspondent aux valeurs de TimeCurrent(). La fonction TimeCurrent() du testeur de stratégie ne prend pas en compte les fuseaux horaires et la correction de l’heure avancée. Le fonctionnement des Expert Advisors est basé sur les changements de prix, donc si votre Expert Advisor est nécessaire pour gérer le temps, utilisez la fonction TimeCurrent(). Cela vous permettra de tester en toute sécurité votre Expert Advisor dans le Strategy Tester.

Les fonctions TimeGMT(), TimeDaylightSavings() et TimeGMTOffset() fonctionnent exclusivement en fonction des paramètres actuels de l’ordinateur d’un utilisateur (les passages à l’heure avancée et retour ne sont pas simulés dans le testeur de stratégie). Si, lors du test d’un Expert Advisor, vous devez simuler des changements d’heure à l’heure avancée et de retour à l’heure normale (si cela est vraiment nécessaire), vous devez vous en occuper vous-même. Cela nécessitera des informations sur les dates et l’heure exactes pour changer l’horloge, ainsi qu’une analyse approfondie.

Une solution à ce problème dépasse de loin le cadre d’un seul article et n’est pas envisagée ici. Si un Expert Advisor travaille pendant les heures de session européennes ou américaines, tandis que le centre de négociation observe l’heure avancée, il n’y aura pas d’écart entre l’heure du serveur et l’heure de l’événement, contrairement à la session asiatique (le Japon n’observe pas l’heure avancée et l’Australie décale ses horloges à l’heure avancée en novembre).


Conclusion

L’article a couvert toutes les fonctions standard MQL5 pour travailler avec le temps. Il énonce les techniques de programmation utilisées lors de la gestion des tâches liées au temps. L’article a également démontré la création de plusieurs indicateurs et de quelques fonctions utiles, avec une description détaillée de leurs principes de fonctionnement.

Toutes les fonctions standard pour travailler avec le temps peuvent être classées en plusieurs catégories:

  1. TimeCurrent() et TimeLocal() sont les principales fonctions utilisées pour déterminer l’heure actuelle.
  2. TimeToString(), StringToTime(), TimeToStruct() et StructToTime() sont des fonctions de traitement du temps.
  3. CopyTime() est une fonction permettant d’obtenir l’heure de la barre.
  4. TimeTradeServer(), TimeGMT(), TimeDaylightSavings() et TimeGMTOffset() sont des fonctions qui dépendent des paramètres de l’ordinateur de l’utilisateur.


Fichiers joints

  • sTestArea.mq5 - un script pour tester des fonctions temporelles complexes.
  • sTestArea_Pivot1.mq5 - le script sTestArea.mq5 utilisé pour tester les fonctions de temps de l’indicateur Pivot1.mq5.
  • Pivot1.mq5 - un indicateur Pivot qui utilise des jours standard (la fonction NewDay).
  • Session.mq5 - indicateur de session de trading du jour (fonction TimeSession).
  • TimePoint.mq5 - un indicateur d’un point de temps donné (la fonction TimeCross).
  • Pivot2.mq5 - un indicateur Pivot qui utilise des jours définis par l’utilisateur (la fonction NewCustomDay).
  • TradeWeekDays.mq5 - un indicateur des jours de trading de la semaine (la fonction WeekDays_Check).
  • SessionWeek.mq5 - indicateur de session de trading de la semaine (la fonction WeekSession).
  • TimeFunctions.mqh - toutes les fonctions de temps fournies dans cet article, dans un seul fichier.

Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/599

Fichiers joints |
stestarea.mq5 (4.96 KB)
pivot1.mq5 (4.5 KB)
session.mq5 (3.51 KB)
timepoint.mq5 (3.32 KB)
pivot2.mq5 (4.14 KB)
tradeweekdays.mq5 (3.59 KB)
sessionweek.mq5 (5.08 KB)
timefuncions.mqh (20.52 KB)
Calcul des caractéristiques intégrales des émissions d’indicateurs Calcul des caractéristiques intégrales des émissions d’indicateurs
Les émissions d’indicateurs sont un domaine peu étudié des études de marché. Cela est principalement dû à la difficulté d’analyse causée par le traitement de très grands tableaux de données variant dans le temps. L’analyse graphique existante est trop gourmande en ressources et a donc déclenché le développement d’un algorithme parcimonieux qui utilise des séries chronologiques d’émissions. Cet article montre comment l’analyse visuelle (image intuitive) peut être remplacée par l’étude des caractéristiques intégrales des émissions. Il peut intéresser à la fois les traders et les développeurs de systèmes de trading automatisés.
Comment devenir un fournisseur de signaux pour MetaTrader 4 et MetaTrader 5 Comment devenir un fournisseur de signaux pour MetaTrader 4 et MetaTrader 5
Voulez-vous offrir vos signaux de trading et gagner de l’argent ? Inscrivez-vous sur le site MQL5.com en tant que vendeur, spécifiez votre compte de trading et proposez aux traders un abonnement pour copier vos transactions.
Informations générales sur les signaux de trading pour MetaTrader 4 et MetaTrader 5 Informations générales sur les signaux de trading pour MetaTrader 4 et MetaTrader 5
Les signaux de trading pour MetaTrader 4 et MetaTrader 5 est un service permettant aux traders de copier les opérations de trading d’un fournisseur de signaux. Notre objectif était de développer le nouveau service massivement utilisé en protégeant les abonnés et en les soulageant des coûts inutiles.
Comment tester un robot de trading avant d’acheter Comment tester un robot de trading avant d’acheter
L’achat d’un robot de trading sur MQL5 Market présente un avantage distinct par rapport à toutes les autres options similaires - un système automatisé proposé peut être testé en profondeur directement dans le terminal MetaTrader 5. Avant d’acheter, un Expert Advisor peut et doit être exécuté avec soin dans tous les modes défavorables du Strategy Tester intégré pour avoir une compréhension complète du système.