
Le MQL5 Wizard : Comment apprendre à un EA à ouvrir des ordres en attente à n’importe quel prix
Introduction
Un Expert Advisor généré en utilisant MQL5 Wizard ne peut ouvrir les ordres en attente qu’à la distance fixe à partir du prix actuel. Cela signifie que si la situation du marché change (par exemple, un changement de volatilité du marché), l’Expert Advisor devra être exécuté à nouveau avec de nouveaux paramètres.
Cela ne conviendrait pas à de nombreux systèmes de trading. Dans la plupart des cas, le niveau de prix des ordres en attente est déterminé dynamiquement par un système de trading. Et la distance par rapport au prix actuel change constamment. Dans cet article, nous expliquerons comment modifier un Expert Advisor généré en utilisant le MQL5 Wizard afin qu’il puisse ouvrir des ordres en attente à des distances variables par rapport au prix actuel.
1. Mécanisme d’ouverture des ordres en attente dans l’Expert Advisor généré en utilisant le MQL5 Wizard
Un Expert Advisor généré aurait à peu près le même code dans son en-tête que celui fourni ci-dessous :
//+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ //--- inputs for expert input string Expert_Title="ExpertMySignalEnvelopes.mq5"; // Document name ulong Expert_MagicNumber =3915; // bool Expert_EveryTick =false; // //--- inputs for main signal input int Signal_ThresholdOpen =10; // Signal threshold value to open [0...100] input int Signal_ThresholdClose =10; // Signal threshold value to close [0...100] input double Signal_PriceLevel =0.0; // Price level to execute a deal input double Signal_StopLevel =85.0; // Stop Loss level (in points) input double Signal_TakeLevel =195.0; // Take Profit level (in points) input int Signal_Expiration =0; // Expiration of pending orders (in bars) input int Signal_Envelopes_PeriodMA =13; // Envelopes(13,0,MODE_SMA,...) Period of averaging input int Signal_Envelopes_Shift =0; // Envelopes(13,0,MODE_SMA,...) Time shift input ENUM_MA_METHOD Signal_Envelopes_Method =MODE_SMA; // Envelopes(13,0,MODE_SMA,...) Method of averaging input ENUM_APPLIED_PRICE Signal_Envelopes_Applied =PRICE_CLOSE; // Envelopes(13,0,MODE_SMA,...) Prices series input double Signal_Envelopes_Deviation=0.2; // Envelopes(13,0,MODE_SMA,...) Deviation input double Signal_Envelopes_Weight =1.0; // Envelopes(13,0,MODE_SMA,...) Weight [0...1.0] //--- inputs for money input double Money_FixLot_Percent =10.0; // Percent input double Money_FixLot_Lots =0.1; // Fixed volume //+------------------------------------------------------------------+
Veuillez noter le paramètre Signal_PriceLevel. Par défaut, l’Expert Advisor est généré avec Signal_PriceLevel=0. Ce paramètre définit la distance par rapport au prix actuel. S’il est égal à zéro, un ordre sera ouvert au prix actuel du marché. Pour ouvrir un ordre en attente, vous devez définir une valeur différente de zéro pour le paramètre Signal_PriceLevel, c’est-à-dire Signal_PriceLevel peut être à la fois négative et positive.
La valeur de Signal_PriceLevel est généralement un nombre assez important. La différence entre les valeurs négatives et positives est illustrée ci-dessous :
Signal_PriceLevel=-50 :
Fig. 1. Signal_PriceLevel=-50
Signal_PriceLevel=50 :
Fig. 2. Signal_PriceLevel=50
Ainsi, si Signal_PriceLevel=-50, un ordre en attente sera ouvert au prix qui est moins favorable que le prix actuel, alors que si Signal_PriceLevel=50, un ordre en attente sera ouvert au prix qui est meilleur que le prix actuel.
Cette version de l’Expert Advisor ouvre les ordres Sell Stop et Buy Stop.
2. Où stockons-nous les données sur la distance par rapport au prix d’ouverture d’un ordre en attente ?
Jetons d’abord un coup d’œil à la figure ci-dessous, puis passons aux commentaires :
Fig. 3. Stockage des données sur la distance par rapport au prix actuel
Interprétation de la figure ci-dessus.
Expert Advisor est l’Expert Advisor généré en utilisant le MQL5 Wizard.
- L’objet ExtExpert de la classe CExpert est déclaré dans l’Expert Advisor au niveau mondial.
- Ensuite, dans la fonction OnInit() de l’Expert Advisor, nous déclarons un pointeur vers l’objet signal de la classe CExpertSignal et l’objet signal est immédiatement créé à l’aide du nouvel opérateur.
- Tout en étant dans la fonction OnInit(), nous appelons la fonction InitSignal de l’objet ExtExpert et initialisons l’objet signal.
- Tout en étant dans la fonction OnInit(), nous appelons la fonction PriceLevel de l’objet signal qui obtient le paramètre Signal_PriceLevel.
Ainsi, le paramètre Signal_PriceLevel où la distance par rapport au prix actuel est stockée et qui a été déclarée dans l’Expert Advisor est transmise à l’objet signal de la classe CExpertSignal.
La classe CExpertSignal stocke la valeur de la distance par rapport au prix actuel dans la variable m_price_level déclarée avec l’étendue de classe protégée :
class CExpertSignal : public CExpertBase { protected: //--- variables double m_base_price; // base price for detection of level of entering (and/or exit?) //--- variables for working with additional filters CArrayObj m_filters; // array of additional filters (maximum number of fileter is 64) //--- Adjusted parameters double m_weight; // "weight" of a signal in a combined filter int m_patterns_usage; // bit mask of using of the market models of signals int m_general; // index of the "main" signal (-1 - no) long m_ignore; // bit mask of "ignoring" the additional filter long m_invert; // bit mask of "inverting" the additional filter int m_threshold_open; // threshold value for opening int m_threshold_close;// threshold level for closing double m_price_level; // level of placing a pending orders relatively to the base price double m_stop_level; // level of placing of the "stop loss" order relatively to the open price double m_take_level; // level of placing of the "take profit" order relatively to the open price int m_expiration; // time of expiration of a pending order in bars
3. Structure de l’Expert Advisor généré en utilisant le MQL5 Wizard
L’Expert Advisor se compose de plusieurs blocs avec des fonctionnalités différentes.
Fig. 4. Structure de l’Expert Advisor
Interprétation de la figure ci-dessus :
- Expert Advisor est l’Expert Advisor généré en utilisant le MQL5 Wizard.
- CExpert est la classe de base pour la mise en œuvre de stratégies de trading.
- CExpertSignal est la classe de base pour la création de générateurs de signal de trading.
- filter0 ... filtern sont des générateurs de signal de trading, les descendants de la classe CExpertSignal. Il convient de noter que notre système de trading est basé sur le générateur de signal de trading de l’indicateur Enveloppes, mais les signaux au sein du générateur ont été modifiés. Nous parlerons de ces changements à l’article 7.
4. Blocs d’Expert Advisor conseillés pour la modification
Comme vous pouvez le voir dans la structure de l’Expert Advisor généré en utilisant le MQL5 Wizard, il existe des blocs de classe de base. Les classes de base font partie de la bibliothèque standard.
Les classes en soi sont des descendants d’autres classes de base et elles se composent à leur tour d’une ou plusieurs classes de base. Vous trouverez ci-dessous les premières lignes du code de deux classes - CExpert et CExpertSignal :
//+------------------------------------------------------------------+ //| Expert.mqh | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "ExpertBase.mqh" #include "ExpertTrade.mqh" #include "ExpertSignal.mqh" #include "ExpertMoney.mqh" #include "ExpertTrailing.mqh" //+------------------------------------------------------------------+ . . . class CExpert : public CExpertBase
et
//+------------------------------------------------------------------+ //| ExpertSignal.mqh | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "ExpertBase.mqh" . . . class CExpertSignal : public CExpertBase
Je suis fortement opposé à toute modification des classes de base :
- Lorsque MetaEditor est mis à jour, toutes les modifications que vous apportez aux classes de base sont remplacées et les classes de base sont restaurées à leur état initial.
- La succession serait plus approprié dans ce cas. Mais alors vous devrez modifier la bibliothèque standard ENTIÈRE.
Au lieu de cela, il serait préférable de modifier le bloc des modules Expert Advisor et générateur de signal de trading, d’autant plus que notre système de trading aura déjà un module modifié en cours d’utilisation - le générateur de signal de trading de l’indicateur Envelopes.
Donc, c’est réglé : nous allons apporter des modifications aux blocs de l’Expert Advisor et au bloc du générateur de signal de trading.
5. La logique d’implémentation
Le pointeur sera transmis de l’Expert Advisor au générateur de signal de trading.
À cette fin, nous devons en outre déclarer une variable avec l’étendue protégée et écrire une méthode qui stocke le pointeur de l’Expert Advisor dans la variable interne :
Fig. 5. La logique d’implémentation
6. Système de trading
La cadre temporel du graphique est D1. L’indicateur à utiliser est enveloppes avec une période de moyenne de 13 et une méthode de moyenne exponentielle. Les types d’ordres que l’Expert Advisor peut ouvrir sont Sell Stop et Buy Stop.
Si la barre précédente était haussière, nous définissons un ordre Sell Stop. Si la barre précédente était baissière, nous définissons un ordre Buy Stop. En d’autres termes, nous espérons un repli :
Fig. 6. Système de trading
Pour générer des signaux de trading comme requis par le système de trading, le module standard du générateur de signal de trading SignalEnvelopes.mqh a été modifié.
Notez qu’ici, vous pouvez utiliser n’importe quel générateur de signal de trading de la bibliothèque standard.
7. Modification du générateur de signal de trading. Obtenir le prix de barre
Alors, commençons. Je dois dire que je préfère enregistrer mes programmes dans MQL5 Storage.
La première chose que nous devrions faire pour commencer à modifier le générateur de signal de trading est de créer un fichier d’inclusion vide, de tout supprimer de celui-ci et de coller tout le contenu du générateur de signal de trading standard de l’indicateur Enveloppes.
Par défaut, le générateur de signal de trading doit être situé sous ...MQL5\Include\Expert\Signal. Ne pas surcharger le ...\Signal de la bibliothèque standard avec trop d’informations, créons un nouveau dossier sous le dossier ...\Expert et appelez-le \MySignals :
Fig. 7. Création du dossier MySignals
Ensuite, nous allons créer un fichier d’inclusion en utilisant le MQL5 Wizard.
Dans MetaEditor, sélectionnez 'New' dans le menu Fichier, puis sélectionnez 'Include file (*.mqh)'.
Fig. 8. Le MQL5 Wizard. Création d’un fichier d’inclusion
Le nom de notre classe de générateur de signal sera MySignalEnvelopes.
Et il sera situé sous : Include\Expert\MySignals\MySignalEnvelopes. Précisons-le :
Fig. 9. Le MQL5 Wizard. Emplacement du fichier include
Après avoir cliqué sur 'Terminer', le MQL5 Wizard génère un modèle vide.
Le fichier MySignalEnvelopes.mqh généré doit ensuite être ajouté au MQL5 Storage :
Fig. 10. Le MQL5 Storage. Ajout du fichier
Une fois le fichier ajouté, nous devons valider les modifications apportées au MQL Storage :
Fig. 11. Le MQL5 Storage. Validation des modifications
Après avoir terminé les étapes ci-dessus, nous pouvons procéder à la modification de notre générateur de signal de trading.
Étant donné que le générateur est basé sur le fichier \Include\Expert\Signal\SignalEnvelopes.mqh, nous copions tout le contenu du fichier et le collons dans le fichier du générateur, en ne laissant que l’en-tête d’origine :
//+------------------------------------------------------------------+ //| MySignalEnvelopes.mqh | //| Copyright © 2013, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2013, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #include <Expert\ExpertSignal.mqh> // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signals of indicator 'Envelopes' | //| Type=SignalAdvanced | //| Name=Envelopes | //| ShortName=Envelopes | //| Class=CSignalEnvelopes | //| Page=signal_envelopes | //| Parameter=PeriodMA,int,45,Period of averaging | //| Parameter=Shift,int,0,Time shift | //| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging | //| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series | //| Parameter=Deviation,double,0.15,Deviation | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSignalEnvelopes. | //| Purpose: Class of generator of trade signals based on | //| the 'Envelopes' indicator. | //| Is derived from the CExpertSignal class. | //+------------------------------------------------------------------+ class CSignalEnvelopes : public CExpertSignal { protected: CiEnvelopes m_env; // object-indicator //--- adjusted parameters int m_ma_period; // the "period of averaging" parameter of the indicator int m_ma_shift; // the "time shift" parameter of the indicator ENUM_MA_METHOD m_ma_method; // the "method of averaging" parameter of the indicator ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter of the indicator double m_deviation; // the "deviation" parameter of the indicator double m_limit_in; // threshold sensitivity of the 'rollback zone' double m_limit_out; // threshold sensitivity of the 'break through zone' //--- "weights" of market models (0-100) int m_pattern_0; // model 0 "price is near the necessary border of the envelope" int m_pattern_1; // model 1 "price crossed a border of the envelope" public: CSignalEnvelopes(void); ~CSignalEnvelopes(void); //--- methods of setting adjustable parameters void PeriodMA(int value) { m_ma_period=value; } void Shift(int value) { m_ma_shift=value; } void Method(ENUM_MA_METHOD value) { m_ma_method=value; } void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; } void Deviation(double value) { m_deviation=value; } void LimitIn(double value) { m_limit_in=value; } void LimitOut(double value) { m_limit_out=value; } //--- methods of adjusting "weights" of market models void Pattern_0(int value) { m_pattern_0=value; } void Pattern_1(int value) { m_pattern_1=value; } //--- method of verification of settings virtual bool ValidationSettings(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators); //--- methods of checking if the market models are formed virtual int LongCondition(void); virtual int ShortCondition(void); protected: //--- method of initialization of the indicator bool InitMA(CIndicators *indicators); //--- methods of getting data double Upper(int ind) { return(m_env.Upper(ind)); } double Lower(int ind) { return(m_env.Lower(ind)); } }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSignalEnvelopes::CSignalEnvelopes(void) : m_ma_period(45), m_ma_shift(0), m_ma_method(MODE_SMA), m_ma_applied(PRICE_CLOSE), m_deviation(0.15), m_limit_in(0.2), m_limit_out(0.2), m_pattern_0(90), m_pattern_1(70) { //--- initialization of protected data m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CSignalEnvelopes::~CSignalEnvelopes(void) { } //+------------------------------------------------------------------+ //| Validation settings protected data. | //+------------------------------------------------------------------+ bool CSignalEnvelopes::ValidationSettings(void) { //--- validation settings of additional filters if(!CExpertSignal::ValidationSettings()) return(false); //--- initial data checks if(m_ma_period<=0) { printf(__FUNCTION__+": period MA must be greater than 0"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Create indicators. | //+------------------------------------------------------------------+ bool CSignalEnvelopes::InitIndicators(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- initialization of indicators and timeseries of additional filters if(!CExpertSignal::InitIndicators(indicators)) return(false); //--- create and initialize MA indicator if(!InitMA(indicators)) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialize MA indicators. | //+------------------------------------------------------------------+ bool CSignalEnvelopes::InitMA(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- add object to collection if(!indicators.Add(GetPointer(m_env))) { printf(__FUNCTION__+": error adding object"); return(false); } //--- initialize object if(!m_env.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_method,m_ma_applied,m_deviation)) { printf(__FUNCTION__+": error initializing object"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| "Voting" that price will grow. | //+------------------------------------------------------------------+ int CSignalEnvelopes::LongCondition(void) { int result=0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width) result=m_pattern_1; //--- return the result return(result); } //+------------------------------------------------------------------+ //| "Voting" that price will fall. | //+------------------------------------------------------------------+ int CSignalEnvelopes::ShortCondition(void) { int result =0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width) result=m_pattern_1; //--- return the result return(result); } //+------------------------------------------------------------------+
Maintenant, nous allons travailler sur des modifications de certaines parties du code.
Pour éviter toute confusion, le code modifié sera mis en évidence :
//+------------------------------------------------------------------+
//| MySignal.mqh |
//| Copyright © 2013, Vladimir Karputov |
//| http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
Le code modifié est le code qui doit être copié et collé dans le générateur de signal de trading. J’espère qu’une telle mise en évidence vous aidera à mieux comprendre le code.
Puisque nous écrivons notre propre classe du générateur de signal de trading, son nom doit être différent du nom de la classe de base. Nous remplaçons donc CSignalEnvelopes par CMySignalEnvelopes dans l’ensemble du code :
Fig. 12. Renommer la classe
Pour vous assurer que la classe du générateur de signal de trading est affichée dans le MQL5 Wizard sous son nom, modifiez le nom de la classe dans le bloc de description
//| Title=Signals of indicator 'Envelopes' |
en
//| Title=Signals of indicator 'MySignalEnvelopes' |
Changer la valeur de la période MA
//| Parameter=PeriodMA,int,45,Period of averaging |
à 13 (ce n’est que ma suggestion, vous pouvez définir n’importe quelle valeur que vous préférez)
//| Parameter=PeriodMA,int,13,Period of averaging |
En outre, nous modifions également le paramètre Deviation
//| Parameter=Deviation,double,0.15,Deviation |
en définissant une valeur supérieure
//| Parameter=Deviation,double,1.15,Deviation |
Selon notre logique d’implémentation,nous devons déclarer une variable interne qui stockera le pointeur vers le signal principal.
Comme il doit s’agir d’une variable interne (dans le cadre de la classe du générateur de signal de trading uniquement), elle sera ajoutée au bloc de code suivant :
protected: CiEnvelopes m_env; // object-indicator //--- adjusted parameters int m_ma_period; // the "period of averaging" parameter of the indicator int m_ma_shift; // the "time shift" parameter of the indicator ENUM_MA_METHOD m_ma_method; // the "method of averaging" parameter of the indicator ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter of the indicator double m_deviation; // the "deviation" parameter of the indicator //--- "weights" of market models (0-100) int m_pattern_0; // model 0 CExpertSignal *m_signal; // storing the pointer to the main signal
Veuillez également noter que j’ai supprimé les variables inutiles du code.
La méthode de stockage du pointeur vers le signal principal sera déclarée dans un autre bloc de code - la 'méthode de réglage du pointeur sur le signal principal'. Ici, j’ai également supprimé certaines méthodes non pertinentes.
public: CMySignalEnvelopes(void); ~CMySignalEnvelopes(void); //--- methods of setting adjustable parameters void PeriodMA(int value) { m_ma_period=value; } void Shift(int value) { m_ma_shift=value; } void Method(ENUM_MA_METHOD value) { m_ma_method=value; } void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; } void Deviation(double value) { m_deviation=value; } //--- methods of adjusting "weights" of market models void Pattern_0(int value) { m_pattern_0=value; } //--- method of verification of settings virtual bool ValidationSettings(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators); //--- methods of checking if the market models are formed virtual int LongCondition(void); virtual int ShortCondition(void); //--- method of setting the pointer to the main signal virtual bool InitSignal(CExpertSignal *signal=NULL);
Spécifions maintenant certains paramètres modifiés dans le constructeur et supprimons les variables qui ne sont plus nécessaires :
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CMySignalEnvelopes::CMySignalEnvelopes(void) : m_ma_period(13), m_ma_shift(0), m_ma_method(MODE_SMA), m_ma_applied(PRICE_CLOSE), m_deviation(1.15), m_pattern_0(50)
À ce stade, nous pouvons procéder à la modification de la logique de génération de signal de trading en fonction de notre système de trading.
Le bloc de code responsable d’un signal d’achat :
int CMySignalEnvelopes::LongCondition(void) { int result=0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width) result=m_pattern_1; //--- return the result return(result); }
sera comme indiqué ci-dessous, en suivant les changements nécessaires :
int CMySignalEnvelopes::LongCondition(void) //---buy
{
int result=0;
int idx =StartIndex();
double open=Open(idx);
double close=Close(idx);
double prlevel;
if(IS_PATTERN_USAGE(0) && close<open)
{
prlevel=GetPriceLevelStopp(open,Open(0));
m_signal.PriceLevel(prlevel);
result=m_pattern_0;
}
//--- return the result
return(result);
}
Le bloc de code responsable d’un signal de vente :
int CMySignalEnvelopes::ShortCondition(void) { int result =0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width) result=m_pattern_1; //--- return the result return(result); }
sera comme indiqué ci-dessous, en suivant les changements nécessaires :
int CMySignalEnvelopes::ShortCondition(void) //---sell
{
int result =0;
int idx =StartIndex();
double open=Open(idx);
double close=Close(idx);
double prlevel;
if(IS_PATTERN_USAGE(0) && close>open)
{
prlevel=GetPriceLevelStopp(Open(0),open);
m_signal.PriceLevel(prlevel);
result=m_pattern_0;
}
//--- return the result
return(result);
}
8. Quelques commentaires sur le bloc de code de signal
Si la condition requise pour un certain signal est remplie, nous appelons la méthode GetPriceLevelStopp qui renvoie un nombre comme "20" ou "15" - la valeur de la distance par rapport au prix actuel.
Ceci est suivi par l’appel de la méthode PriceLevel de l’objet m_signal (qui définit la distance pour déterminer le prix du niveau d'ordre en attente). Il convient de rappeler que m_signal est l’objet de classe CExpertSignal qui stocke le pointeur vers le signal principal.
Le code de la méthode GetPriceLevelStopp est fourni ci-dessous :
double CMySignalEnvelopes::GetPriceLevelStopp(double price_0,double min)
{
double level;
double temp;
temp-=(price_0-min)/PriceLevelUnit();
level=NormalizeDouble(temp,0);
return(level);
}
Nous devons déclarer cette méthode dans l’en-tête de classe :
protected: //--- method of initialization of the indicator bool InitMA(CIndicators *indicators); //--- methods of getting data double Upper(int ind) { return(m_env.Upper(ind)); } double Lower(int ind) { return(m_env.Lower(ind)); } double GetPriceLevelStopp(double price,double min); };
Une autre méthode dont nous aurons besoin est la méthode de passage du pointeur au signal principal à la variable interne:
bool CMySignalEnvelopes::InitSignal(CExpertSignal *signal)
{
m_signal=signal;
return(true);
}
Après cela, nous devons créer un Expert Advisor dans le MQL5 Wizard et y inclure le module de signal 'MySignalEnvelopes'.
Nous devons également ajouter l’appel de méthode InitSignal au code de l’Expert Advisor généré en utilisant le MQL5 Wizard :
//--- Set filter parameters filter0.PeriodMA(Signal_Envelopes_PeriodMA); filter0.Shift(Signal_Envelopes_Shift); filter0.Method(Signal_Envelopes_Method); filter0.Applied(Signal_Envelopes_Applied); filter0.Deviation(Signal_Envelopes_Deviation); filter0.Weight(Signal_Envelopes_Weight); filter0.InitSignal(signal); //...
Pour une meilleure visualisation du fonctionnement de l’Expert Advisor, j’ai fourni une courte vidéo :
Le code de l’Expert Advisor généré en utilisant le MQL5 Wizard, ainsi que le code du module de signal, sont joints à l’article.
Vous trouverez ci-dessous les résultats des tests de l’Expert Advisor. Il a été testé pour EURUSD et USDJPY avec les paramètres suivants: période de test 2013.01.01 - 2013.09.01, période - D1, niveau Stop Loss = 85, niveau Take Profit = 195.
Fig. 13. Test pour EURUSD sur D1
Fig. 14. Test pour USDJPY sur D1
Conclusion
Nous venons de voir comment nous pouvons modifier le code du module de signal de trading pour la mise en œuvre de la fonctionnalité nous permettant de définir des ordres en attente à n’importe quelle distance du prix actuel : il peut s’agir du prix Close ou Open de la barre précédente ou de la valeur de la moyenne mobile. Il y a beaucoup d’options. Il est important que vous puissiez définir n’importe quel prix d’ouverture pour un ordre en attente.
L’article a montré comment nous pouvons accéder au pointeur vers le signal principal, et donc aux méthodes de classe CExpertSignal. Je crois que l’article s’avérera utile aux traders qui tradent avec des ordres en attente.
Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/723





- 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