Analyse de la struture du code d'un EA

Par l'équipe Trader-Forex.fr

Avant de programmer soi-même un Expert Advisor, il est utile de voir comment d'autres EAs ont été codés. MetaTrader 4 est fourni avec un EA «MACD Sample.mq4» qui se trouve sous le répertoire «experts» de votre installation. Cet EA servira d'exemple de base pour analyser la structure d'un EA simple. L'objectif n'est pas d'analyser en détail la logique de l'EA mais surtout de déterminer les «blocs» de code qui sont significatifs.

Fonctionnalités non-utilisées par MACD Sample

Avant de voir plus en détail le contenu de cet EA, on peut noter que certaines fonctionnalités de MQL4 ne sont pas utilisées dans cet EA car il est relativement simple.

  • il n'y a pas de directives de précompilation telles que #include, #import ou #define
  • il n'y a pas de variables globales autres que les paramètres d'entrée de l'EA
  • les fonctions init() et deinit() ne sont pas définies.

Analyse du code

Entête

Le code démarre par un entête rappelant le nom du programme et la propriété du code.

Analyse de la struture du code d'un EA

Ceci n'est pas obligatoire mais est une bonne pratique.

Définition des paramètres d'entrée

Les paramètres d'entrées sont définis tout de suite après l'entête en tant que variables globales.

extern double TakeProfit = 50;

extern double Lots = 0.1;

extern double TrailingStop = 30;

extern double MACDOpenLevel=3;

extern double MACDCloseLevel=2;

extern double MATrendPeriod=26;

Chaque paramètre à une valeur par défaut. Celle-ci peut être modifiée par l'utilisateur et dans ce cas l'EA utilisera la valeur définie par l'utilisateur.

Définition des variables locales de la fonction start()

La fonction start() est la seule fonction de cet EA. Au tout début de celle –ci sont définies les variables locales à cette fonction.

int start()

{

double MacdCurrent, MacdPrevious, SignalCurrent;

double SignalPrevious, MaCurrent, MaPrevious;

int cnt, ticket, total;

Ces variables ne sont pas initialisées car elles sont initialisées plus tard dans le code.

Contrôles effectués avant l'exécution de la logique

Avant d'exécuter la logique de l'EA il est souhaitable de vérifier que les conditions nécessaires à cette exécution sont remplies.

Dans cet EA 2 contrôles sont effectués:

• comme cet EA utilise plusieurs indicateurs calculant leurs valeurs sur plusieurs barres dans le passé il faut s'assurer que le nombre de barres dans le passé est suffisant.

if(Bars<100)

{

Print("bars less than 100");

return(0);

}

Bars est prédéfini dans le langage MQL4. On teste donc juste si le nombre de barre est suffisant, sinon la logique n'est pas exécutée.

• Il est aussi parfois utile de contrôler les valeurs d'entrée des paramètres pour s'assurer que l'utilisateur a entré une valeur valide. Nous avons le cas ici avec le TakeProfit mais ceci peut être fait avec n'importe quel paramètre.

if(TakeProfit<10)

{

Print("TakeProfit less than 10");

return(0); // check TakeProfit

}

Calcul des valeurs des indicateurs

La première étape de la logique est d'acquérir les valeurs des indicateurs.

MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);

MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);

SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);

SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);

MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);

MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);

Tous les indicateurs utilisés ici (MACD et moyenne mobile) sont des indicateurs proposés par défaut dans MQL4 et l'appel de la fonction ainsi que les paramètres nécessaires sont décrits dans l'aide en ligne de MetaEditor. Si des indicateurs non fournis en standard étaient utilisés il faudrait utiliser la fonction iCustom() pour les appeler.

Vérifications des conditions pour l'ouverture d'un ordre

Cet EA n'ouvre qu'un ordre à la fois, donc la première chose a faire avant d'ouvrir un ordre est de vérifier qu'il n'y pas d'ordre déjà ouvert. Ceci est réalisé par les 2 lignes suivantes:

total=OrdersTotal();

if(total<1)

OrdersTotal() est une fonction par défaut fournie par MQL4 permettant de connaitre le nombre total d'ordres ouverts sur la plateforme.

Ensuite avant d'essayer d'ouvrir un ordre le programme vérifie qu'il y a assez d'argent sur le compte pour ouvrir la taille de l'ordre demandé.

if(AccountFreeMargin()<(1000*Lots))

{

Print("We have no money. Free Margin = ", AccountFreeMargin());

return(0);

}

Puis viennent la vérification des conditions d'ouverture des ordres et l'ouverture des ordres. +

Dans le cas d'un Buy :

if(MacdCurrentSignalCurrent && MacdPrevious

MathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious)

{

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0, Ask+TakeProfit*Point, "macd sample",16384,0,Green); // ouvre l'ordre

if(ticket>0) // vérifie l'ouverture de l'ordre

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice()); // order bien ouvert

}

else Print("Error opening BUY order : ",GetLastError()); // erreur

return(0);

}

Dans le cas d'un Sell :

if(MacdCurrent>0 && MacdCurrentSignalPrevious &&

MacdCurrent>(MACDOpenLevel*Point) && MaCurrent

{

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red); // ouvre l'ordre

if(ticket>0) // vérifie l'ouverture de l'ordre

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice()); // order bien ouvert

}

else Print("Error opening SELL order : ",GetLastError()); // erreur

return(0);

}

Le code ci-dessus non seulement ouvre un ordre si les conditions requises sont remplies mais aussi vérifie ensuite que l'ordre a bien été ouvert.

Gestion des ordres ouverts

Une fois qu'un ordre a été ouvert il faut le gérer jusqu'à sa fermeture. Dans le cas présent, l'EA gère un trailing stop et la fermeture des ordres.

Pour cela l'EA boucle sur tous les ordres ouverts

for(cnt=0;cnt

Puis vérifie que ces ordres sont soit des Buy ou des Sell (et non pas des ordres limit ou stop) et aussi que ces ordres sont sur la paires sur laquelle l'EA est appliqué

OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderType()<=OP_SELL && // check for opened position

OrderSymbol()==Symbol()) // check for symbol

Ensuite dans le cas d'un Buy il vérifie si la condition de fermeture de l'ordre est remplie et dans ce cas ferme l'ordre

if(MacdCurrent>0 && MacdCurrentSignalPrevious &&

MacdCurrent>(MACDCloseLevel*Point))

{

OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // ferme position

return(0);

}

Si l'ordre n'est pas fermé alors le calcul du trailing stop est effectué

if(TrailingStop>0)

{

if(Bid-OrderOpenPrice()>Point*TrailingStop)

{

if(OrderStopLoss()

{

OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop, OrderTakeProfit(), 0,Green);

return(0);

}

}

}

Ici on peut noter qu'au lieu d'avoir 3 conditions «if» imbriquées il aurait pu être plus simple d'avoir un seul «if» avec un et logique «&&» entre les 3 conditions. Un code similaire est écrit pour la partie Sell pour effectuer les mêmes opérations.

Conclusion

Cet Expert Advisor est relativement simple mais il contient la structure de base des éléments devant être pris en compte dans un EA. Certaines parties de cet EA peuvent être améliorées pour prendre en compte d'autres éléments tels que la gestion de différentes paires ou l'exécution de plusieurs EA sur la même paire.