Rejoindre la communauté
banner_forum
Devenez membre de la plus grande
communauté francophone sur le Forex
Partagez, échangez et apprenez en gagnant des crédits sur votre compte de trading

Fabriquer son EA à partir d'indicateur

  • babs

    Bonjour à tous,

    Il me semble que plusieurs personnes seraient intéressées par le fait de fabriquer un EA à partir de ses indicateurs favoris.
    Donc je propose de vous expliquer comment faire.

    Tout d'abord il vous faut lancer le logiciel "MetaEditor" fournit avec la plateforme MT4 (vous le trouverez dans le menu de vos programmes sous Metatrader)

    Ensuite il faut faire : File -> New -> Expert Advisor
    Dans la fenêtre qui suit faites : Sélection Expert Advisor -> Next -> Remplir le champ Name (Vous pouvez ajouter des paramètres en cliquant sur Add)-> Terminer.

    Un fichier s'ouvre il comporte 3 fonctions : init() deinit() et start()
    Comme vous pouvez le constater une fonction est encadrée par deux accolades { }.

    >>init() : C'est la fonction qui est appelée lorsque le robot est attaché à un graphique ou si vous changez les paramètre du robot.

    >>deinit() : Cette fonction est appelé lorsque vous désactivez le robot. C'est à dire lorsque vous le supprimez du graphe en cours ou si vous cliquez sur le bouton "Expert Advisors"

    >>start() : Cette fonction est appelée à chaque tick, elle contiendra la logique de votre robot.

    *Paramètres d'entrées : les paramètres d'entrées permettent de modifier des variables à l'extérieur du code, plus précisément dans la boite de dialogue qui s'ouvre lorsque vous attachez le robot au graphe. Ils sont de la forme "extern <type> nomDuParamètre;"
    Les différents types sont les suivants:
    >> int : un nombre entier
    >>double : un chiffre décimale
    >> bool : un booléen, ça valeur sera FALSE ou TRUE
    >> string : Une chaîne de caractère (une phrase dans le cas général)

    Pour plus de renseignement vous pouvez aller voir la documentation MQL4 (le langage de MT4) sur : http://docs.mql4.com/index
  • babs

    En principe pour faire un robot les paramètres de base utilisés sont les suivants :
    >> MagicNumber : Le numéro d'identification du robot permettant de retrouver ses ordres
    >> Lot : La taille des lots des trades (pour un lot fixe)
    >> StopLoss : Valeur en pips du SL des trades effectués par le robot
    >> TakeProfit : Valeur en pips du TP des trades effectués par le robot

    Pour notre exemple je pense que ceux-ci suffiront.
  • babs

    Passons aux choses sérieuses...

    Quels indicateur allons nous utiliser pour cet exemple??? La réponse est Moving Average plus communément appelé MA.
    Bon ok vous vous en doutiez....

    Mais comment appelez cette indicateur???
    Une chose importante : Tout indicateurs appelés par un EA doit être placé dans le dossier Indicators!!!

    Bon il existe deux types d'appels :
    --- Appeler les indicateurs natifs de MT4---
    Bon Metatrader a été sympa ils ont crée des fonctions permettant facilement d'appelé leurs indicateurs vous les trouverez à cette adresse : http://docs.mql4.com/indicators

    >>>Exemple<<<

    Prenons l'indicateur MA : le prototype de sa fonction est le suivant
    double iMA( string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift)
    >> Symbol : Mettre NULL pour utiliser la paire courante
    >> timeframe : Mettre 0 pour utiliser le TF courant (Certain vont se dire : MMMmmmmhh je peux faire du multiframe alors... Et bien OUI)
    >> period : La période de votre MA, ici nous utiliserons 5 et 13 pour la deuxième.
    >>ma_shift : Offset de l'indicateur
    >> ma_method : A choisir parmi les suivantes (MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA)
    >>applied_price : A choisir parmi les suivants (PRICE_OPEN , PRICE_CLOSE , PRICE_HIGH , PRICE_LOW , PRICE_MEDIAN , PRICE_TYPICAL , PRICE_WEIGHTED)
    >> shift : Offset horizontal (utile pour détecter les croisements)

    Donc au final nous obtenons ceci : iMA(NULL,0,5,0,MODE_SMMA,PRICE_CLOSE,0)

    --- Appeler mes indicateurs personnels ---

    Rien de plus facile encore un grand merci a Metatrader pour la fonction iCustom : Vous trouverez des explications à cette adresse : http://docs.mql4.com/indicators/iCustom

    >>>Exemple<<<

    double iCustom( string symbol, int timeframe, string name, ..., int mode, int shift)
    >>Symbol , timeframe et shift sont identiques aux paragraphes au-dessus
    >> name : Vous devez mettre le nom exact de votre indicateurs situé dans le dossier Indicators.
    >> ... : Correspond aux paramètres externes de l'indicateur, vous devez les mettre dans l'ordre exact dans lequel ils sont disposés dans la boite de dialogue.
    >> mode : C'est option est plus technique, il faut savoir qu'un indicateur se compose de plusieurs buffers (par exemple si vous prenez un indicateur qui vous signale un achat ou une vente par deux flèches celui-ci "en général" comportera deux buffers). Cette option permet de choisir le buffer à lire.

    Passons à un exemple concret : Nous allons appeler l'indicateur "Moving Averages" placé dans indicateurs personnalisés.
    Donc si je veux l'appeler je fais comme ceci :
    iCustom(NULL,0,"Moving Averages",5,0,MODE_SMMA,0,0);

    Voilà c'est fait!


  • babs

    Note 1 : Arrêter de mettre "Bon" partout
    Note 2 : Corriger les fautes dès que l'option d'édition sera disponible.

    Désolé pour tout ça...
  • babs

    Code
    //+------------------------------------------------------------------+ //| MACross.mq4 | //| Copyright © 2010, Babs Assoc. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2010, Babs Assoc." #property link "http://www.metaquotes.net" //+------------------------------------------------------------------+ //| External Parameters | //+------------------------------------------------------------------+ extern int MagicNumber = 9876; extern double Lot = 0.01; extern int TakeProfit = 60; extern int StopLoss = 30; //+------------------------------------------------------------------+ //| Global Variable | //+------------------------------------------------------------------+ int OpenedOrder; // 1=Buy , 2=Sell double MyPoint; int NbBars; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- OpenedOrder=FALSE; NbBars=0; if (Digits == 5 || Digits == 3) MyPoint = Point*10; else MyPoint= Point; //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- double ema5, ema5Prev; double ema13, ema13Prev; //Acquisition des indicateurs ema5=iMA(NULL, 0, 5, 0, MODE_SMMA, PRICE_MEDIAN, 0); ema5Prev=iMA(NULL, 0, 5, 0, MODE_SMMA, PRICE_MEDIAN, 1); ema13=iMA(NULL, 0, 13, 0, MODE_SMMA, PRICE_MEDIAN, 0); ema13Prev=iMA(NULL, 0, 13, 0, MODE_SMMA, PRICE_MEDIAN, 1); //Verification des trades ouverts CheckTrade(); //Logique if(isNewBar()) { if(ema5>ema13 && ema5Prev<ema13Prev && (OpenedOrder==2 || OpenedOrder==0)) //Croisement à la hausse { CloseTrade(); OpenBuy(); } if(ema5<ema13 && ema5Prev>ema13Prev && (OpenedOrder==1 || OpenedOrder==0)) // Croisement à la baisse { CloseTrade(); OpenSell(); } } //---- return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| expert Close Buy/Sell order function | //+------------------------------------------------------------------+ void CloseTrade() { for(int i= OrdersTotal()-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); if (OrderMagicNumber() == MagicNumber && Symbol()==OrderSymbol()) { switch(type) { //Fermeture des positions d’achat case OP_BUY : OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(),MarketInfo(OrderSymbol(), MODE_BID), Red ); break; // Fermeture des positions de vente case OP_SELL : OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(),MarketInfo(OrderSymbol(), MODE_ASK), Red ); break; } } } } //+------------------------------------------------------------------+ //| expert Open Buy order function | //+------------------------------------------------------------------+ void OpenBuy() { if (!IsTradeContextBusy() && IsTradeAllowed()) { OrderSend(Symbol(),OP_BUY,Lot,Ask,3,Bid-StopLoss*MyPoint,Ask+TakeProfit*MyPoint,"MACross",MagicNumber,0,Green); } } //+------------------------------------------------------------------+ //| expert Open Sell order function | //+------------------------------------------------------------------+ void OpenSell() { if (!IsTradeContextBusy() && IsTradeAllowed()) { OrderSend(Symbol(),OP_SELL,Lot,Bid,3,Ask+StopLoss*MyPoint,Bid-TakeProfit*MyPoint,"MACross",MagicNumber,0,Green); } } //+------------------------------------------------------------------+ //| Check order function | //+------------------------------------------------------------------+ void CheckTrade() { OpenedOrder=0; for(int i= OrdersTotal()-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()) { switch(type) { case OP_BUY : OpenedOrder=1; break; case OP_SELL : OpenedOrder=2; break; } } } } //+------------------------------------------------------------------+ //| Check New Bar function | //+------------------------------------------------------------------+ bool isNewBar() { if (NbBars < Bars) { NbBars = Bars; return (TRUE); } return (FALSE); }


    Edit: Correction du code par Babs
  • babs

    Le formatage du code a sauté donc si vous voulez le fichier je peux vous l'envoyer. Laissez moi juste votre email.
  • Forex88

    Je te remercie Babs pour ces explications, on pourrait presque croire que programmer est un jeu d'enfant...
  • cathare

    Merci Babs pour tes explications très pédagogique.
  • babs

    Il est vrai que programmer (pour les débutants) ressemble souvent à un jeu à cause des points communs suivants :
    >> Tu réfléchis à ce que tu veux faire (ou pas)
    >> Tu l'essayes
    >> Tu testes
    >> Tu recommences

    quand on deviens un peu expérimenté on préfère passer plus de temps sur la première partie afin de ne pas passer par la dernière "Recommencer". C'est la qu'intervient le papier et le crayon et les logigrammes ou tout autre description de son système (UML, SysML...)

    @Tout le monde
    Mais pour commencer il faut connaître quelques bases, je vous rassures il en faut peu. Un site très connu permet de commencer la programmation C de façon très simple. Je ne veux pas faire du pub donc cherchez juste "Programmation C" sous le site de recherche le plus connu lol. C'est la première réponse.
  • babs

    Dans le code d'un EA vous pouvez voir ceci : "//" ou encore "/*" et plus loin vous trouverez forcément ceci "*/"
    >> // : Ces caractère permettent de dire "ce qui suit n'est pas du code jusqu'à la fin de la ligne"
    >> /* : A partir de ces caractères tout ce qui suit ne sera pas considérer comme du code jusqu'à ce que je rencontre "*/"

    du coup on peut faire ceci :

    int nombreDeBars; // Cette variable représente le nombre de barres déjà traitée par le robot

    ou ceci :
    int nombreDeBars; /* Cette variable représente le nombre de barres déjà traitée par le robot */

    ou :
    /*La variable suivante représente
    le nombre de barres déjà traitée par le robot*/
    int nombreDeBars;

    En gros les commentaires permettent de pouvoir comprendre le code plus facilement. Donc n'hésitez pas à en mettre dans votre code afin que vous puissiez le reprendre plus tard
  • Gabou1103

    Merci
    babsou t'es le meilleur!

  • furynick

    on va blinder le "coin des experts" à nous deux babs ;o)
  • babs

    Yep, Blindons le ;)

    En postant à deux j'espère que toutes les personnes trouveront leur bonheur.
  • Djmisterjon

    je savai deja et avai deja poster quelque post ladessu pour aider les gens effectivement de fair un post la dessu est une bonne idée.
    Jaispair que cela menera les gens a fabriquer pluis dindicateur, car la comunauter francaise est vraiment pas fort pour le developpement .
    Tout les indicateur la plupart son canada englais ou US.
    Sa serai bien de voir quelque programmeur et mathematicien avancé, ce lancé dans le developpement dindicateur MT4.

    Merci de ton post detail , je suis moi meme programmeur et scypteur, jai lintention de commencer d'ici 4 a 6 mois la programmation Mt4.
  • babs

    oui surtout qu'en France (je ne sais pas pour la belgique) on a de bonnes ressources en mathématique et en informatique.
    J'ai un ami qui se forme a la fabrication d'indicateur, il a deux projets en cours:
    -Indicateur de reconnaissance des figures de chandeliers
    -indicateur donnant le rayon de courbure du cours (indicateur de range ou tendance)

  • robotrader

    salut babs je reponds a se forum peut etre un peu tard mais est il possible d avoir le fichier du code de cet ea par mail ? merci
  • babs

    Oui pas de soucis, je dois l''avoir quelquepart.

    Par contre pourrai-tu passer par la section présentation stp.

    Merci
  • robotrader

    sa y est je suis passer par les présentation
    alor voila j ai copier coller ton code le probleme est que le robot n' ouvre que les position d' achat je ne comprend pas pourquoi
    j ai tout essayer pour modifier le code mais le probleme est toujours la au passage j ai modifier aussi cette ligne
    if(isNewBar() && ema5>ema13 && ema5Prev<ema13Prev && (OpenedOrder==2 || OpenedOrder==0)) en rajoutant un = je sais c est pas grand chose mais la position s ouvre pile au moment du croisement
    if(isNewBar() && ema5>=ema13 && ema5Prev<ema13Prev && (OpenedOrder==2 || OpenedOrder==0))
    voila mon email si tu peux m envoyer le fichier [email protected]
    et si tu peux m expliquer pourquoi le robot n ouvre pas de position a la vente je pense que le problème vient de la fonction check trade peut etre mais pas sur étant novice j ai un peut de mal a me plonger dans le code de quelqu un d autre
    voila je te remercie d avance
  • robotrader

    a oui et je me demandais aussi pourquoi est ce que tu as mis un stoploss et un take profit alors que les trade doive se femer automatiquement sur les croisement ??
  • babs

    Je t'envoi ca dans 2min.

    Je pense que c'est du au copier coller car normalement il doit prendre des positions dans les deux sens. J'ai pas trop le temps de regarder ce soir mais demain j'y jetterai un oeil.