
Comprendre les fonctions dans MQL5 avec des applications
Introduction
Dans le monde de la programmation, il existe un terme très populaire que l'on utilise et que l'on entend souvent en raison de son importance dans tout logiciel : les fonctions. Dans cet article, nous allons aborder cette notion en détail pour apprendre à créer des logiciels très fonctionnels et de grande qualité. Nous allons essayer de couvrir ce sujet important pour apprendre ce que sont les fonctions, pourquoi nous avons besoin d'utiliser des fonctions et comment les utiliser dans nos applications. Nous partagerons ensuite quelques fonctions simples qui peuvent être utilisées dans n'importe quel système de trading comme exemples. Les points suivants sont les idées principales que nous allons partager dans cet article pour couvrir ce sujet intéressant :
- Définition de la fonction
- Structure de la fonction
- Fonction avec arguments
- Fonction sans arguments
- Fonction avec valeurs par défaut
- Transmission des paramètres
- Opérateur return
- Fonction de type void
- Surcharge des fonctions
- Applications fonctionnelles
- Application d'alerte sur les nouvelles
- Application de calcul de la taille du lot
- Fermer toutes les applications
- Conclusion
Définition de la fonction
Dans cette partie, nous identifierons les fonctions en programmation, leurs types et les raisons pour lesquelles nous devons les utiliser. La fonction est un bloc de code déclaré par un nom explicite et significatif qui peut être utilisé dans n'importe quelle autre partie du logiciel en l'appelant à plusieurs reprises pour effectuer une tâche spécifique. Si nous avons une tâche spécifique que le logiciel doit effectuer dans plusieurs parties de notre logiciel ou dans plusieurs logiciels, nous créons une fonction ou un bloc de code pour effectuer cette tâche et l'appeler uniquement dans ces parties sans réécrire le code complet. Nous pouvons donc dire que la fonction est une méthode pour abstraire notre code sans avoir beaucoup de code désordonné, comme nous le verrons dans cet article. Il existe 2 types principaux de fonctions : les fonctions intégrées et les fonctions définies par l'utilisateur. La fonction intégrée est la fonction prête à l'emploi par le langage de programmation lui-même, tandis que la fonction définie par l'utilisateur est la fonction qui peut être créée par l'utilisateur en fonction de ses besoins ou des tâches qu'il souhaite que le logiciel accomplisse. Dans cet article, nous nous concentrerons sur les fonctions définies par l'utilisateur. Nous allons donc étudier ce type de fonction en détail afin de voir pourquoi nous devons l'utiliser, quelle est son importance ou quelles sont ses caractéristiques.
Disons que nous avons besoin que le logiciel exécute la tâche de fermer tous les ordres ouverts si le solde a atteint un drawdown maximum. Cette tâche doit être exécutée dans plusieurs parties du logiciel. Il sera préférable ici de créer une fonction et d'inclure tout le code ou la logique nécessaire pour exécuter cette tâche, puis d'appeler cette fonction dans d'autres parties. Il serait au contraire mauvais d'écrire et de répéter le même code dans plusieurs parties pour exécuter la tâche.
Si vous vous demandez pourquoi nous devons utiliser ce type de fonction, la réponse à cette question nous amènera à apprendre les caractéristiques de l'utilisation des fonctions définies par l'utilisateur :
- Application du concept DRY (Do not Repeat Yourself - Ne Vous Répétez Pas) : l'utilisation de fonctions définies par l'utilisateur nous aidera à ne pas répéter le même code encore et encore. Nous créerons à la place une fonction qui peut effectuer notre tâche une fois et l'appeler ensuite dans n'importe quelle partie du logiciel.
- Réutilisation : après avoir créé notre fonction, nous pouvons la réutiliser à tout moment.
- Application du concept "diviser pour mieux régner" : lorsque nous créons un logiciel, le code peut être complexe pour résoudre un problème. Mais si nous divisons le gros problème en petits problèmes et que nous résolvons chacun d'entre eux par des fonctions, cela peut être très utile pour atteindre notre objectif de résolution du gros problème.
- Le code est plus lisible et compréhensible : lorsque nous utilisons des fonctions, notre code devient plus lisible car il est mieux organisé grâce aux fonctions et chacun gère un problème spécifique et a une tâche spécifique.
- Application du concept d'abstraction : l'utilisation de fonctions permet d'abstraire notre code, car si nous ne les utilisons pas, nous risquons de devoir écrire plus de lignes de code qu'en utilisant des fonctions.
- Appliquer du concept d'encapsulation : lorsque nous utilisons des fonctions, cela nous permet de sécuriser et de gérer notre code et nos données davantage que si nous ne les utilisions pas.
- Améliore le processus de débogage : l'utilisation de fonctions permet d'améliorer l'exploration des erreurs et de les résoudre plus facilement.
Suivant les caractéristiques de l'utilisation des fonctions, nous pouvons facilement déterminer les avantages de l'utilisation de ces fonctions définies par l'utilisateur dans notre logiciel.
Structure de la fonction
Dans cette partie, nous allons apprendre plus de détails sur les fonctions et leurs structures. Nous allons le faire à travers les 2 étapes suivantes :
- Déclaration ou définition de fonction
- Appel de fonction
Tout d'abord, nous devons définir ou déclarer une nouvelle fonction, ce qui revient à faire quelque chose de similaire à la structure suivante :
returnedDataType functionName(param1, param2) { bodyOfFunction }
- returnedDataType : il s'agit du type de données que la fonction doit renvoyer après son exécution.
- functionName : c'est le nom de la fonction, il faut déterminer ce nom en fonction de la tâche que la fonction exécute.
- param1, param2 : ce sont les variables dont nous avons besoin si nécessaire, car il se peut que nous n'en indiquions aucune.
- bodyOfFunction : c’est tout le code qui exécutera notre tâche.
Appliquons cela à un exemple simple : créons une fonction simple pour effectuer l’addition de 2 valeurs :
//addition function // returned data type is an integer - the name of the function is add - parameters or arguments are two int variables val1 and val2 int add(int val1, int val2) { //body of function that we need the function to perform when calling it //create a result new variable to be assigned by the result of val1 and val2 addition int result = val1+val2; //Print result in the experts tab Print(result); //returning value return result; }
Après avoir défini notre fonction, nous devons passer à la deuxième étape, qui consiste à appeler la fonction. Nous pouvons le faire en appelant le nom de la fonction et en spécifiant les paramètres souhaités, conformément à notre fonction, à l'endroit voulu du code du logiciel. Pour revenir à notre exemple, si nous voulons appeler notre fonction, il faudra le faire de cette façon :
//calling our defined function by its name and specifying arguments add(5,15);
Lorsque nous l'appelons, le résultat 20 sera affiché dans l'onglet "Experts" conformément à notre fonction et aux arguments spécifiés, comme dans l'image suivante :
L'exemple précédent n'est qu'un exemple de ce que l'on peut faire en utilisant une fonction. Mais il existe de nombreuses caractéristiques disponibles que l'on peut utiliser dans les fonctions. En voici quelques-unes dans la suite de l’article.
Fonction avec arguments
Dans le dernier exemple de fonction d'addition, nous avons utilisé 2 variables entières, val1 et val2, considérées comme des arguments dans notre fonction. Ces arguments peuvent être des données de type integer, string, etc. Dans notre dernier exemple, il s'agissait de variables integer. Voici un autre exemple d'arguments de type string :
//sayHello function // returned data type is string - name of function is sayHello - parameters or arguments are two string variables greeting and name string sayHello(string greeting, string name) { //body of function that we need the function to perform when calling it //create a result new variable to be assigned by the result of greeting and name addition string result = greeting+name; //Print result in the experts tab Print(result); //returning value return result; }
Nous pouvons appeler cette fonction comme la précédente, et son résultat sera également visible de la même façon :
Les types de données peuvent également être mélangés suivant nos besoins dans la fonction. Le nombre de ces arguments peut également être différent en fonction de nos besoins.
Fonction sans arguments
La fonction peut être déclarée ou définie sans spécifier de paramètres ou d'arguments. Il suffit de donner un nom significatif à la fonction et de laisser les arguments vides, d’écrire le corps de la fonction pour qu'elle exécute la tâche, puis d'appeler la fonction sans spécifier d'arguments, comme dans le cas suivant :
//sayHello function // returned data type is a string - the name of the function is sayHello - no parameters string sayHello() { //body of the function that we need the function to perform when calling it //create a result new variable to be assigned by the result of greeting and name addition string greeting= "Hello, "; string name= "World!"; string result = greeting+name; //Print the result in the experts' tab Print(result); //returning value return result; }
Lorsque nous appelons la fonction, elle sera identique à la suivante :
sayHello();
Le résultat sera le même que celui que nous avons mentionné précédemment dans la fonction avec arguments, car le corps de la fonction est le même.
Fonction avec valeurs par défaut
Nous définissons également une fonction et donnons des valeurs initiales, ou par défaut, aux paramètres. Mais nous sommes toujours en mesure de les modifier ou de les mettre à jour avec les valeurs souhaitées.
//defining function with default values string sayHello(string greeting= "Hello, ", string name="World!") { string result = greeting+name; Print(result); return result; }
Nous pouvons ensuite appeler la fonction 2 fois pour identifier la différence entre les valeurs par défaut et les valeurs données au moment de l’appel, comme dans l'exemple suivant :
sayHello(); sayHello("Hi, ", "Developer!");
Le résultat sera le même que le suivant :
Transmission des paramètres
Nous pouvons passer des valeurs à la fonction et ces valeurs peuvent être n'importe quel type de données comme nous l'avons mentionné : int, string, array,... etc. En passant les paramètres par des valeurs, les variables originales de la fonction resteront identiques ou inchangées car nous avons transmis la valeur des paramètres à la fonction. Nous pouvons également transmettre des paramètres à la fonction par référence si nous devons mettre à jour les variables d'origine.
Voici un exemple simple pour comprendre le passage par référence :
//passing by reference void updateNums(int &val1, int &val2) { val1*=2; val2/=2; }
Nous allons ensuite créer de nouvelles variables et afficher leurs valeurs, puis appeler notre fonction avec ces nouvelles variables comme paramètres, puis afficher ses valeurs après l'appel pour voir la différence :
//new variables int firstNum = 10; int secondNum = 20; //before calling function Print("before calling: "); Print(firstNum, " - " ,secondNum, "\n"); // calling updateNums(firstNum, secondNum); // after calling Print("after calling: "); Print(firstNum, " - " ,secondNum, "\n");
Ainsi, le résultat du premier affichage sera les valeurs des nouvelles variables 10 et 20. Puis, après l'appel, les valeurs auront été mises à jour par 20 et 10, conformément au corps de la fonction. Le résultat est le même que le suivant :
Opérateur return
Si une fonction renvoie une valeur, elle doit avoir un opérateur de retour, return. Nous pouvons avoir plus d'un opérateur de retour dans la fonction en fonction de la tâche de la fonction. Mais si la fonction renvoie une valeur, elle doit avoir au moins un retour à la dernière ligne de la fonction. Cet opérateur return peut être de n'importe quel type, sauf un tableau. Si nous voulons que la fonction retourne un tableau, nous pouvons passer le tableau à la fonction par référence, comme nous l’avons mentionné précédemment.
Voici un exemple de ce que nous avons mentionné précédemment et qui comporte un opérateur de retour, return
string sayHello(string greeting= "Hello, ", string name="World!") { string result = greeting+name; Print(result); return result; }
Fonction de type void
Si une fonction ne renvoie pas de valeur, nous devons utiliser le type void, car ce type ne renvoie pas de valeur. Nous pouvons passer des paramètres à ce type de fonction, mais celle-ci n'a pas besoin d'un opérateur de retour. Voici un exemple de ce type de fonctions :
void add(int val1, int val2) { int result= val1+val2; }
Surcharge des fonctions
Dans certains cas, lorsque l'on définit des fonctions, il est nécessaire de définir plusieurs fonctions sous le même nom pour effectuer la même tâche, mais avec des paramètres différents. Par exemple, si nous avons une tâche d'addition, mais que nous devons effectuer cette addition pour deux valeurs et que nous devons effectuer la même tâche pour trois valeurs, dans ce cas, nous créons deux fonctions sous le même nom de fonction mais nous changerons les paramètres en fonction de la tâche. Cela signifie que nous avons une fonction de surcharge. La fonction de surcharge est donc une fonction qui effectue la même tâche mais avec des paramètres différents.
Ces différents paramètres peuvent être des types de données différents, des nombres du même type de données, ou les deux. Voici un exemple de fonction de surcharge ayant le même type de données, mais dont le nombre de paramètres est différent :
void overloadingFun(int val1, int val2) { int result=val1+val2; } void overloadingFun(int val1, int val2, int val3) { int result=val1+val2+val3; }
Comme nous pouvons le voir, nous avons la même fonction, mais les paramètres sont différents. Lorsque nous appelons la fonction, nous constatons que ces deux fonctions apparaissent lorsque nous tapons le nom de la fonction ; nous pouvons alors choisir celle dont nous avons besoin en fonction des détails de notre tâche. Voici un exemple de fonction de surcharge avec différents paramètres selon le type de données :
void overloadingFun(int val1, int val2) { int result=val1+val2; } void overloadingFun(string message, int val1, int val2) { int result=message+val1+val2; }
Nous pouvons également choisir la fonction dont nous avons besoin en fonction des paramètres lors de l'appel de la fonction.
Applications fonctionnelles
Dans cette partie, nous allons créer des applications simples pour lesquelles nous pouvons utiliser une fonction définie par l'utilisateur pour faciliter le processus de codage. Après avoir créé ces applications, nous pouvons les appeler dans différentes parties du logiciel ou même dans un autre logiciel en les incluant.
Application d'alerte sur les nouvelles
Nous savons tous qu'il est très risqué de trader pendant les nouvelles économiques et de nombreux professionnels conseillent même de ne pas le faire. Si vous ne savez pas ce qu'est le calendrier économique, il s'agit d'un calendrier prêt à l'emploi qui contient des nouvelles et des indicateurs macroéconomiques avec des descriptions, leur date, leur heure et leur degré d'importance, ainsi que les valeurs publiées de ces événements économiques. Il existe de nombreuses sources qui peuvent être utilisées pour obtenir ces valeurs importantes afin d'être mis à jour avec ce qui peut affecter le marché et de négocier en fonction de cela. Ce calendrier est également disponible dans le terminal de trading MetaTrader 5. Vous trouverez son onglet dans la fenêtre Boîte à Outils, et vous pourrez contrôler ce que vous souhaitez voir en termes d'importance, de devises et de pays. Il existe également des fonctions intégrées pour travailler avec le calendrier économique, vous pouvez les consulter dans la documentation de MQL5 en cliquant sur le lien suivant :
Fonctions du Calendrier Economique
Nous devons donc vérifier manuellement le calendrier économique des nouvelles pour éviter de trader pendant les nouvelles, ou créer une application qui nous alerte lorsque nous approchons des nouvelles pour arrêter de trader. Nous pouvons donc créer une fonction pour cela et l'appeler facilement. C'est ce que nous allons faire dans cette partie à travers les étapes suivantes :
Cette application sera un EA, nous créerons un type bool pour le nom de notre fonction isNewsComing dans la portée globale et ensuite nous n'ajouterons pas de paramètres.
bool isNewsComing()
Le corps de la fonction crée un tableau avec un nom de valeurs et de type MqlCalendarValue, qui seront les valeurs du communiqué de presse comme la valeur réelle par exemple.
MqlCalendarValue values[];
Nous devons définir la journée en cours en définissant l'heure de début de la journée en utilisant iTime pour retourner l'heure d'ouverture de la barre après avoir déclaré une nouvelle variable startTime de type datetime et l'heure de fin de la journée endTime, de type datetime, égale à l'heure de début définie plus le nombre de secondes de la journée en utilisant la fonction PeriodSeconds.
datetime startTime=iTime(_Symbol,PERIOD_D1,0); datetime endTime=startTime+PeriodSeconds(PERIOD_D1);
Nous devons ensuite obtenir le tableau des valeurs de tous les événements de la journée en utilisant l'heure de début et l'heure de fin définies pour déterminer l'intervalle de temps, puis nous trions par le pays et la devise actuels en utilisant la fonction CalendarValueHistory. Les paramètres sont le tableau des valeurs, l'heure de début, l'heure de fin, le pays et la devise :
CalendarValueHistory(values,startTime,endTime,NULL,NULL);
Nous allons créer une boucle sur la variable i de type int, de 0 jusqu’à ce que la valeur de i soit inférieure à la taille du tableau des valeurs, avec i incrémenté à chaque boucle :
for(int i=0; i<ArraySize(values); i++)
Le corps de la boucle for crée une variable d'événement de type MqlCalendarEvent pour les descriptions d'événements. Elle peut être utilisée dans la fonction CalendarEventById :
MqlCalendarEvent event;
Nous obtenons ensuite la description de l'événement par son ID en utilisant la fonction CalendarEventById. Ses paramètres sont event_id et l'événement.
CalendarEventById(values[i].event_id,event);
Nous créons ensuite une variable pays, de type MqlCalendarCountry pour les descriptions de pays. Elle peut être utilisée avec CalendarCountryById :
MqlCalendarCountry country;
Nous obtenons les descriptions des pays par leur ID en utilisant la fonction MqlCalendarCountry. Ses paramètres sont country_id et le pays.
CalendarCountryById(event.country_id,country);
Définissons les conditions pour filtrer les événements en fonction du symbole actuel ou de l'actualité monétaire, de l'importance moyenne ou élevée de l'actualité, et s'il y a quelque chose d'autre qui se poursuit :
if(StringFind(_Symbol,country.currency)<0) continue; if(event.importance==CALENDAR_IMPORTANCE_NONE) continue; if(event.importance==CALENDAR_IMPORTANCE_LOW) continue;
Définissons la condition sur la plage horaire de l'alerte dont nous avons besoin, à savoir 30 secondes avant l'heure de la nouvelle :
if(TimeCurrent()>=values[i].time-30*PeriodSeconds(PERIOD_M1) && TimeCurrent()<values[i].time+30*PeriodSeconds(PERIOD_M1))
Nous devons ensuite afficher un message dans l'onglet des experts avec le nom de l'événement et le texte (" is coming!"). Stop Trading...)
Print(event.name, " is coming! Stop Trading...");
La valeur retournée sera true
return true;
Si les conditions sont fausses, terminer la boucle et renvoyer false pour mettre fin à la fonction.
return false;
Ensuite, nous pouvons appeler la fonction dans la fonction OnTick. Si elle renvoie true, le message doit être affiché (« News is coming... ! »).
if(isNewsComing()) { Print("News is comming...!"); }
Maintenant, nous avons créé la fonction et nous l'avons appelée et nous pouvons l'utiliser dans n'importe quelle partie de notre logiciel selon nos besoins. Ce qui suit est le code complet en un seul bloc pour être facile à relire. Vous trouverez les fichiers de code source de toutes les applications en pièce jointe de l'article.
//+------------------------------------------------------------------+ //| News Alert Function | //+------------------------------------------------------------------+ void OnTick() { if(isNewsComing()) { Print("News is comming...!"); } } //+------------------------------------------------------------------+ bool isNewsComing() { MqlCalendarValue values[]; datetime startTime=iTime(_Symbol,PERIOD_D1,0); datetime endTime=startTime+PeriodSeconds(PERIOD_D1); CalendarValueHistory(values,startTime,endTime,NULL,NULL); for(int i=0; i<ArraySize(values); i++) { MqlCalendarEvent event; CalendarEventById(values[i].event_id,event); MqlCalendarCountry country; CalendarCountryById(event.country_id,country); if(StringFind(_Symbol,country.currency)<0) continue; if(event.importance==CALENDAR_IMPORTANCE_NONE) continue; if(event.importance==CALENDAR_IMPORTANCE_LOW) continue; if(TimeCurrent()>=values[i].time-30*PeriodSeconds(PERIOD_M1) && TimeCurrent()<values[i].time+30*PeriodSeconds(PERIOD_M1)) { Print(event.name, " is coming! Stop Trading..."); return true; } } return false; } //+------------------------------------------------------------------+
App de calcul de la taille du lot
Nous devons créer une application capable de calculer la taille de lot optimale après avoir déterminé le pourcentage de risque et la perte maximale en pips, et nous devons créer une fonction surchargée pour calculer la taille de lot optimale après avoir déterminé le pourcentage de risque, le prix d'entrée et le prix du stop loss. Nous allons créer cette application comme un script comme dans les étapes suivantes :
Créons la fonction OptimalLotSize qui retourne un double, ses deux paramètres seront le pourcentage de risque maximum maxRiskPrc, de type double, et la perte maximale en pips maxLossInPips, de type double également. La fonction sera définie comme ceci :
double OptimalLotSize(double maxRiskPrc, double maxLossInPips)
Ensuite, spécifions ce que nous devons faire pour ces paramètres. Tout d'abord, nous définissons la valeur de l'avoir du compte grâce à la fonction AccountInfoDouble qui renvoie la valeur de la propriété correspondante du compte, qui est ici l'identifiant de l'avoir du compte ENUM_ACCOUNT_INFO_DOUBLE. Et nous créons une alerte avec la valeur suivante :
double accEquity = AccountInfoDouble(ACCOUNT_EQUITY); Alert("accEquity: ", accEquity);
Définissons la taille du contrat du symbole en utilisant la fonction SymbolInfoDouble qui renvoie la propriété correspondante du symbole spécifié, avec le nom du symbole _Symbol (pour utiliser le symbole actuel) et prop_id qui sera SYMBOL_TRADE_CONTRACT_SIZE (l'une des valeurs de l’énumération ENUM_SYMBOL_INFO_DOUBLE). Après quoi, nous avons besoin d'une alerte avec cette valeur renvoyée :
double lotSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE); Alert("lotSize: ", lotSize);
Calculons la valeur du pip et obtenons une alerte avec cette valeur :
double tickValue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); Alert("tickValue: ", tickValue);
Calculons la valeur maximale de la perte à partir des fonds propres du compte défini et émettons une alerte avec cette valeur :
double maxLossDollar = accEquity * maxRiskPrc; Alert("maxLossDollar: ", maxLossDollar);
Calculons la valeur maximale dans la devise de cotation sur la base de la valeur de perte maximale calculée et renvoyons une alerte avec cette valeur :
double maxLossInQuoteCurr = maxLossDollar / tickValue; Alert("maxLossInQuoteCurr: ", maxLossInQuoteCurr);
Calculons la taille optimale du lot et renvoyons une alerte avec la valeur :
double OptimalLotSize = NormalizeDouble(maxLossInQuoteCurr / (maxLossInPips * 0.0001)/ lotSize,2); Alert("OptimalLotSize: ", OptimalLotSize);
L'opérateur return retourne OptimalLotSize sous la forme d'une valeur de type double :
return OptimalLotSize;
Ensuite, nous créerons la fonction de surcharge en passant 3 paramètres de type double pour le pourcentage de risque maximal, le prix d'entrée et le prix de la perte maximale :
double OptimalLotSize(double maxRiskPrc, double entryPrice, double stopLoss)
Définissons la perte maximale en pips comme une valeur absolue basée sur les paramètres d'entrée du prix d'entrée et du prix du stop loss puis divisé par 0,0001 :
double maxLossInPips = MathAbs(entryPrice - stopLoss)/0.0001;
L’opérateur retourné sera la fonction OptimalLotSize créée avec ses paramètres : le pourcentage de risque maximum et la perte maximum en pips.
return OptimalLotSize(maxRiskPrc,maxLossInPips);
Nous pouvons ensuite appeler l'une des deux fonctions dans la partie OnStart() en fonction de nos besoins, par exemple comme suit :
OptimalLotSize(0.01, 1.12303, 1.11920);
Voici le code complet pour créer ce type de fonction pour créer ce type d'application :
//+------------------------------------------------------------------+ //| lotSize Calc Function | //+------------------------------------------------------------------+ void OnStart() { OptimalLotSize(0.01, 1.12303, 1.11920); } //+------------------------------------------------------------------+ double OptimalLotSize(double maxRiskPrc, double maxLossInPips) { double accEquity = AccountInfoDouble(ACCOUNT_EQUITY); Alert("accEquity: ", accEquity); double lotSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE); Alert("lotSize: ", lotSize); double tickValue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); Alert("tickValue: ", tickValue); double maxLossDollar = accEquity * maxRiskPrc; Alert("maxLossDollar: ", maxLossDollar); double maxLossInQuoteCurr = maxLossDollar / tickValue; Alert("maxLossInQuoteCurr: ", maxLossInQuoteCurr); double OptimalLotSize = NormalizeDouble(maxLossInQuoteCurr / (maxLossInPips * 0.0001)/ lotSize,2); Alert("OptimalLotSize: ", OptimalLotSize); return OptimalLotSize; } //+------------------------------------------------------------------+ double OptimalLotSize(double maxRiskPrc, double entryPrice, double stopLoss) { double maxLossInPips = MathAbs(entryPrice - stopLoss)/0.0001; return OptimalLotSize(maxRiskPrc,maxLossInPips); } //+------------------------------------------------------------------+
En exécutant ce script, nous obtiendrons l'alerte suivante :
Comme dans l'application mentionnée précédemment, nous disposons de la fonction lotSizeCalc que nous pouvons utiliser et appeler facilement dans différentes parties du logiciel pour effectuer la tâche sans réécrire le code.
Fermer toutes les applications
Il s'agit ici de créer un script permettant de clôturer les ordres ouverts et les ordres en attente en créant une fonction qui peut être utilisée ou appelée dans n'importe quelle partie du logiciel pour effectuer cette tâche. Nous pouvons le faire en suivant les étapes suivantes :
Inclure la classe Trade dans le code en utilisant la directive de préprocesseur #include pour inclure toutes les fonctions de trading dans le fichier Trade.mqh :
#include <Trade/Trade.mqh>
Création d'un objet du type de la classe CTrade à utiliser dans le logiciel :
CTrade trade;
Dans le champ d'application global, nous devons également créer une fonction void closeAll sans arguments :
void closeAll()
Le corps de la fonction crée une boucle for pour vérifier les ordres en cours :
for(int i=PositionsTotal()-1; i>=0; i--)
Le corps de la boucle, qui crée une variable posTicket de type ulong et qui lui assigne le ticket des ordres ouverts :
ulong posTicket=PositionGetTicket(i);
Fermer la transaction ouverte en utilisant trade.PositionClose(posTicket) :
trade.PositionClose(posTicket);
Nous allons supprimer les ordres en attente en créant une autre boucle for pour détecter ces ordres, en assignant leurs tickets à la variable ulong de posTicket, et en supprimant l'ordre en attente par son ticket :
for(int i=OrdersTotal()-1; i>=0; i--) { ulong posTicket=OrderGetTicket(i); trade.OrderDelete(posTicket); }
Ensuite, nous pouvons appeler cette fonction dans la partie OnStart() :
closeAll();
L'exécution de ce script entraîne la clôture et la suppression de tous les ordres. Voici le code complet pour créer cette application closeAllApp en un seul bloc :
//+------------------------------------------------------------------+ //| closeAll Function | //+------------------------------------------------------------------+ #include <Trade/Trade.mqh> CTrade trade; //+------------------------------------------------------------------+ void OnStart() { closeAll(); } //+------------------------------------------------------------------+ void closeAll() { //close all open positions for(int i=PositionsTotal()-1; i>=0; i--) { ulong posTicket=PositionGetTicket(i); trade.PositionClose(posTicket); } //delete all pending orders for(int i=OrdersTotal()-1; i>=0; i--) { ulong posTicket=OrderGetTicket(i); trade.OrderDelete(posTicket); } } //+------------------------------------------------------------------+
Ces applications ne sont que des exemples de ce que nous pouvons créer en tant que fonctions définies par l'utilisateur. Vous pouvez les développer ou créer d'autres applications ou fonctions suivant vos besoins, comme une application de trailing stop et de gestion des transactions, un outil de sécurité du drawdown, etc.
Conclusion
D'après ce que nous avons mentionné dans cet article, il est supposé que vous avez trouvé qu'il est crucial d'utiliser des fonctions dans votre logiciel en raison de toutes les caractéristiques et de tous les avantages que vous obtiendrez en le faisant, car il est supposé que vous avez identifié les caractéristiques de leur utilisation comme :
- Permet d'appliquer le concept DRY (do not repeat yourself) à la programmation
- Permet de minimiser tout problème important en le divisant en petits problèmes et en les traitant
- Rend le code plus lisible
- Réutilisation
- Abstraction du code
- Encapsulation du code
- Amélioration du débogage
On suppose également que vous avez bien compris ce qu'est une fonction, ses types, une fonction intégrée et une fonction définie par l'utilisateur, et comment vous pouvez créer ou définir des fonctions en apprenant la structure des fonctions et toutes leurs caractéristiques, comme les fonctions avec arguments et comment nous pouvons passer ces arguments ou paramètres, sans arguments, et les fonctions avec des valeurs par défaut. Vous êtes censé pouvoir définir votre fonction en utilisant n'importe quel type de données et traiter l'opérateur de retour en fonction de celui-ci. Vous savez comment créer de nombreuses fonctions de surcharge avec le même nom mais des arguments différents pour effectuer la même tâche.
Après avoir présenté des applications pour créer des fonctions à titre d'exemple, je pense que cela vous a beaucoup aidé à approfondir votre compréhension du sujet en créant deux fonctions différentes :
- Nouvelle application d'alerte : à utiliser ou à appeler dans n'importe quelle partie du logiciel pour recevoir des alertes lorsque des nouvelles importantes arrivent. Vous trouverez le code source de newsAlertApp ci-joint.
- Lot size Calc App : à utiliser ou à appeler dans n'importe quelle partie du logiciel pour obtenir la taille de lot optimale pour ouvrir une transaction en fonction du pourcentage de risque défini, du prix d'entrée et du prix du stop loss. Ou, sur la base du pourcentage de risque défini et de la perte maximale en pips, ce qui signifie que nous avons créé une fonction de surcharge dans cette application. Vous trouverez le code source de lotSizeCalcApp ci-joint.
- Close All App : à utiliser ou à appeler pour clôturer tous les ordres ouverts et en attente. Vous trouverez le code source de closeAllApp ci-joint.
Le monde des fonctions est très intéressant et il est très important d'y prêter attention pour pouvoir créer des morceaux de code utiles de manière simple, fluide et efficace. J'espère que cet article vous sera utile pour développer vos compétences en matière de codage et améliorer votre carrière de trader en créant des outils utiles qui peuvent vous aider à bien trader. Si vous voulez lire plus d'articles sur la programmation ou sur la façon de créer des systèmes de trading basés sur les indicateurs techniques les plus populaires comme la moyenne mobile, le RSI, le MACD, le Stochastique, les bandes de Bollinger, le SAR Parabolique, etc., vous pouvez consulter mes publications. J'espère qu'elles vous seront également utiles.
Traduit de l’anglais par MetaQuotes Ltd.
Article original : https://www.mql5.com/en/articles/12970
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.
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.





- 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
Elles (les fonctions de Kim) ont été portées depuis longtemps de MQL4 à MQL5.
Excusez mon ignorance et croyez-moi, je ne suis pas sarcastique, mais qu'est-ce qui est porté ? Sont-elles réécrites pour MQL5 ? Si elles sont rassemblées quelque part, et si ce n'est pas difficile pour vous, veuillez fournir un lien vers les fonctions de Kim portées sur MQL5. J'ai essayé de rechercher sur le site les fonctions portées de Kim, mais je n'ai rien trouvé.
Cordialement, Vladimir.
fournir un lien vers les fonctions de Kim portées sur MQL5.
https://www.mql5.com/ru/forum/107476
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading
Bibliothèques : MT4Orders
fxsaber, 2019.01.13 17:23 PM.
Les fonctions de Kim sous MT4 sont assez populaires, j'ai donc téléchargé toutes les sources de son site et écrit un simple "convertisseur" pour elles sous MT5.https://www.mql5.com/ru/forum/107476
Je vous remercie de votre attention.
Cordialement, Vladimir.