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.
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
- iMAX3 : Détecteur de Tendances Rapides pour Traders
- Découvrez le 3ème Génération XMA : L'indicateur essentiel pour MetaTrader 5
- Découvrez l'indicateur Tymen STARC Bands MTF pour MetaTrader 5
- WKBIBS : L'oscillateur incontournable pour MetaTrader 5
- Améliorez vos graphiques avec ClearView : Indicateurs et modèles pour MetaTrader 5