Accueil Indicateur technique Publication

Affichez la tendance actuelle sur tous les délais avec un indicateur pour MetaTrader 4

Pièce jointe
15620.zip (2.17 KB, Télécharger 0 fois)

Salut à tous ! Aujourd'hui, je vais vous parler d'un indicateur graphique qui va révolutionner votre façon de voir les tendances sur MetaTrader 4. Basé sur l’indicateur de tendance directionnelle, cet outil est conçu pour afficher toutes les tendances sur une seule et même interface.

Bien qu'il existe déjà plusieurs versions de cet indicateur, aucun d'entre eux ne permettait jusqu'à présent d’afficher tous les délais dans un panneau graphique unique. Si vous souhaitez explorer les différentes versions, vous pouvez jeter un œil à ce lien.

Pour ma part, j'ai pris cet indicateur et l'ai transformé en un panneau graphique qui affiche toutes les tendances. J'ai également apporté quelques modifications au code original. L'une des améliorations permet à l'utilisateur de sélectionner la méthode de moyenne mobile utilisée pour le lissage. L'original utilisait une moyenne mobile pondérée, mais j'ai ajouté l'option de choisir une méthode de lissage. Si l'on utilise une moyenne mobile simple pour le second calcul, l'indicateur donne une tendance plus fiable de l'évolution des prix.

Une autre nouveauté est la possibilité d'obtenir non seulement la direction de la tendance (haussière, baissière ou latérale), mais aussi sa valeur. Je prévois d'écrire un autre article prochainement pour expliquer comment utiliser un indicateur double SlopeDirection et créer un Expert Advisor avec.

SlopeDirection 

Mais pour l’instant, jetons un coup d'œil au code. Je commence par définir tous les noms d'objets que j'utiliserai. C'est une bonne pratique car chaque fois que vous définissez un nom d'objet entre guillemets, cela réserve de l'espace dans le programme. En les définissant une seule fois (via une instruction define), vous économisez de l'espace dans votre code.

// Définir les directions de tendance
#define     UPTREND           1
#define     DOWNTREND         -1
#define     FLATTREND         0

// Définir les objets
#define     TrendPanel        "TrendPanel"
#define     InfoLine1         "InfoLine1"
#define     InfoLine2         "InfoLine2"
#define     TrendLabel        "Tendance :  M1  M5  M15  M30  H1  H4  D1  W1  MN"
#define     TrendUp           "\233"
#define     TrendDown         "\234"
#define     TrendFlat         "\232"
#define     TrendUnknown      "\251"
#define     StatObjectError   "%s(%d) Échec de la création de '%s'.  Erreur = %d"

Ensuite, je définis deux tableaux. Un pour la position des pixels pour chacun des 9 délais, et le second pour les délais eux-mêmes. Ces tableaux sont définis comme des variables globales.

// Définir les variables globales
int      TrendPosition[] = { 44, 64, 88, 114, 136, 156, 174, 194, 216 };
int      TrendPeriods[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };

La fonction OnInit() de notre indicateur appelle une fonction pour créer le panneau et les objets à l'intérieur du panneau. Elle effectue également une vérification rapide sur les barres utilisées pour calculer la tendance. Moins de 3 barres, c'est un peu inutile.

//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé                         |
//+------------------------------------------------------------------+
int   OnInit()
{
   // Création des objets pour le panneau d'indicateur
   if(Create_Panel() && BarCount >= 3)
      return(INIT_SUCCEEDED);
   else
      return(INIT_FAILED);
}

Je ne vais pas entrer dans les détails sur le fonctionnement de la fonction GetTrend(), car il existe déjà une bonne documentation sur ce site à ce sujet. Jetons un coup d'œil à la fonction graphique DisplayTrend().

//+------------------------------------------------------------------+
//| Afficher la tendance actuelle pour tous les délais
//+------------------------------------------------------------------+
void  DisplayTrend(void)
{
   int      i, cntr, Trend, LastTrend;
   string   str;
   
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      Trend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method);
      if(Trend == FLATTREND)
      {
         // Je suis à plat, trouve la dernière direction de tendance
         cntr = 1;
         do 
         { 
            LastTrend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method, false, cntr++);
         } while(LastTrend == Trend);
         ObjectSetText(str, TrendFlat, 8, "WingDings", (LastTrend == UPTREND ? Green : Red));
         ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 6);
      }
      else
      {
         ObjectSetText(str, (Trend == UPTREND ? TrendUp : TrendDown), 8, "WingDings", (Trend == UPTREND ? Green : Red));
         ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 5 + (Trend == UPTREND ? 1 : -1));
      }
   }
}

En gros, nous parcourons simplement le tableau TrendPeriods[] (pour obtenir tous les délais) et nous définissons la flèche de tendance en fonction de la direction de tendance de ce délai. Si la tendance est plate, nous trouvons la première direction qui n'est pas plate pour savoir d'où venait la tendance afin d'afficher la flèche du côté de cette direction.

La fonction Create_Panel() dans notre OnInit() crée les objets ancrés en bas à gauche de l'écran et utilise TrendPosition[] pour placer les flèches au bon endroit.

//+------------------------------------------------------------------+
//| Créer le panneau de tendance en bas à gauche de l'écran
//+------------------------------------------------------------------+
bool  Create_Panel(void)
{

   int      i;
   string   str;
   
   // Créer la fenêtre de l'indicateur de tendance
   if(ObjectCreate(TrendPanel, OBJ_RECTANGLE_LABEL, 0, 0, 0))
   {
      ObjectSetInteger(0, TrendPanel, OBJPROP_XDISTANCE, 1);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YDISTANCE, 29);
      ObjectSetInteger(0, TrendPanel, OBJPROP_XSIZE, 240);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YSIZE, 26);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BGCOLOR, White);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BORDER_TYPE, 0);
      ObjectSetInteger(0, TrendPanel, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSetInteger(0, TrendPanel, OBJPROP_COLOR, Red);
      ObjectSetInteger(0, TrendPanel, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, TrendPanel, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BACK, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTED, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_HIDDEN, true);
      ObjectSetString(0, TrendPanel, OBJPROP_TOOLTIP, "\n");
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, TrendPanel, GetLastError()); return(false); }

   if(ObjectCreate(InfoLine1, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine1, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine1, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine1, OBJPROP_YDISTANCE, 15);
      ObjectSetInteger(0, InfoLine1, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine1, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine1, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine1, TrendLabel, 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine1, GetLastError()); return(false); }
   
   if(ObjectCreate(InfoLine2, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine2, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine2, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine2, OBJPROP_YDISTANCE, 5);
      ObjectSetInteger(0, InfoLine2, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine2, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine2, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine2, " " + DoubleToStr(BarCount, 0) + " / " + DoubleToStr(Method, 0), 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine2, GetLastError()); return(false); }

   // Créer l'objet de tendance et afficher la tendance actuelle    
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      if(ObjectCreate(str, OBJ_LABEL, 0, 0, 0))
      {
         ObjectSet(str, OBJPROP_CORNER, CORNER_LEFT_LOWER);
         ObjectSet(str, OBJPROP_XDISTANCE, TrendPosition[i-1]);
         ObjectSet(str, OBJPROP_YDISTANCE, 5);
         ObjectSetInteger(0, str, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(0, str, OBJPROP_HIDDEN, true);
         ObjectSetString(0, str, OBJPROP_TOOLTIP, "\n");
      }
      else
      { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, str, GetLastError()); return(false); }
   }

   // Allez afficher la tendance actuelle
   DisplayTrend();
      
   // Tout est bon
   return(true);
}

Cette fonction retournera TRUE si elle a réussi à créer tous les objets, ou retournera FALSE si une erreur s'est produite lors de la création d'un objet. Ce qui est sympa, c’est que l’indicateur affichera dans l’onglet EXPERT de votre console le code d'erreur et le numéro de ligne du code où l'erreur s'est produite.

Nous devons également mettre à jour l'indicateur de tendance pour chaque nouveau tick que nous recevons. Cela se fait en appelant DisplayTrend() dans notre fonction start().

//+------------------------------------------------------------------+
//| Fonction d'itération de l'indicateur personnalisé                              |
//+------------------------------------------------------------------+
int   start()
{
   // Afficher la tendance actuelle pour tous les délais
   DisplayTrend();   

   return(0);
}

Enfin, nous détruisons tous les objets créés par l’indicateur lorsque nous le fermons.

//+------------------------------------------------------------------+
//| Fonction de désinitialisation                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Supprimer les objets de l'indicateur
   if(ObjectFind(TrendPanel) >= 0) ObjectDelete(TrendPanel);
   if(ObjectFind(InfoLine1) >= 0) ObjectDelete(InfoLine1);
   if(ObjectFind(InfoLine2) >= 0) ObjectDelete(InfoLine2);
   for(int i=1; i<10; i++)
      if(ObjectFind("Trend"+DoubleToStr(i, 0)) >= 0) ObjectDelete("Trend"+DoubleToStr(i, 0));
}

Et voilà ! Vous disposez maintenant d'un joli panneau d'indicateurs affichant la tendance actuelle pour tous les délais en bas à gauche de votre écran.

Profitez-en !


Articles connexes

Commentaire (0)