lundi 27 janvier 2014

Le nombre et le numéro de secondes dans les périodes (bars) avec MQL4


Nous allons utiliser les techniques arithmétiques de code vues dans la première partie de ce sujet pour réaliser des fonctions supplémentaires de calculs temporels, à placer dans le fichier include d'arithmétique temporelle que nous avons créé. Ces fonctions seront très simple pour les premières.

La fonction Period():


On commence par utiliser une fonction prédéfinie par Metatrader qui donne une caractéristique de la période courante: le nombre de minutes qu'elle contient. La période courante étant celle sur laquelle on a lancé le programme (expert advisor ou indicateur). Cette fonction est  Period() . Si elle nous donne le nombre 5, c'est que nous sommes sur une période de 5 minutes ! c'est aussi simple que cela. Nous allons l'utiliser pour obtenir une information qui en découle comme le nombre de secondes de la période.

Le nombre de secondes dans la période courante:


Une fonction très simple à faire: calculer le nombre de secondes en ayant le nombre de minutes ! Tout ça pour la période utilisée dans le graphique sur lequel le programme a été lancé. Je suis sûr que vous avez déjà trouvé comment faire. La fonction  Period()  nous donne les minutes et je vous donne le code de la fonction très minimaliste:

int obtenirNbSecsDsPeriodeCourante() {
   return(60*Period());
}


Le nombre de secondes dans une période quelconque:


Sur le même modèle, on calcule le nombre de secondes d'une période en recevant en argument le nombre de minutes dans la période. Le code complet et minimaliste également de la fonction:

int obtenirNbSecsDsPeriode(int nbMinsDansPeriode) {
   return(60*nbMinsDansPeriode);
}

Mais plutôt que de faire deux fonctions pour la même chose, on va en faire une synthèse. Je m'explique: on ne va pas créer la première mais modifier celle-ci pour qu'elle prenne en compte le cas particulier de la première. L'argument aura une valeur par défaut:  EMPTY  comme ça lorsque dans le corps de la fonction la variable est vide, on lui met alors la valeur utilisée dans la première fonction issue de  Period() . Ainsi nous n'avons pas besoin de préciser le nombre de secondes dans une période si on veut la période courante. Voici le code:

int obtenirNbSecsDsPeriode(int nbMinsDansPeriode=EMPTY) {
   int nbSecsDsPeriode;
   if(nbMinsDansPeriode == EMPTY) { nbMinsDansPeriode = Period(); }
   nbSecsDsPeriode = 60 * nbMinsDansPeriode;
   return(nbSecsDsPeriode);
}


Le numéro d'une seconde dans une période:


On va maintenant faire un calcul un peu différent, puisqu'on veut non pas un numéro depuis l'epoch (1er janvier 1970 à 00:00:00) mais le numéro d'une seconde depuis le début de la période. Par exemple, si les périodes sont des M1, c'est-à-dire de 1 min = 60 sec, et que la seconde porte l'horodatage 132 (je sais c'est très vieux!) alors on en déduit que de 0 à 59, c'est la période n°0, de 60 à 119 c'est la période n°1, et que 132 est dans la période n°2. C'est la seconde n°132-120=n°12 de la période n°2. Il faut donc retirer de l'horodatage toutes les périodes entières qu'il contient et prendre le reste. Cette opération porte un nom en arithmétique: modulo. L'opérateur modulo (souvent représenté avec le signe pourcent: %) indique de faire la division euclidienne (entière) et de prendre le reste. En résumé: 132%60=12 ou encore 12%5=2. Mentalement il faut faire comme on vient de voir, retirer le diviseur autant de fois que possible et voir ce qui reste. 12=10+2=5x2+2, donc 12%5=2. Je vous propose une série d'exercices pour vous exercer si vous en avez besoin:

Exercices sur l'opérateur modulo
Soit l'opération 24%5 (prononcez «vingt-quatre modulo cinq»)
Combien de 5 peut-on retirer de 24:
La décomposition de 24 à choisir est:
24%5 est égal à:
Pour 24%11 la décomposition est:
Pour 8%3 la décomposition est:
8%3 est égal à:
Pour 9%3 la décomposition est:
9%3 est égal à:

Il faut retenir qu'il y a un nombre limité de restes possibles, par exemple: un nombre modulo 5, ne peut avoir que 5 résultats possibles qui sont 0, 1, 2, 3 et 4. On ne peut évidemment pas avoir 5 ou plus car on pourrait y retirer encore le diviseur qui est 5. Quand un nombre augmente, le résultat de son modulo est cyclique:
  • 0%3=0
  • 1%3=1
  • 2%3=2
  • 3%3=0
  • 4%3=1
  • 5%3=2
  • 6%3=0
  • 7%3=1
  • etc.

Nous allons donc utiliser l'opérateur modulo pour extraire le numéro d'une seconde dans la période à laquelle il appartient à partir de son horodatage. Notre fonction va donc recevoir en argument un horodatage et le nombre de secondes dans la période. Nous mettrons ce deuxième argument avec une valeur par défaut  EMPTY  comme ça lorsque nous le préciserons pas, il s'agira du nombre de secondes dans la période courante. Et lorsque le deuxième argument sera vide il faudra y mettre la valeur qu'on fera calculer par la fonction que nous avons créée précédemment, sans argument évidemment comme ça nous l'aurons pour la période courante:

int obtenirNoSecDsPeriode(datetime horodatageSec, int nbSecsDansPeriode=EMPTY) {
   int noSecDansPeriode;
   if(nbSecsDansPeriode == EMPTY) { nbSecsDansPeriode = obtenirNbSecsDsPeriode(); }
   noSecDansPeriode = horodatageSec % nbSecsDansPeriode;
   return(noSecDansPeriode);
}


Le tutoriel vidéo et le code du fichier include augmenté:




//+------------------------------------------------------------------+
//|                                       ArithmetiqueTemporelle.mqh |
//|                  Copyright 2014, argent-facile-avec-robots-forex |
//|               http://argent-facile-avec-robots-forex.blogspot.fr |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, argent-facile-avec-robots-forex"
#property link   "http://argent-facile-avec-robots-forex.blogspot.fr"

//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| EX4 imports                                                      |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| includes                                                         |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| variables globales                                               |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| constantes globales                                              |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| fonctions comptage                                               |
//+------------------------------------------------------------------+

datetime obtenirNoDerniereSecConnue(string paire="NULL") {
   datetime horodatage;
   if(paire=="NULL") { horodatage = TimeCurrent(); }
   else { horodatage = MarketInfo(paire, MODE_TIME); }
   return(horodatage);
}

int obtenirNbSecsDsPeriode(int nbMinsDansPeriode=EMPTY) {
   int nbSecsDsPeriode;
   if(nbMinsDansPeriode == EMPTY) { nbMinsDansPeriode = Period(); }
   nbSecsDsPeriode = 60 * nbMinsDansPeriode;
   return(nbSecsDsPeriode);
}

int obtenirNoSecDsPeriode(datetime horodatageSec, int nbSecsDansPeriode=EMPTY) {
   int noSecDansPeriode;
   if(nbSecsDansPeriode == EMPTY) { nbSecsDansPeriode = obtenirNbSecsDsPeriode(); }
   noSecDansPeriode = horodatageSec % nbSecsDansPeriode;
   return(noSecDansPeriode);
}

//+------------------------------------------------------------------+


Dans le prochain post nous ferons sans attendre un code de test pour ces deux fonctions, à ajouter à celui déjà existant. Il est impératif de le faire le plus tôt possible, car nous ne voyons pas le code fonctionner pour l'instant, et il ne s'agit pas de modifier ces fonctions quand nous voudrons les inclure dans un gros projet. Ou même d'avoir un bug dans un gros projet à cause de petites fonctions de base, on perdrait ainsi un temps précieux à chercher l'origine du problème et de la motivation au passage.

Aucun commentaire:

Enregistrer un commentaire