Forex: apprendre à programmer son robot de trading pour son système automatique
Une explication détaillée d’un robot de trading simple pour le forex, Logical Trend.
De nombreux mails me parviennent de personnes me demandant s’il est simple de programmer son robot de trading.
Pour répondre à cette question, voici une stratégie simple sur 10 mois que j’ai appelée Logical Trend, et que l’on va coder, pour faire fonctionner le robot avec le logiciel Metatrader 4. Le moyen le plus simple pour apprendre rapidement n’est pas d’apprendre un bouquin par coeur, mais de regarder des robots déjà codés, pour en comprendre le fonctionnement.
Vous verrez à partir de là, si vous accrochez ou bien si cela vous rebute. Cette stratégie tourne sur 10 mois sur une unité D1 (daily), voici le résultat final que l’on aura, avec l’évolution de notre capital:

Vous pouvez dès à présent télécharger le robot de trading Logical Trend ici.
Présentation de la stratégie Logical Trend:
Lorsqu’un cours est en tendance (haussière par exemple), on peut remarquer 2 choses. La première est le plus pas de la bougie en cours est très souvent plus haut que le plus bas de la bougie précédente. La deuxième est que en 80% du temps, cette bougie a une mèche basse.
A partir de là, on va se dire que notre entrée pourra se faire en tendance haussière lorsque la bougie en cours a une mèche basse et que le cours repasse à la hausse en cassant le cours d’ouverture et inversement pour une tendance baissière.

La tendance sera définie par une moyenne mobile lissée qui portera sur le prix médian, dont la période variera selon l’ATR du moment (tout comme le stoploss et le takeprofit). En effet, plus l’ATR sera petit plus la période de la MM sera longue, plus l’ATR sera grand, plus la période de la MM sera courte, pour bien être réactive.
Détaillons alors le code de Logical Trend:
Nous définissons les variables que nous pourrons modifier à loisir (pour optimiser le robot par exemple). Double représente un nombre a décimale, int un nombre entier:
extern double MARatio=5.5;
extern double ATRSL=0.275;
extern double ATRTP=1.3;
extern int Slippage=30;
Nous définissons ensuite des variables que nous ne pourrons modifier manuellement. Magic servira à identifier les trades faits par le robot et non en manuel.
int Magic=123456;
double Lots;
int MAPeriode;
int CapitalInitial;
Ci dessous, l’initialisation de l’expert. Ce qui est fait dans ces lignes ne se fera qu’une seule fois, lorsque l’on met en route le robot:
//+——————————————————————+
//| expert initialization function |
//+——————————————————————+
int init()
{
//—-
CapitalInitial=AccountBalance();
//—-
return(0);
}
Ici, il vérifie le capital de départ. On met la valeur du capital de départ (AccountBalance) dans une variable qui s’appelle CapitalInitial. On le fait à cet instant, car quand le robot va trader, le capital changera tout le temps, et donc on aura plus le loisir de savoir à combien il était au départ.
Ensuite, les instructions à suivre lorsque l’on coupe l’expert. Dans notre cas, aucune:
//+——————————————————————+
//| expert deinitialization function |
//+——————————————————————+
int deinit()
{
//—-
//—-
return(0);
}
Nous codons ensuite une boucle Start. Cette boucle sera exécutée à chaque fois que le cours changera:
//+——————————————————————+
//| expert start function |
//+——————————————————————+
int start()
{
//—-
Une petite ligne appelera la fonction Orderlist qui gère le breakeven, mais ne le fera que si nous avons au moins un ordre en cours (pour ne pas surcharger le robot s’il n’y a pas d’ordre):
if (OrdersTotal()>0)OrdersList();
Nous développerons cette fonction à la fin (”void OrdersList()“).
En revanche, précisons le rôle du if. il introduit une condtion. La syntaxe classique d’une condition est:
if (condition) {instructions à suivre si la condition est réalisée;}
Une deuxième syntaxe existe dans le cas où il n’y a qu’une seule instruction à suivre:
if (condition) instruction uniique à suivre si la condition est réalisée;
On peut également introduire une alternative:
if (condition) {instructions à suivre si la condition est réalisée;} else {insctructions si la condition n’est pas remplie;}
Ensuite, arrive à un jeu d’instructions que nous exécuterons que si aucun ordre n’est en cours:
if(OrdersTotal()<1){
Nous allons donc entrer ici, tout ce qui concerne la prise de position (les entrées).
Nous commençons par définir la moyenne mobile qui définit notre tendance:
MAPeriode=MathRound(1/iATR(Symbol(),PERIOD_D1,14,0)/MARatio*2);
On utilise ici 1/ATR que l’on divise par notre MARatio que l’on arrondi pour trouver notre pérdioe de moyenne mobile.
if (iLow(Symbol(),PERIOD_D1,0) > iLow(Symbol(),PERIOD_D1,1) &&iLow(Symbol(),PERIOD_D1,0) < iOpen(Symbol(),PERIOD_D1,0) &&Close[0] > iOpen(Symbol(),PERIOD_D1,0) &&iMA(Symbol(),PERIOD_D1,MAPeriode,0,MODE_SMMA,PRICE_MEDIAN,0) > iMA(Symbol(),PERIOD_D1,MAPeriode,0,MODE_SMMA,PRICE_MEDIAN,1) &&OrdersTotal()<1)
{
Lots=AccountEquity()/Close[0]/CapitalInitial*10/100 / (AccountEquity()/1000);
if(Lots<0.1||AccountEquity()<CapitalInitial) Lots=0.1;
OrderSend (Symbol(),OP_BUY,Lots,Ask,Slippage, Ask-ATRSL*iATR(Symbol(),PERIOD_D1,14,0), Ask+ATRTP*iATR(Symbol(), PERIOD_D1,14,0), “LogicalTrend”, Magic, Blue);
}
Ici un jeu d’instruction plutot long que j’aurais pu raccourcir, mais je code souvent au kilomètre
Nous allons donc le détailler:
if ( iLow(Symbol(),PERIOD_D1,0) > iLow(Symbol(),PERIOD_D1,1) &&iLow(Symbol(),PERIOD_D1,0) < iOpen(Symbol(),PERIOD_D1,0) &&Close[0] > iOpen(Symbol(),PERIOD_D1,0) &&iMA(Symbol(),PERIOD_D1,MAPeriode,0,MODE_SMMA,PRICE_MEDIAN,0) > iMA(Symbol(),PERIOD_D1,MAPeriode,0,MODE_SMMA,PRICE_MEDIAN,1) &&OrdersTotal()<1)
{
si le plus bas de la bougie D1 actuelle est plus haut que le plus bas de la bougie D1 d’hier
et que le plus bas d’aujourd’hui est plus bas que l’ouverture d’aujourd’hui (on vérifie la présence d’une mèche basse)
et que le cours actuel est supérieur à l’ouverture du jour
et que la moyenne mobile est supérieure à celle d’hier
et qu’il n’y a pas d’ordre en cours
Alors:
Lots=AccountEquity()/Close[0]/CapitalInitial*10/100 / (AccountEquity()/1000);
if(Lots<0.1||AccountEquity()<CapitalInitial)Lots=0.1;
OrderSend( Symbol(), OP_BUY, Lots, Ask, Slippage, Ask-ATRSL*iATR(Symbol(),PERIOD_D1,14,0), Ask+ATRTP*iATR(Symbol(),PERIOD_D1,14,0), “LogicalTrend”, Magic, Blue);
Dans ce cas, on commence par définir le nombre de lot (ici, on prend 10% du capital disponible pour trader. Si ce nombre de lots calculé est inférieur à 0.1 ou que le capital actuel est en dessous de notre capital de départ, on trade avec 0.1 lot.
Ensuite, on envoit un ordre d’achat (OrderSend), que l’on détaille ici:
OrderSend(
Symbol(), sur la paire du graph en cours
OP_BUY, c’est un achat (OP_SELL pour un ordre de vente)
Lots, le nombre de lots concerné
Ask, au cours actuel (Bid si on vend)
Slippage, (avec une déviation du cours maxi, du nombre indiqué dans slippage dans la définition des variables, voir le début)
Ask-ATRSL*iATR(Symbol(),PERIOD_D1,14,0), avec un stoploss qui est du cours actuel moins ATR*ATRSL que l’on a défini au début
Ask+ATRTP*iATR(Symbol(),PERIOD_D1,14,0), avec un takeprofit qui est du cours actuel plus ATR*ATRTP que l’on a défini au début
“LogicalTrend”, sera mis en commentaire de l’ordre passé
Magic, numéro défini au début qui permet au robot de retrouver ses propres ordres, et de les distinguer de ceux d’autres robots ou d’autres autres manuels
Blue); couleur du signal d’achat sur le graph
Ensuite, nous définissons exactement l’inverse, pour trader en tendance baissière:
if (iHigh(Symbol(),PERIOD_D1,0) < iHigh(Symbol(),PERIOD_D1,1) &&iHigh(Symbol(),PERIOD_D1,0)>iOpen(Symbol(),PERIOD_D1,0) &&Close[0] < iOpen(Symbol(),PERIOD_D1,0) &&iMA(Symbol(),PERIOD_D1,MAPeriode,0,MODE_SMMA,PRICE_MEDIAN,0) < iMA(Symbol(),PERIOD_D1,MAPeriode,0,MODE_SMMA,PRICE_MEDIAN,1) &&OrdersTotal()<1)
{
Lots=AccountEquity()/Close[0]/CapitalInitial*10/100 / (AccountEquity()/1000);
if(Lots<0.1||AccountEquity()<CapitalInitial)Lots=0.1;
OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage, Bid+ATRSL*iATR(Symbol(),PERIOD_D1,14,0), Bid-ATRTP*iATR(Symbol(), PERIOD_D1,14,0), “LogicalTrend”, Magic,Red);
}}
Voilà pour le programme principal.
Il nous resta à voir ce qu’il se passe lorsque l’on fait appel à la fonction de breakeven:
void OrdersList()
{
for (int cnt=0;cnt<OrdersTotal();cnt++) il passera en revue tous les ordres en cours, du premier numéro au dernier
{
OrderSelect(cnt, SELECT_BY_POS); il sélectionne l’ordre de la position numéro cnt étudiée
if (OrderSymbol()==Symbol()&&OrderMagicNumber()==Magic) on vérifie que l’ordre soit bien sur la paire actuelle et que le magic number soit bien celui de notre robot
{
Et ensuite, la gestion du breakeven à proprement parler:
if (OrderType()==OP_BUY) si c’est un ordre d’achat
{
//—- BreakEven
if (Bid-OrderOpenPrice() > ATRSL*iATR(Symbol(),PERIOD_D1,14,0) &&OrderStopLoss()!=OrderOpenPrice())
Si le cours actuel-le prix d’entrée est supérieur à notre seuil de breakeven et que le breakeven n’as pas déjà été mis (stoploss différent du prix d’entrée)
{
OrderModify(OrderTicket(),OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), 0, LightGreen);
On modifie ici le stoploss de l’ordre en cours, en mettant comme stoploss le cours d’ouverture
return(0);
}
}
On fait exactement la même chose à l’inverse dans le cas où notre ordre est un ordre de vente:
if (OrderType()==OP_SELL)
{
//—- BreakEven
if (OrderOpenPrice()-Ask > ATRSL*iATR(Symbol(),PERIOD_D1,14,0) &&OrderStopLoss()!=OrderOpenPrice())
{
OrderModify(OrderTicket(),OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), 0, Yellow);
return(0);
}
}
Voilà, vous pouvez vous amuser à modifier ce robot, l’optimiser, il est totalement gratuit. Merci de juste laisser l’entête indiquant sa provenance.
N’hésitez pas à envoyer vos propres modifs, pour les partager.
Comme d’habitude, ce robot est distribué à titre d’exemple, aussi, l’usage que vous pouvez en faire est votre propre responsabilité.
En aucun cas, la responsabilité du site ou de l’auteur de ce robot ne peut être mis en cause.
Si vous avez apprécié cet article, s'il vous plait, prenez le temps de laisser un commentaire ou de souscrire au flux afin de recevoir les futurs articles directement dans votre lecteur de flux.
Commentaires
Bonjour Chris,
Existe t’il un moyen de programmer un robot de ce type sur pro real time sur du sdr.
Merci
La stratégie n’est pas liée au programme. Donc oui.
Mais l’important ici est la programmation sur MT4, pas la stratégie en elle-même
Le principe semble assez simple. On rentre les conditions comme dans n’importe backtest. Il faut juste maitriser le langage. Je crois que du C++. Si vous avez plus d’informations sur ce langage, je suis preneur.
Cordialement
alors, je ne connais pas c++, mais effectivement, d’après ce qu’on m’a dit, ca y ressemble beaucoup.
pour plus d’infos sur le langage, le mieux est d’utiliser la bibliothèque fournie avec l’éditeur MT4 (très rapide)
Bonjour Giroud et Chris,
Non ce n’est pas du tout du C++, mais plutôt du C car ce n’est pas un langage orienté objet. MQL5 se rapproche plus du C++ par contre.
Cordialement
encore bravo Chris, du super travail tu nous donnes vraiment
envie de nous accrocher dans la programmation et la mise au
point de robots.je ne connais que le language de PRT mais
avec ton site je vais vraiment m’y mettre
Merci encore pour ce “tuto” chris !! j’y vois un peut plus clair mais c’est encore obscure quand même. Par exemple koment appliquer cette strat sur une moyenne de hull??
Chris, je n’ai pas MT4 mais juste PRT. Dans ce topic, le concept de la MM variat avec l’ATR m’a bien séduit. Cependant, je n’arrive pas à comprendre comment tu fais cette moyenne, car je ne maitrise pas du tout le langage MT4. Un petit coup de main serait le bienvenu!
En effet, tu précises “On utilise ici 1/ATR que l’on divise par notre MARatio que l’on arrondi pour trouver notre pérdioe de moyenne mobile”, mais 1/ATR/5.5 cela fait moins de 1 me semble t il, donc la MM est une MM0.
Qu’ai je donc raté?
2 exemples avec ATR=0,0037 et ATR=0,0353:
1/0,0037/5,5=49 et quelques, soit quasi une MM49
1/0,0353/5,5=5 et quelques, soit quasi une MM5
plus la volatilité est forte, plus on a besoin d’une moyenne courte, plus la volatilité est faible, plus on a besoin d’une moyenne mobile longue.
Merci Chris, je viens de comprendre… je ne suis pas forexien! Je regarde les actions, les indices et les futures. C’est bête, ma question était stupide!
En tout cas, cette moyenne variable est une super idée!
Salut Chris,
Je viens de tester la source que tu as mis en ligne. Elle produit une division par zéro. Message zero divide dans le journale d’éxecution. J’ai lancé le testeur avec le modèle ‘chaque tic’. Les barres que j’ai sont des H4.
Tu a rencontré l’erreur ?
Cordialement
Bonsoir
Je vient de copier Logical Trend dans la MT4
Je ne comprend pas comment le lancer je fais comme pour magic trend ou d’autres indicateurs.mais la il ne se passe rien ?
Comment exécuter ce programme ?
Merci pour tout le travail fourni su ce site
Cordialement
M Granie
Re bonsoir
Jais mi en place Logical Trend et je voudrais savoir s’il est possible de le faire fonctioner en bougie 1 ou 5 minutes
Bonsoir Chris
Je suis les cours avec les indicateur que tu à fabriquer le formidable Magic trend etmon premier system de trading + celui de Belkhayate aussi le tout sur Meta trader
Les trois systeme fonctionne bien
Mais dans la journé pas toujours possible de suivre !
ma question est de savoir
si par la suite il serait possible d’avoir un ROBOT basé sur Magic Trend ?
J’essais de programmer mais sa ne fonctionne pas encore et ton aide serait la bien venu
Encore Merci pour tous le Travail fourni
Cordialement
M Granie
Bonjour,j’ai testé cet expert.
Et j’ai beaucoup de message d’erreur avec FXPRO!
Message ” Ordermodify Error 1
Test fait sur plusieurs paires.Malgré tout j’obtiens un graphe et une modélisation très bonne!
C’est un problème d’écart de prix?
Bonsoir Chris
J’ai testé ce ROBOT.
J’obtiens bien un graphe ,mais j’ai un nombre très important de message erreur dans le journal du testeur!
J’utilise FXPRO.
message ordermodify error 1
Pourrait tu m’aider?
Bonjour
Je teste le robot sur france 40 et jais des résultats négatif
Comment faire pour optimiser les résultat ?
Les réglages de bases à modifier ?
Merci encore pour tout
M Granie





Super article!
Décidément je vais devoir me mettre à MT4…:-)