Trading-Attitude
Apprendre la bourse en ligne facilement et gagner de l'argent avec les actions, les CFD ou le Forex

 

Nous respectons vos données personnelles. Nous détestons les spams. C'est pour cela que nous nous engageons à ne pas vendre votre adresse email.
Email Marketing by AWeber

Trading automatique : coder un EA complet sans indicateur – partie 2

MQL4 trading automatiqueLeçon Trading automatique n°4

Programmer avec MQL4

 

Cette quatrième leçon sur MetaTrader fait suite à l’article dans lequel nous voulions programmer un système de trading automatisé décrit dans le numéro de mai 2013 du magazine Currency Trader.

Nous en étions resté au passage d’ordre grâce à la fonction OrderSend. Cette fonction envoie un ordre de trading sur le Forex (ou un autre marché / actif : un indice, un CFD, …).

 

Finir le code de l’EA Metatrader

Notre problème est que l’EA reçoit chaque tick. Si nous appliquons chaque fois les critères d’entré on se retrouve à passer n fois le même ordre.

Nous devons donc introduire un moyen de limiter le nombre d’exécutions des ordres de trading sur la paire.

On stocke donc la date du jour (nous intervenons sur la clôture / ouverture du jour, en daily) :

 

    datetime now = TimeCurrent(),
             BOD = DateOfDay(now);

    if (PrevBOD == BOD) {
      return;
    }

 

Au passage, vous voyez que l’on peut définir et initialiser 2 (ou plus) variables sur la même ligne (les variables now et BOD).

 

La variable PrevBOD est mise à jour dans la fonction start(). Elle a la même valeur durant toute la journée. Elle ne change qu’à l’ouverture (ie à 00:00 heure).

Si la valeur calculée BOD possède la même valeur que PrevBOD on ne fait rien (return).

Bien sûr, la variable PrevBOD est une variable globale (interne), donc définie au début du fichier (mais sans le modificateur extern).

 

La fonction DateOfDay est définie à la fin du code :

datetime DateOfDay(datetime when){  return( when - TimeOfDay(when) );       }

 

Vous trouverez le code complet ci-dessous ou en téléchargeant le code de l’expert advisor ici.

 

Installer le code de l’EA

Téléchargez ou copiez le code. Placez votre fichier dans le dossier « experts » situé dans le dossier d’installation de votre logiciel MetaTrader.

Ouvrez-le avec MetaEditor.

Cliquez sur le bouton Compile.

L’EA lecon3 devrait maintenant apparaître dans la liste des Experts Advisors (ou Expert Consultant) dans la fenêtre Navigateur (tapez Ctrl+N).

 

Exécuter l’EA sur une paire

Pour l’appliquer à une paire de devises, faites-le glisser sur le graphique.

Un petit smiley avec un sourire devrait apparaître en haut à droite du graphique.

Attention : il vaut mieux que celui-ci soit en daily !

 

Si le smiley ne sourit pas, ou s’il y a une croix à côté de son nom, vérifiez :

  • que le bouton Expert Advisors est enfoncé
  • que le trading en direct est activé dans les propriétés de l’EA (cliquez sur le smiley et cochez « autoriser Trading en direct »)

 

bouton expert advisor

Cliquez sur ce bouton pour autoriser les EA

 

Smiley de l'EA

Smiley indiquant un EA non actif

 

smiley expert advisor proprietes

Clic sur le smiley – cochez « autoriser Trading en direct »

 

Tester un expert advisor

Je vous recommande cependant de tester (backtester) l’expert advisor avant de l’utiliser.

Pour tester votre nouveau robot de trading, tapez Ctrl+R pour faire apparaître le cadre Stratégies.

  • Dans la liste déroulante sélectionnez leçon3.
  • Sélectionnez le symbole que vous voulez.
  • Pour le modèle, mieux vaut utiliser la méthode « chaque tick« , mais c’est beaucoup plus long (prenez un intervalle de dates court).
  • Cochez « Utiliser date » et sélectionner la date de départ et la date d’arrivée.
  • Ne cochez pas « Mode visuelle », sauf si vous voulez voir ce qui se passe sur le graphique.
  • Avec le bouton « Propriétés de l’Expert » choisissez le nombre de lots (j’ai pris 0.1).
  • Choisissez la période Daily.
  • Cliquez sur Valeur initiale pour démarrer le test.

 

cadre strategies lecon3

Le cadre stratégies

Pour voir ce que cela donne, cliquez sur l’onglet Graphique du cadre Stratégies. Si cela monte, c’est bon !

 

Les tests de l’expert Advisor MQL4

Nous verrons dans une prochaine leçon comment exploiter les résultats d’un backtest de robot de traing avec MetaTrader.

 

Pour l’instant voici les quelques résultats que j’ai obtenus.

 

performances EUR/USD

Performances EUR/USD

 

 

Performances GBP/USD

Performances GBP/USD

 

EUR / USD long terme

Performances EUR / USD long terme

 

Ma conclusion :

on arrive à certains gains avec ce robot de trading, mais on ne sait pas trop pourquoi. C’est purement analytique. Est-ce que cela peut durer ? On ne sait pas.

Le facteur de profit varie de 0,68 (très mauvais) à 1,5.

Le drawdown maximal n’est pas si mauvais (de 7% à 20%).

Je ne suis pas convaincu par ce robot de trading.

Il nous aura quand même permis d’apprendre beaucoup de choses et pourra peut-être vous servir de base à vos propres automates de trading.

 

Téléchargez les rapports au format HTML zippé…

Pour aller plus loin…

Si vous voulez aller plus loin voici un bon bouquin :


Une formation en vidéo

 

Si vous préférez la vidéo, voici une formation en vidéo sur MQL4.

 

Le code source de l’expert advisor

 

#property copyright "Copyright © 2013 Trading Attitude"
#property link      "http://www.trading-attitude.com"

/*

(CurrencyTrader de mai 2013)

Long entry (short exit):
1. Today’s close is below its open (Close[0] < Open[0]).
2. Today’s open is above the low two days ago (Open[0] > Low[2]).
3. Today’s range is greater than the range seven days earlier (Range[0] > Range[7]).
4. Yesterday’s close is above the close seven days ago (Close[1] > close[7]).
5. Yesterday’s close is above the high four days ago (Close[1] > high[4]).
Short entry (long exit):
1. Today’s close is above its open (Close[0] > Open[0]).
2. Today’s open is below the high two days ago (Open[0] < High[2]).
3. Today’s range is greater than the range seven days earlier (Range[0] > Range[7]).
4. Yesterday’s close is below the close seven days ago (Close[1] < close[7]).
5. Yesterday’s close is below the low four days ago (Close[1] < Low[4]).

iBarShift(NULL, 0, TimeCurrent()-(TimeCurrent()&3600)-(60 * 60 * (Hour()+1) ) )  // gives the bar number for 23:00 hour the previous day

TimeCurrent()-(TimeCurrent()&3600)-(60 * 60 * (Hour()+1) )       // gives the datetime for the 23:00 hour the previous day

*/
#define HR2400          86400                   // 24 * 3600

extern int MagicNumberBuy          = 45454;
extern int MagicNumberSell         = 45455;
extern double Lots       =0.01;

bool OpenBuy = false;
bool OpenSell = false;

double maVar = 2.0;
bool done = false;
datetime PrevBOD;

int init()
  {
   Print("Must be run in Daily timeframe");
   return(0);
  }

int start() {

   static datetime lastTradeOpen;
    datetime now = TimeCurrent(),
             BOD = DateOfDay(now);
    bool     isTradingAllowed = BOD != lastTradeOpen;

    datetime y2300 = BOD - 3600; // Yesterday+2300z
   int      i2300H1 = iBarShift(NULL, PERIOD_H1, y2300);
   datetime t2300   = iTime(0, PERIOD_H1, i2300H1);
   double   o2300   = iOpen(0, PERIOD_H1, i2300H1);
   //Print("Yesterday's open at ",TimeToStr(t2300), " was ", o2300);

   calculSignal();

   openOrder();

   PrevBOD = BOD;
   return(0);
}

void calculSignal() {
   static datetime lastTradeOpen;
    datetime now = TimeCurrent(),
             BOD = DateOfDay(now);
    bool     isTradingAllowed = BOD != lastTradeOpen;

    datetime y2300 = BOD - 3600; // Yesterday+2300z
   int      i2300H1 = iBarShift(NULL, PERIOD_H1, y2300);
   datetime t2300   = iTime(0, PERIOD_H1, i2300H1);
   double   o2300   = iOpen(0, PERIOD_H1, i2300H1);
   //Print("Yesterday's open at ",TimeToStr(t2300), " was ", o2300);

   if (PrevBOD == BOD) {
      return;
   }
   double pclose = iClose(Symbol(),PERIOD_D1,1);
   double popen = iOpen(Symbol(),PERIOD_D1,1);
   double phigh = iHigh(Symbol(),PERIOD_D1,1);
   double plow = iLow(Symbol(),PERIOD_D1,1);
   double p2low = iLow(Symbol(),PERIOD_D1,3);
   double p2high = iHigh(Symbol(),PERIOD_D1,3);
   double p7low = iLow(Symbol(),PERIOD_D1,8);
   double p7high = iHigh(Symbol(),PERIOD_D1,8);
   double p1close = iClose(Symbol(),PERIOD_D1,2);
   double p7close = iClose(Symbol(),PERIOD_D1,8);
   double p4high = iHigh(Symbol(),PERIOD_D1,5);
   double p4low = iLow(Symbol(),PERIOD_D1,3);

   bool crit1 = pclose < popen;
   bool crit2 = popen > p2low;
   double range = phigh - plow;
   double range7 = p7high - p7low;
   bool crit3 = range > range7;
   bool crit4 = p1close > p7close;
   bool crit5 = p1close > p4high;

   bool critBuy = crit1 && crit2 && crit3 && crit4 && crit5;

   if (critBuy) {
      OpenBuy = true;
   } else {
      OpenBuy = false;
   }

   crit1 = pclose > popen;
   crit2 = popen < p2high;
   crit3 = range > range7;
   crit4 = p1close < p7close;
   crit5 = p1close < p4low;

   bool critSell = crit1 && crit2 && crit3 && crit4 && crit5;

   if (critSell) {      
      OpenSell = true;
   } else {
      OpenSell = false;
   }

   openOrder();

}

void openOrder() {
   RefreshRates();
   double SL=0;
   double TP=0;
   double Ticket = 0;

   bool weAreLong = orderNumber(MagicNumberBuy) > 0;
   bool weAreShort = orderNumber(MagicNumberSell) > 0;
   bool notInMarket = !weAreLong && !weAreShort;

   if (OpenBuy && (weAreShort || notInMarket)) {
      if (weAreShort) {
         closeTrades(MagicNumberSell);
      }
      Ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,2,SL,TP,"Simple",MagicNumberBuy,0,Green);
      if (Ticket>=0) {
         OpenBuy = false;
      }
   } else if (OpenSell && (weAreLong || notInMarket)) {
      if (weAreLong) {
         closeTrades(MagicNumberBuy);
      }
      Ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,2,SL,TP,"Simple",MagicNumberSell,0,Green);
      if (Ticket>=0) {
         OpenSell = false;
      }
   }

}

void closeTrades(int mgNb) {
  int total = orderNumber(mgNb);
  for(int j=total-1;j>=0;j--) {
    OrderSelect(j, SELECT_BY_POS);
    int type   = OrderType();

   if (OrderMagicNumber() != mgNb) {
         continue;
   }
    bool result = false;

    switch(type) {
      //Close opened long positions
      case OP_BUY       : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
                          break;

      //Close opened short positions
      case OP_SELL      : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );

    }
  }
}

int orderNumber(int mgNb) {
   int total = 0;
   for(int i=1; i<=OrdersTotal(); i++) {         // Loop through orders
      if (OrderSelect(i-1,SELECT_BY_POS)==true) {
         if (OrderSymbol()!=Symbol()) {
               continue;      // Another security
         }
         if (OrderMagicNumber() != mgNb) {
            continue;
         }

         total = total + 1;
      }
   }
   return (total);
}

datetime TimeOfDay(datetime when){  return( when % HR2400          );       }
datetime DateOfDay(datetime when){  return( when - TimeOfDay(when) );       }

 

 

 

Leave a reply

Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

CommentLuv badge