Comprendre le placement des ordres dans MQL5
Introduction
Dans tout système de trading, nous devons traiter les ordres et leurs opérations telles que l'ouverture de positions, le placement de stop-loss et la prise de bénéfices, ainsi que la modification d'ordres. Il est donc très important de comprendre comment gérer les opérations d'ordre dans mql5 lors de la création d'un système de trading pour MetaTrader5. L'objectif de cet article est de vous fournir des indications simples sur la plupart des opérations d'ordre et de position afin de vous permettre de traiter efficacement tous les aspects de ce sujet. Dans cet article, nous aborderons les sujets suivants :
- Ordres, positions et conditions de transaction
- OrderSend()
- Application OrderSend()
- Classe CTrade
- Application de la classe CTrade
- Conclusion
J'espère que cet article vous sera utile pour développer votre système de trading MetaTrader5 en douceur en ce qui concerne le placement d'ordres. Toutes les applications présentées dans cet article doivent être testées avant d'être utilisées afin de s'assurer qu'elles sont rentables ou qu'elles conviennent à votre activité de trading, car l'objectif principal de leur mention est de donner un exemple de création d'un système de trading utilisant deux méthodes différentes pour travailler avec les opérations d'ordre, de transaction et de position.
Termes relatifs aux ordres, aux positions et aux transactions
Dans cette partie, nous parlerons des termes importants pour comprendre comment traiter les ordres de manière efficace. Nous allons comprendre les différences entre trois termes liés aux ordres dans MetaTrader 5. Ces termes sont l'ordre, la transaction et la position, que l'on peut considérer comme les étapes de l'exécution de la transaction.
Ordre : il s'agit d'une demande/requête reçue par le serveur de trading d'ouvrir une transaction d'achat ou de vente avec un lot ou un volume spécifique à un prix spécifique. Il existe 2 types d'ordres, l'ordre au marché et l'ordre en attente.
- Ordre au marché : ordre qui peut être exécuté immédiatement au prix courant du marché.
- Ordre en attente : un ordre qui exécute la transaction à des conditions prédéterminées concernant le prix pour exécuter la transaction à son niveau et le moment pour exécuter la transaction.
Ces ordres en attente peuvent être l'un des suivants :
- Buy Stop : un ordre d'achat en attente à un prix spécifique supérieur au prix actuel du marché.
- Buy Limit : un ordre d'achat en attente à un prix spécifique inférieur au prix actuel du marché.
- Sell Stop : un ordre de vente en attente à un prix spécifique qui est inférieur au prix actuel sur le marché.
- Sell Limit : un ordre de vente en attente à un prix spécifique supérieur au prix actuel du marché.
Une fois l'ordre placé, qu'il s'agisse d'un ordre au marché ou d'un ordre en attente, il peut être trouvé dans l'onglet Trade de la fenêtre Boîte à Outils de MetaTrader 5. Voici un exemple :

Lorsque l'ordre est clôturé ou annulé sans être exécuté, nous pouvons le retrouver dans l'onglet Historique de la fenêtre Boîte à Outils.

Lorsque nous voulons modifier une position courante par MQL5, nous devons traiter ces ordres de la même manière que nous le ferons plus tard lors de la modification des ordres.
Transaction : Il s'agit du résultat lorsque l'ordre de transaction est exécuté ou rempli. Il s'agit d'actions d'entrée et de sortie basées sur l'exécution de la transaction. Supposons qu'un ordre d'achat d'1 lot soit exécuté. Ensuite, nous avons clôturé une partie de la position, soit 0,5 lot, puis nous avons clôturé les 0,5 lots restants. Les transactions seront donc les suivantes :
- 1 achat
- 0,5 vente
- 0,5 vente
Nous pouvons trouver ces transactions dans l'onglet Historique de la boîte à outils de MetaTrader 5 en faisant apparaître les données des transactions avec clic droit et en les sélectionnant.

Position : Il s'agit du résultat net des transactions longues ou courtes basées sur l'achat ou la vente d'un actif financier. Nous pouvons la trouver dans l'onglet Trade en tant que transaction active ou dans l'onglet Historique si nous choisissons d'afficher les positions.

Il est bon de mentionner que le prix exécutable de l'ordre d'achat est le cours vendeur, et que le prix exécutable lors de la clôture est le cours acheteur. En revanche, le prix exécutable de l'ordre de vente est le cours acheteur et le prix exécutable lors de la clôture est le cours vendeur.
OrderSend()
Après avoir compris les termes importants concernant l'exécution des transactions dans MetaTrader 5, nous devons apprendre comment exécuter les ordres automatiquement dans MQL5. Tout d'abord, vous pouvez consulter les Fonctions de Trading dans la référence MQL5 pour plus d'informations sur les fonctions destinées à la gestion des activités.
Nous examinerons la fonction OrderSend(), qui peut être utilisée pour exécuter des opérations de trading en envoyant des demandes (ou requêtes) à un serveur de trading. En d'autres termes, elle peut être utilisée pour placer, modifier et clôturer des ordres.
Le format de cette fonction est le suivant :
bool OrderSend( MqlTradeRequest& request, MqlTradeResult& result );
Comme nous pouvons le voir, la fonction a 2 paramètres :
- Structure MqlTradeRequest : elle contient les paramètres de l'ordre et tous les champs ou variables nécessaires pour effectuer les transactions de trading. Objets transmis par référence avec le caractère &. La variable TradeRequest permet l'interaction entre le terminal du client et le serveur de trading pour l'exécution des ordres.
- Structure MqlTradeResult: La variable de type TradeResult renvoie les résultats de la demande d'ordre. Elle est passée par référence également.
La structure MqlTradeRequest :
La structure est un ensemble de données connexes de différents types. La définition de la structure MqlTradeRequest est la suivante :
struct MqlTradeRequest { ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type ulong magic; // Expert Advisor ID (magic number) ulong order; // Order ticket string symbol; // Trade symbol double volume; // Requested volume for a deal in lots double price; // Price double stoplimit; // StopLimit level of the order double sl; // Stop Loss level of the order double tp; // Take Profit level of the order ulong deviation; // Maximal possible deviation from the requested price ENUM_ORDER_TYPE type; // Order type ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type ENUM_ORDER_TYPE_TIME type_time; // Order expiration type datetime expiration; // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type) string comment; // Order comment ulong position; // Position ticket ulong position_by; // The ticket of an opposite position };
Nous pouvons déclarer un objet MqlTradeRequest comme suit :
MqlTradeRequest request; Ensuite, nous pouvons affecter les paramètres de trading aux variables de l'objet requête créé en ajoutant un point (.) après l'objet, comme dans l'exemple suivant :
request.symbol = _Symbol; request.volume = 0.01; request.type = ORDER_TYPE_BUY;
Voici une liste de tous les membres ou variables de la structure MqlTradeRequest, ainsi que les valeurs acceptées :
| Variable | Description | Valeur acceptée pour l'affectation |
|---|---|---|
| action | Représente le type de l'opération de trading | Une valeur de ENUM_TRADE_REQUEST_ACTIONS (TRADE_ACTION_DEAL, TRADE_ACTION_PENDING, TRADE_ACTION_SLTP, TRADE_ACTION_MODIFY, TRADE_ACTION_REMOVE, TRADE_ACTION_CLOSE_BY) |
| magic | Il s'agit de l'identifiant de l’Expert Advisor permettant d'identifier les ordres passés par un certain Expert Advisor | Valeur de type ulong |
| order | Représente le ticket de l’ordre. Il est requis lors de l'utilisation de TRADE_ACTION_MODIFY ou TRADE_ACTION_REMOVE dans la variable d'action. | Valeur de type ulong |
| symbol | Le symbole spécifié ou l'instrument à négocier. _SYMBOL fait référence au symbole actuel. | Tout symbole de type chaîne de caractères |
| volume | Précise le volume d'échange ou les lots | Valeur de type double |
| price | Le prix d'ouverture | Valeur de type double |
| stoplimit | Le prix d'ouverture de l'ordre à cours limité en attente. L'action doit être de type TRADE_ACTION_PENDING et la variable type doit être ORDER_TYPE_BUY_STOP_LIMIT ou ORDER_TYPE_SELL_STOP_LIMIT. Elle est nécessaire pour les ordres stop limit. | Valeur de type double |
| sl | Le prix du stop loss de la transaction | Valeur de type double |
| tp | Le prix du take profit de la transaction | Valeur de type double |
| deviation | L'écart de prix maximal en points | Valeur de type ulong |
| type | Le type de l’ordre | Une valeur de ENUM_ORDER_TYPE (ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP, ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT, ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT) |
| type_filling | Type d'exécution de l'ordre ou politique de remplissage de l'ordre | Une valeur de ENUM_ORDER_TYPE_FILLING (ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_BOC, ORDER_FILLING_RETURN) |
| type_time | Le type d'expiration de l'ordre en attente | Une valeur de ENUM_ORDER_TYPE_TIME (ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY) |
| expiration | L'heure d'expiration de l'ordre en attente. Il est requis lorsque le type_time est ORDER_TIME_SPECIFIED | Valeur de type datetime |
| comment | Le commentaire de l’ordre | Valeur de type string |
| position | Le ticket d’une position existante Elle est requise lorsqu'une position est modifiée ou fermée afin de l'identifier | Valeur de type ulong |
| position_by | Le ticket d'une position opposée Il est utilisé lorsque la position est fermée par une position ouverte opposée dans la direction opposée pour le même symbole. | Valeur de type ulong |
Nous allons maintenant mentionner quelques actions importantes que nous devons utiliser lorsque nous passons des ordres dans MQL5 :
- Ordre au marché
- Ajout d'un stop-loss et d'un take-profit
- Ordre en attente
- Modification d’un ordre en attente
- Suppression d’un ordre en attente
Ordre au Marché :
Dans ce type d'action, nous devons placer un ordre au marché, ce qui signifie que l'ordre sera placé au prix actuel du marché, nous utiliserons l'actionTRADE_ACTION_DEAL. S'il s'agit d'un ordre d'achat, l'ordre sera placé au cours vendeur actuel ou s'il s'agit d'un ordre de vente, l'ordre sera placé au cours acheteur actuel. Voici comment procéder :
Après avoir déclaré les objets MqlTradeRequest et MqlTradeResult, nous pouvons attribuer les valeurs suivantes aux variables :
request.action = TRADE_ACTION_DEAL; &nbsthe p; //market order palcement request.type = ORDER_TYPE_BUY; //type of order is buy request.symbol = _Symbol; //applied for the cuurrent symbol request.volume = 0.1; //the lot size request.type_filling = ORDER_FILLING_FOK; //the filling policy fill or kill request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); //the price is the current ask for buy request.sl = 0; //stop loss is 0 request.tp = 0; //take profit is 0 request.deviation = 50; //slippage is 50 OrderSend(request, result); //calling the OrderSend function
Comme nous pouvons le voir dans le code précédent, nous n'avons pas ajouté de valeurs de stop loss et de take profit. Nous pouvons ajouter leurs valeurs au code avec les autres variables, ou nous pouvons les ajouter par le biais d'une autre action, comme nous le verrons dans le point suivant.
Nous pouvons ajouter leurs valeurs au code avec les autres variables, ou nous pouvons les ajouter par le biais d'une autre action, comme nous le verrons dans le point suivant.
Ajout d'un stop-loss et d'un take-profit :
request.action = TRADE_ACTION_SLTP; //adding sl and tp request.symbol = _Symbol; //applied for the cuurrent symbol request.sl = 1.07000; //sl price request.sl = 1.09000; //tp price OrderSend(request, result); //calling the OrderSend function
Lorsque nous devons ajouter un stop-loss et un take-profit, nous attribuons la variable TRADE_ACTION_SLTP à la variable action, comme dans l'exemple suivant.
Ordre en attente : Si nous voulons placer un ordre en attente, nous pouvons utiliser l’action TRADE_ACTION_PENDING. Nous déterminons ensuite le type de l’ordre :
request.action = TRADE_ACTION_PENDING; //pending order placement request.type = ORDER_TYPE_BUY_STOP; //type of order is buy stop request.symbol = _Symbol; //applied for the cuurrent symbol request.volume = 0.1; //the lot size request.price = 1.07000; //opening price request.sl = 1.06950; //stop loss request.tp = 1.07100; //take profit request.type_time = ORDER_TIME_SPECIFIED; //to set an expiration time request.expiration = D'2023.08.31 00.00'; //expiration time - datetime constant request.type_filling = ORDER_FILLING_FOK; //the filling policy fill or kill request.stoplimit = 0; //for stoplimit order only OrderSend(request, result); //calling the OrderSend function
Nous pouvons définir l'heure si nous avons besoin d'un délai d'expiration pour l'ordre en attente.
Modification d’un ordre en attente : Si nous devons modifier un ordre en attente, nous devons obtenir le numéro de ticket de l'ordre en attente que nous devons modifier. Nous pouvons utiliser la fonction OrderGetTicket pour obtenir le ticket de l’ordre.
ulong OrderGetTicket( int index // Number in the list of orders );
Cette fonction renvoie le ticket de l'ordre correspondant, que nous pouvons utiliser pour sélectionner l'ordre et travailler avec lui. Considérons que nous avons une variable nommée ’ticket’ qui contient le numéro du ticket de l’ordre. Nous pouvons utiliser cette variable pour attribuer le numéro de ticket de l’ordre à la variable order de l'objet request :
request.action = TRADE_ACTION_MODIFY; //pending order modyfying request.order = ticket; //ticket variable that holds the pending order ticket to modify request.price = 1.07050; //new opening price request.sl = 1.07000; //new stop loss request.tp = 1.07150; //new take profit request.type_time = ORDER_TIME_SPECIFIED; //to set an expiration time request.expiration = D'2023.09.01 00.00'; //new expiration time - datetime constant OrderSend(request, result); //calling the OrderSend function
Nous pouvons alors modifier l'ordre à l'aide de l'action TRADE_ACTION_MODIFY, comme dans l'exemple suivant.
Suppression d’un ordre en attente : Si nous devons supprimer un ordre en attente, nous pouvons le faire en utilisant l'action TRADE_ACTION_REMOVE. Nous avons également besoin du numéro de ticket de l’ordre en attente que nous devons supprimer.
request.action = TRADE_ACTION_REMOVE; //pending order remove request.order = ticket; //ticket variable that holds the pending order ticket to remove OrderSend(request, result); //calling the OrderSend function
Nous pouvons utiliser la variable ticket en supposant qu'elle contient le numéro de ticket nécessaire.
La structure MqlTradeResult : La structure MqlTradeResult renvoie le résultat de la réussite ou de l'échec de l'ordre lorsqu'un ordre a été passé par la fonction OrderSend().
Elle contient des informations sur les transactions provenant du serveur de transactions, telles que le numéro de ticket, le volume et le prix.
struct MqlTradeResult { uint retcode; // Operation return code ulong deal; // Deal ticket, if it is performed ulong order; // Order ticket, if it is placed double volume; // Deal volume, confirmed by broker double price; // Deal price, confirmed by broker double bid; // Current Bid price double ask; // Current Ask price string comment; // Broker comment to operation (by default it is filled by description of trade server return code) uint request_id; // Request ID set by the terminal during the dispatch int retcode_external; // Return code of an external trading system };
Voici la définition de la structure MqlTradeResult :
MqlTradeResult result; Nous pouvons déclarer un objet nommé ’result’ pour le passer comme 2ème paramètre après le premier (request) à l'appel de la fonction OrderSend().
Comme nous pouvons le voir dans les variables de la structure MqlTradeResult, la variable retcode est très importante car elle renvoie le code du serveur de trading pour indiquer si la demande a abouti ou non. Si la transaction n'est pas placée, le code de retour indique un état d'erreur. Vous pouvez consulter la liste des codes de retour dans la référence MQL5 pour plus d'informations.
if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED) { Print("Trade Placed Successfully"); } else { Print("Trade Not Placed, Error ", result.retcode); }
Il est essentiel d'inclure un code dans notre système de trading pour signaler si une erreur a été renvoyée ou non, comme dans l'exemple suivant : Comme nous pouvons le voir dans le code précédent, un message sera imprimé avec le résultat après la requête et remplira les variables de résultat.
Si la transaction a été effectuée, un message nous l'indique. En cas de problème, un message d'erreur s'imprime et le code d'erreur est renvoyé pour nous aider à résoudre le problème.
Application OrderSend() Nous devons créer un système de trading simple capable d'exécuter des transactions à l'aide de la fonction OrderSend().
Le système de trading que nous devons créer est un simple croisement de moyenne mobile et l'action consiste à placer un ordre de marché uniquement. L'objectif est ici de comprendre les différences entre la création d'un même système de trading en utilisant la classe OrderSend() et la classe CTrade.
Les étapes suivantes permettent de créer ce croisement de MA à l'aide de la fonction OrderSend().
int simpleMA; int barsTotal;
Dans le champ d'application global, créez 2 variables entières (simpleMA, barsTotal) sans affectation ; elles seront affectées plus tard dans la partie OnInit. simpleMA sera assignée à la fonction iMA qui renvoie le handle de l'indicateur technique de la moyenne mobile.
- Ses paramètres sont : symbol :
- pour spécifier le nom du symbole, _Symbol fait référence à l'instrument actuel. period :
- pour spécifier la période de temps, nous utiliserons PERIOD_H1 qui fait référence à une période d’1 heure.
- ma_period : la période de la moyenne mobile, nous utilisons 50.
- ma_shift : pour spécifier le décalage horizontal nécessaire. ma_method :
- pour spécifier le type de moyenne mobile, nous allons spécifier la moyenne simple. applied_price :
pour spécifier le type de prix qui sera utilisé dans le calcul de la MA, nous utiliserons le prix de clôture. Le total des barres sera affecté à la fonction iBars qui renvoie le nombre de barres.
- symbol : le nom du symbole
- le nom du symbole
simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,PERIOD_H1);
timeframe : la période de temps
MqlRates priceArray[]; double mySMAArray[];
Dans la partie OnTick, nous allons créer 2 tableaux : l'un pour le prix en utilisant le type MqlRates qui stocke des informations sur le prix, le volume et l'écart, et l'autre pour la moyenne mobile en utilisant le type de variable double.
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
Définition des prix de vente et d'achat
ZeroMemory(request); Création de 2 objets pour la fonction OrderSend() : l'un pour la demande en utilisant MqlTradeRequest et l'autre pour le résultat en utilisant MqlTradeResult, puis réinitialisation de la variable de demande par référence. L'utilisation de la fonction ArraySetAsSeries permet d'attribuer l'indicateur AS_SERIES à ces deux tableaux créés, priceArray et mySMAArray.
- Ses paramètres sont : array[] :
- pour spécifier le tableau nécessaire flag :
ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true);
le sens d'indexation du tableau. Obtention des données historiques de MqlRates en utilisant la fonction CopyRates.
- symbol : le nom du symbole ou _Symbol pour le symbole ou l'instrument actuel.
- symbol : le nom du symbole ou _Symbol pour le symbole ou l'instrument actuel.
- time frame : période de temps ou _period pour la période actuelle.
- start position : la position de départ.
- count : le nombre de données à copier.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
rates_array : le tableau cible à copier. Obtention du buffer de données de l'indicateur à l'aide de la fonction CopyBuffer.
- indicator_handle : indicator_handle :
- pour spécifier la poignée de l'indicateur MA. buffer_num :
- Pour spécifier le numéro du buffer tampon de l'indicateur.
- start_pos : la position de départ.
- count : quantité d’éléments à copier.
CopyBuffer(simpleMA,0,0,3,mySMAArray);
buffer[] : le tableau cible.
double lastClose=(priceArray[1].close); double prevClose=(priceArray[2].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
Définition des derniers prix de clôture, des prix de clôture précédents, des dernières valeurs SMA et des valeurs SMA précédentes
int bars=iBars(_Symbol,PERIOD_H1);
Création d’une variable entière bars et elle est assigné à la variable iBars
if(barsTotal != bars) Vérification des barres, si barsTotal n'est pas égal à la variable bars
barsTotal=bars;
Mise à jour de la valeur barsTotal pour qu'elle soit égale à celle des barres si elles ne sont pas égales entre elles
if(prevClose<prevSMAVal && lastClose>SMAVal) Vérification de la condition de la stratégie pour ouvrir une transaction : si la dernière clôture est supérieure à la dernière valeur SMA après que la clôture précédente ait été inférieure à la valeur SMA précédente.
request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_BUY; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); request.sl = Ask-(500*_Point); request.tp = Ask+(1000*_Point); request.deviation = 50; OrderSend(request, result);
Ouverture d'un ordre d'achat sur le marché en utilisant les variables appropriées liées à la fonction MqlTradeRequest
if(prevClose>prevSMAVal && lastClose<SMAVal)Vérification de la condition de la stratégie d'ouverture d'une transaction de vente : si la dernière clôture est inférieure à la dernière valeur SMA après que la clôture précédente ait été supérieure à la valeur SMA précédente. request.type = ORDER_TYPE_SELL; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID); request.sl = Bid+(500*_Point); request.tp = Bid-(1000*_Point); request.deviation = 50; OrderSend(request, result);
Ouverture d'un ordre de vente sur le marché à l'aide de variables appropriées liées à la fonction MqlTradeRequest
//+------------------------------------------------------------------+ //| OrderSend_Trading_system.mq5 | //+------------------------------------------------------------------+ int simpleMA; int barsTotal; int OnInit() { simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,PERIOD_H1); return(INIT_SUCCEEDED); } void OnTick() { MqlRates priceArray[]; double mySMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true); int Data=CopyRates(_Symbol,_Period,0,3,priceArray); CopyBuffer(simpleMA,0,0,3,mySMAArray); double lastClose=(priceArray[1].close); double prevClose=(priceArray[2].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits); int bars=iBars(_Symbol,PERIOD_H1); if(barsTotal != bars) { barsTotal=bars; if(prevClose<prevSMAVal && lastClose>SMAVal) { request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_BUY; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); request.sl = Ask-(500*_Point); request.tp = Ask+(1000*_Point); request.deviation = 50; OrderSend(request, result); } if(prevClose>prevSMAVal && lastClose<SMAVal) { request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_SELL; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID); request.sl = Bid+(500*_Point); request.tp = Bid-(1000*_Point); request.deviation = 50; OrderSend(request, result); } } }
Voici le code complet en un seul bloc pour créer ce type de système de trading à l'aide de la fonction OrderSend()
Après avoir appris comment passer des ordres avec la fonction OrderSend(), nous disposons d'une méthode simple pour accéder aux fonctions de trading. Après avoir appris comment passer des ordres avec la fonction OrderSend(), nous disposons d'une méthode simple pour accéder aux fonctions de trading. Nous pouvons utiliser la classe CTrade prête à l'emploi fournie par MQL5, ou nous pouvons créer notre propre classe pour des préférences plus personnelles. Nous allons maintenant mentionner comment utiliser la classe CTrade prête à l’emploi dans MQL5.
Vous pouvez consulter la classe CTrade dans la référence MQL5 pour plus d'informations. Tout d'abord, nous incluons le fichier de la classe CTrade du dossier Trade dans les fichiers d'installation de MetaTrader 5.
#include <Trade\Trade.mqh> Tout ce dont nous avons besoin est d'inclure ce fichier dans l’Expert Advisor pour appeler et utiliser toutes les fonctions de trading de la manière suivante :
CTrade trade;
Créer un objet à partir de la classe CTrade Après cela, nous serons en mesure d'utiliser toutes les fonctions de trading de la classe CTrade en utilisant trade avant le point (.) et la fonction souhaitée.
Nous pouvons utiliser toutes les fonctions des opérations avec les ordres, des opérations avec les positions, l'accès aux paramètres de la dernière demande, l'accès aux résultats de la vérification de la dernière demande, l'accès aux résultats de l'exécution de la dernière demande, et d'autres encore. Nous mentionnerons quelques fonctions importantes de la même manière que pour OrderSend() afin de comprendre les différences entre les deux méthodes.
- Nous comprendrons comment procéder :
- Ajout d'un stop-loss et d'un take-profit
- Ordre en attente
- Modification d’un ordre en attente
- Suppression d’un ordre en attente
Ordre au marché :
Ordre au marché :
- Après avoir créé notre objet de transaction, nous pouvons utiliser la fonction PositionOpen pour placer un ordre au marché :
- symbol : pour spécifier le symbole nécessaire
- order_type : pour spécifier le type d'ordre pour ouvrir une position
- volume : pour spécifier la taille du lot
- price : pour spécifier le prix d'ouverture de la position
- sl : pour spécifier le prix du stop loss
- tp : pour spécifier le prix du take profit
comment : pour spécifier un commentaire ou NULL
trade.PositionOpen( _Symbol, //to be applied for the current symbol ORDER_TYPE_BUY, //to place buy order 0.1, //lot size or volume Ask, //opening price of the order - current ask Ask-(500*_Point), //sl Ask+(1000*_Point), //tp NULL //NULL );
Voici un exemple :
Nous pouvons également utiliser les méthodes supplémentaires de CTrade telles que Buy, Sell au lieu de PositionOpen pour ouvrir un ordre au marché.
Nous pouvons modifier la position par le symbole ou par le numéro de ticket à l'aide de la fonction PositionModify. Nous pouvons modifier la position par le symbole ou par le numéro de ticket à l'aide de la fonction PositionModify.
- symbol ou ticket : pour spécifier la position à modifier - si l'on modifie par le symbole, on spécifiera le nom du symbole, et si l'on modifie par le ticket, on spécifiera le numéro du ticket.
- symbol ou ticket : pour spécifier la position à modifier - si l'on modifie par le symbole, on spécifiera le nom du symbole, et si l'on modifie par le ticket, on spécifiera le numéro du ticket.
- sl : le nouveau prix du stop loss
tp : le nouveau prix du take profit
trade.PositionModify( EURUSD, //the symbol name 1.06950, //the new sl 1.07100, //the new tp );
Exemple de modification par le symbole :
trade.PositionModify( ticket, //the ticket variable that holds the needed ticket number to modify 1.06950, //the new sl 1.07100, //the new tp );
Exemple de modification par le ticket :
Si nous devons placer un ordre en attente à l'aide de la classe CTrade, nous pouvons utiliser la fonction OrderOpen. Si nous devons placer un ordre en attente à l'aide de la classe CTrade, nous pouvons utiliser la fonction OrderOpen.
- symbol : détermine le nom du symbole
- symbol : détermine le nom du symbole
- order_type : pour déterminer le type d'ordre en attente
- volume : pour spécifier la taille du lot
- limit_price : pour spécifier le prix stop limit
- price : pour spécifier le prix d'exécution de l'ordre en attente
- sl : pour spécifier le stop loss
- tp : pour spécifier le take profit
- type_time : pour spécifier le type par expiration
- expiration : pour spécifier la date d'expiration
comment : pour spécifier un commentaire si nécessaire
trade.OrderOpen( "EURUSD", // symbol ORDER_TYPE_BUY_LIMIT, // order type 0.1, // order volume 0, // StopLimit price 1.07000, // execution price 1.06950, // Stop Loss price 1.07100, // Take Profit price ORDER_TIME_SPECIFIED, // type by expiration D'2023.08.31 00.00', // expiration "" // comment );
L'exemple suivant permet de placer un ordre d'achat limite (buy limit) en attente à l'aide de la fonction OrderOpen.
Si nous devons modifier un ordre en attente placé, nous pouvons le faire en utilisant la fonction OrderModify de la classe CTrade. Si nous devons modifier un ordre en attente placé, nous pouvons le faire en utilisant la fonction OrderModify de la classe CTrade.
- ticket : pour spécifier le ticket de l’ordre en attente à modifier
- ticket : pour spécifier le ticket de l’ordre en attente à modifier
- price : le nouveau prix d'exécution
- sl : le nouveau prix du Stop Loss
- tp : le nouveau prix du Take Profit
- expiration : pour spécifier la date d'expiration
- expiration : pour spécifier la date d'expiration
stoplimit : pour déterminer le prix de l'ordre limite
trade.OrderModify( ticket, // ticket number of the pending order to modify 1.07050, // execution price 1.07000, // Stop Loss price 1.07150, // Take Profit price ORDER_TIME_SPECIFIED, // type by expiration D'2023.08.31 00.00', // expiration 0, // StopLimit price );
Voici un exemple de modification d'un ordre en attente
Suppression d’un ordre en attente : Si vous devez supprimer un ordre en attente, vous pouvez le faire en utilisant la fonction OrderDelete qui a besoin du numéro de ticket de l'ordre en attente à supprimer.
trade.OrderDelete(
ticket, // tick number of the pending order to delete
); Voici un exemple de cette fonction.
Application de la classe CTrade Nous devons créer le même système de trading que celui que nous avons créé à l'aide de la fonction OrderSend().
Nous utiliserons la classe CTrade pour comprendre les différences de fonctionnement entre ces deux classes.
Les étapes suivantes sont les seules étapes différentes pour créer ce système de trading en utilisant la classe CTrade, toutes les autres étapes sont les mêmes que celles que nous avons effectuées précédemment.
#include <Trade\Trade.mqh> Inclure le fichier Trade include en utilisant le préprocesseur #include
CTrade trade;
Créer l'objet de transaction à partir de la classe CTrade
trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
Lorsque la condition d'achat est remplie, nous pouvons utiliser PositionOpen et le type d'ordre sera ORDER_TYPE_BUY ou la méthode d'achat supplémentaire, comme dans le code suivant
trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
Lorsque la condition de vente est remplie, nous pouvons utiliser PositionOpen avec le type d'ordre ORDER_TYPE_SELL ou la méthode de vente supplémentaire, comme dans le code suivant
//+------------------------------------------------------------------+ //| CTrade_Trading_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> int simpleMA; int barsTotal; CTrade trade; int OnInit() { simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,PERIOD_H1); return(INIT_SUCCEEDED); } void OnTick() { MqlRates priceArray[]; double mySMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true); int Data=CopyRates(_Symbol,_Period,0,3,priceArray); CopyBuffer(simpleMA,0,0,3,mySMAArray); double lastClose=(priceArray[1].close); double prevClose=(priceArray[2].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits); int bars=iBars(_Symbol,PERIOD_H1); if(barsTotal != bars) { barsTotal=bars; if(prevClose<prevSMAVal && lastClose>SMAVal) { trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL); } if(prevClose>prevSMAVal && lastClose<SMAVal) { trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL); } } }
Voici le code complet permettant de créer le système de trading à l'aide de la classe CTrade :
Si vous avez terminé la lecture de cet article, vous êtes supposé avoir compris comment fonctionnent les ordres, les positions et les transactions dans MQL5. Si vous avez terminé la lecture de cet article, vous êtes supposé avoir compris comment fonctionnent les ordres, les positions et les transactions dans MQL5.
En plus de comprendre comment nous pouvons créer un système de trading en douceur en utilisant les deux méthodes d'opérations de trading, la méthode OrderSend et la méthode CTrade.
Nous avons identifié la manière dont nous plaçons les ordres de marché et les ordres en attente, dont nous ajoutons des stop-loss et des take-profit, dont nous modifions les ordres en attente et dont nous supprimons les ordres en attente à l'aide des deux méthodes.
- On suppose que vous avez compris comment appliquer tous les éléments précédents pour créer une application car nous avons fourni deux applications simples pour créer le même système de trading à moyenne mobile croisée en utilisant les deux méthodes.
- OpenSend_Trading_System
CTrade_Trading_System
L'objectif des applications est uniquement de comprendre les différences entre elles d'un point de vue pratique. Attention, vous devez les tester avant de les utiliser sur un compte réel afin de vous assurer qu'elles sont rentables et adaptées à votre activité de trading. Je pense que vous avez compris à quel point il est facile d'utiliser la classe CTrade prête à l'emploi pour travailler sur des opérations de trading, car elle permet d'économiser beaucoup de temps et d'efforts.
En plus d'autres caractéristiques lors de l'utilisation de classes dans la programmation en général. Si vous voulez en savoir plus à ce sujet et sur la programmation orientée objet dans MQL5, vous pouvez lire mon précédent article Comprendre la Programmation Orientée Objet (POO) de MQL5, j'espère qu'il vous sera utile.
MQL5 a fait beaucoup de travail et d'efforts appréciés pour nous fournir des outils permettant de développer et de créer des logiciels de trading facilement et en douceur. J'espère que cet article vous a été utile et qu'il vous a apporté de nombreuses informations utiles pour comprendre et effectuer votre travail facilement.
Traduit de l’anglais par MetaQuotes Ltd.
Article original : https://www.mql5.com/en/articles/13229
Avertissement: Tous les droits sur ces documents sont réservés par MetaQuotes Ltd. La copie ou la réimpression de ces documents, en tout ou en partie, est interdite.
Cet article a été rédigé par un utilisateur du site et reflète ses opinions personnelles. MetaQuotes Ltd n'est pas responsable de l'exactitude des informations présentées, ni des conséquences découlant de l'utilisation des solutions, stratégies ou recommandations décrites.
Passer à MQL5 Algo Forge (Partie 1) : Création du Dépôt Principal
La théorie du chaos dans le trading (1ère partie) : Introduction, application aux marchés financiers et exposant de Lyapunov
Approche quantitative de la gestion des risques : Application du modèle VaR pour optimiser un portefeuille multidevises en utilisant Python et MetaTrader 5
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation
Bonjour,
excellent texte, tyvm.
J'ai trouvé un petit bug :
dans la caseTRADE_ACTION_SLTP vous avez écrit deux fois request.sl, la deuxième devrait être request.tp, comme indiqué dans le commentaire à la fin de la ligne.
Je vous prie d'agréer, Madame, Monsieur, l'expression de mes salutations distinguées,
Gunther
Bonjour,
Merci pour votre commentaire. Vous avez raison, il s'agit d'une erreur qui sera prise en compte.
Je vous prie d'agréer, Madame, Monsieur, l'expression de mes salutations distinguées,
En utilisant votre code, j'écris un simple placement d'ordre pour un instrument !
double price = 94500 ;
double stopLoss = price - (500 * _Point) ;
double takeProfit = price + (1000 * _Point) ;
ulong ticket = trade.OrderOpen(
"SiM4", // symbole
returns GetLastError() = 0 and the order is not placed and there is no deal
Est-il nécessaire de spécifier un jeton d'accès spécial lors de la passation d'un ordre à partir du courtier ?
renvoie GetLastError() = 0, l'ordre n'est pas passé et il n'y a pas de transaction
Est-il nécessaire de spécifier un jeton d'accès spécial lorsque l'on passe un ordre à partir du courtier ?
Bonjour Abdel Maaboud,
merci pour la gentillesse avec laquelle vous avez rédigé ce tutoriel.
Ce tutoriel ne donne que le placement d'ordre. Est-ce qu'il y a un code pour fermer la position(take profit ou cut loss) dans votre article ?
Meilleures salutations,
Ahmad Juniar