English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Systèmes de trading simples utilisant des indicateurs de sémaphore

Systèmes de trading simples utilisant des indicateurs de sémaphore

MetaTrader 5Systèmes de trading | 22 décembre 2021, 17:00
213 0
Nikolay Kositsin
Nikolay Kositsin

Introduction

Les indicateurs de sémaphore ou de signal sont de simples détecteurs qui indiquent les moments d’entrée ou de sortie du marché. Dans le cas où il y a un signal d’entrée à la barre actuelle, une étiquette appropriée apparaît sur un graphique de symboles. Cette étiquette peut ensuite être utilisée comme condition pour effectuer une transaction.

Il existe de nombreux indicateurs de ce type, mais l’essence même du système de trading original basé sur de tels indicateurs n’a pas changé du tout. Par conséquent, c’est une bonne idée de l’implémenter sous la forme la plus simple et la plus universelle. Cela permettra une utilisation plus poussée du résultat obtenu lors de l’utilisation d’indicateurs similaires sans modifications considérables.

Fig.1. Indicateur de signal sémaphore ASCtrend

Fig.1. Indicateur de signal sémaphore ASCtrend

Fig.2. Indicateur ASCtrend. Signal de trading pour effectuer une transaction 

Fig.2. Signal de trading pour effectuer une transaction à l’aide de l’indicateur de signal de sémaphore ASCtrend


Échantillons d’indicateurs de signal de sémaphore typiques

Actuellement, il existe de nombreux indicateurs de ce type dans Base de code. Dans cet article, je ne fournirai que quelques liens vers les pages Web appropriées:

En plus des indicateurs de signal de sémaphore, il existe un groupe d’indicateurs de tendance de sémaphore:

Fig.3. Signaux de trading à l’aide de l’indicateur Heiken_Ashi_Smoothed 

Fig.3. Indicateur de tendance du sémaphore

 

Fig.4. Signal de trading pour effectuer une transaction à l’aide de l’indicateur de tendance du sémaphore lissé Heiken Ashi

Fig.4. Signal de trading pour effectuer une transaction à l’aide de l’indicateur de tendance du sémaphore lissé Heiken Ashi

Les systèmes de trading utilisant de tels indicateurs ont un code légèrement différent pour obtenir des signaux de trading, tandis que le code Expert Advisor reste presque inchangé.

Exemples d’indicateurs de tendance typiques des sémaphores

La Base de code contient beaucoup de ces indicateurs. Dans cet article, je ne fournirai que quelques liens vers les pages Web appropriées:

 

Données de base pour la création d’un système de trading :

  1. Indicateur de sémaphore avec les paramètres d’entrée qui doivent être présents dans l’Expert Advisor ;
  2. La liste des paramètres de trading Expert Advisor d’entrée supplémentaires :
    • une part des ressources financières d’un dépôt utilisées dans une transaction ;
    • un volume de Stop Loss et Take Profit (les ordres en attente ne doivent pas être utilisés en cas de valeurs nulles) ;
    • glissement (différence maximale admissible entre les prix fixés et les prix réels des contrats) ;
    • indice de la barre, à partir de laquelle les signaux de trading seront reçus ;
    • autorisations pour l’ouverture de positions longues et courtes ;
    • autorisations pour la fermeture forcée des positions longues et courtes en fonction des signaux indicateurs.

Bien sûr, il serait beaucoup plus pratique de donner des ordres pour effectuer des transactions en utilisant des fonctions de trading universelles. Ces fonctions sont assez complexes et doivent être regroupées dans un fichier de bibliothèque séparé pour rendre le code de l’application aussi facile que possible.

Le code de l’Expert Advisor mettant en œuvre le système de trading sémaphore :

//+------------------------------------------------------------------+
//|                                                 Exp_ASCtrend.mq5 |
//|                             Copyright © 2011,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
#property version   "1.00"
//+----------------------------------------------+
//| Expert Advisor indicator input parameters    |
//+----------------------------------------------+
input double MM=-0.1;             // Share of a deposit in a deal, negative values - lot size
input int    StopLoss_=1000;      // Stop loss in points
input int    TakeProfit_=2000;    // Take profit in points
input int    Deviation_=10;       // Max. price deviation in points
input bool   BuyPosOpen=true;     // Permission to buy
input bool   SellPosOpen=true;    // Permission to sell
input bool   BuyPosClose=true;    // Permission to exit long positions
input bool   SellPosClose=true;   // Permission to exit short positions
//+----------------------------------------------+
//| ASCtrend indicator input parameters          |
//+----------------------------------------------+
input ENUM_TIMEFRAMES InpInd_Timeframe=PERIOD_H1; // ASCtrend indicator time frame
input int  RISK=4;                               // Risk level
input uint SignalBar=1;                          // Bar index for getting an entry signal
//+----------------------------------------------+

int TimeShiftSec;
//---- declaration of integer variables for the indicators handles
int InpInd_Handle;
//---- declaration of integer variables of the start of data calculation
int min_rates_total;
//+------------------------------------------------------------------+
//| Trading algorithms                                               | 
//+------------------------------------------------------------------+
#include <TradeAlgorithms.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- getting ASCtrend indicator handle
   InpInd_Handle=iCustom(Symbol(),InpInd_Timeframe,"ASCtrend",RISK);
   if(InpInd_Handle==INVALID_HANDLE) Print(" Failed to get handle of ASCtrend indicator");

//---- initialization of a variable for storing a chart period in seconds  
   TimeShiftSec=PeriodSeconds(InpInd_Timeframe);

//---- initialization of variables of the start of data calculation
   min_rates_total=int(3+RISK*2+SignalBar);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//----
   GlobalVariableDel_(Symbol());
//----
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---- checking the number of bars to be enough for calculation
   if(BarsCalculated(InpInd_Handle)<min_rates_total) return;
   
//---- uploading history for IsNewBar() and SeriesInfoInteger() functions normal operation  
   LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe);

//---- declaration of local variables
   double DnVelue[1],UpVelue[1];
//---- declaration of static variables
   static bool Recount=true;
   static bool BUY_Open=false,BUY_Close=false;
   static bool SELL_Open=false,SELL_Close=false;
   static datetime UpSignalTime,DnSignalTime;
   static CIsNewBar NB;

//+----------------------------------------------+
//| Searching for deals performing signals       |
//+----------------------------------------------+
   if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar
     {
      //---- zeroing out trading signals
      BUY_Open=false;
      SELL_Open=false;
      BUY_Close=false;
      SELL_Close=false;
      Recount=false;

      //---- copy newly appeared data into the arrays
      if(CopyBuffer(InpInd_Handle,1,SignalBar,1,UpVelue)<=0) {Recount=true; return;}
      if(CopyBuffer(InpInd_Handle,0,SignalBar,1,DnVelue)<=0) {Recount=true; return;}

      //---- getting buy signals
      if(UpVelue[0] && UpVelue[0]!=EMPTY_VALUE)
        {
         if(BuyPosOpen) BUY_Open=true;
         if(SellPosClose) SELL_Close=true;
         UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- getting sell signals
      if(DnVelue[0] && DnVelue[0]!=EMPTY_VALUE)
        {
         if(SellPosOpen) SELL_Open=true;
         if(BuyPosClose) BUY_Close=true;
         DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- searching for the last trading direction for getting positions closing signals
      //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester 
      if((BuyPosOpen && BuyPosClose || SellPosOpen && SellPosClose) && (!BUY_Close && !SELL_Close))
        {
         int Bars_=Bars(Symbol(),InpInd_Timeframe);

         for(int bar=int(SignalBar+1); bar<Bars_; bar++)
           {
            if(SellPosClose)
              {
               if(CopyBuffer(InpInd_Handle,1,bar,1,UpVelue)<=0) {Recount=true; return;}
               if(UpVelue[0]!=0 && UpVelue[0]!=EMPTY_VALUE)
                 {
                  SELL_Close=true;
                  break;
                 }
              }

            if(BuyPosClose)
              {
               if(CopyBuffer(InpInd_Handle,0,bar,1,DnVelue)<=0) {Recount=true; return;}
               if(DnVelue[0]!=0 && DnVelue[0]!=EMPTY_VALUE)
                 {
                  BUY_Close=true;
                  break;
                 }
              }
           }
        }
     }

//+----------------------------------------------+
//| Performing deals                             |
//+----------------------------------------------+
//---- Closing a long position
   BuyPositionClose(BUY_Close,Symbol(),Deviation_);

//---- Closing a short position   
   SellPositionClose(SELL_Close,Symbol(),Deviation_);

//---- Buying
   BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);

//---- Selling
   SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);
//----
  }
//+------------------------------------------------------------------+

Le code pour la réalisation d’une telle idée est assez simple et clair, bien que certains détails devraient être clarifiés.

La période graphique utilisée par un indicateur de signal et un Expert Advisor est fixée dans la variable d’entrée InpInd_Timeframe de l’Expert Advisor. Par conséquent, la modification d’un graphique, où se trouve un Expert Advisor, ne modifie pas ce paramètre pour l’Expert Advisor.

La fonction IsNewBar() nécessaire pour déterminer le moment de l’arrivée d’une nouvelle barre est implémentée sous forme de classe placée dans le fichier TradeAlgorithms.mqh. Cela permet d’utiliser facilement n’importe quel nombre de ces fonctions dans le code en définissant une variable CIsNewBar statique individuelle pour chacune d’elles.

Les variables UpSignalTime et DnSignalTime sont utilisées pour stocker et transférer le temps, après quoi il est possible d’effectuer la prochaine transaction après la précédente, vers les fonctions de trading. Dans notre cas, cette fonctionnalité est utilisée pour éviter d’effectuer plusieurs transactions dans la même direction à la même barre (lors de l’exécution d’une transaction, la fonction de trading stocke l’heure de la finition de la barre courante et n’effectue pas de nouvelles transactions dans la même direction jusqu’à ce moment-là).

Le bloc « Recherche de la dernière direction de trading pour obtenir des signaux de clôture de positions » dans la fonction OnTick() est nécessaire pour recevoir des signaux de clôture de positions sur les barres sans signaux de trading. Dans le cas d’un fonctionnement normal d’Expert Advisor, on n’en a pas besoin. Mais en cas d’échec de la connexion Internet, il est tout à fait possible qu’un nouveau signal de trading soit manqué. C'est rarement une bonne idée d'entrer sur le marché après coup, toutefois il serait sage de fermer les positions d’ouverture.

Utilisation du système de trading avec d’autres indicateurs de signal de sémaphore

Maintenant, s’il est nécessaire d’utiliser ce code avec un autre indicateur de signal de sémaphore, les actions suivantes doivent être effectuées :

  1. Remplacer les données d’indicateur précédentes par les paramètres nécessaires de la nouvelle dans les paramètres d’entrée d’un Expert Advisor ;
  2. Modifier le code d’obtention du descripteur de l’indicateur dans le bloc OnInit() ;
  3. Déterminer les indices des tampons d’indicateurs, utilisés pour stocker les signaux de trading d’achat et de vente à partir du code de l’indicateur, et les entrer de manière appropriée dans les appels de fonction CopyBuffer() du bloc OnTick(). Dans ce cas, des tampons zéro et premier indicateur sont utilisés ;
  4. Modifier l’initialisation de la variable de point de départ (min_rates_total) de calcul des données dans un Expert Advisor en fonction du code de l’indicateur ;
  5. Changer le bloc « Recherche de la dernière direction de trading pour obtenir des signaux de clôture des positions » dans la fonction OnTick() suivant le code de l’indicateur. 

Utilisation du système de trading avec d’autres indicateurs de tendance du sémaphore

Lors de l’utilisation de ce système de trading avec indicateur de tendance sémaphore, le code Expert Advisor a un peu changé dans le bloc pour déterminer les signaux pour les transactions de la fonction OnTick(). Par exemple, le code se présentera comme suit pour l’Expert Advisor basé sur l’indicateur FiboCandles :

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---- checking the number of bars to be enough for calculation
   if(BarsCalculated(InpInd_Handle)<min_rates_total) return;
   
//---- uploading history for IsNewBar() and SeriesInfoInteger() functions  
   LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe);

//---- declaration of local variables
   double TrendVelue[2];
//---- declaration of static variables
   static bool Recount=true;
   static bool BUY_Open=false,BUY_Close=false;
   static bool SELL_Open=false,SELL_Close=false;
   static datetime UpSignalTime,DnSignalTime;
   static CIsNewBar NB;

//+----------------------------------------------+
//| Searching for deals performing signals       |
//+----------------------------------------------+
   if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar
     {
      //---- zeroing out trading signals
      BUY_Open=false;
      SELL_Open=false;
      BUY_Close=false;
      SELL_Close=false;
      Recount=false;

      //---- copy the newly obtained data into the arrays
      if(CopyBuffer(InpInd_Handle,4,SignalBar,2,TrendVelue)<=0) {Recount=true; return;}

      //---- getting buy signals
      if(TrendVelue[0]==1 && TrendVelue[1]==0)
        {
         if(BuyPosOpen) BUY_Open=true;
         if(SellPosClose)SELL_Close=true;
         UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- getting sell signals
      if(TrendVelue[0]==0 && TrendVelue[1]==1)
        {
         if(SellPosOpen) SELL_Open=true;
         if(BuyPosClose) BUY_Close=true;
         DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- searching for the last trading direction for getting positions closing signals
      //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester 
        {
         if(SellPosOpen && SellPosClose  &&  TrendVelue[1]==0) SELL_Close=true;
         if(BuyPosOpen  &&  BuyPosClose  &&  TrendVelue[1]==1) BUY_Close=true;
        }
     }

//+----------------------------------------------+
//| Performing deals                             |
//+----------------------------------------------+
//---- Closing a long position
   BuyPositionClose(BUY_Close,Symbol(),Deviation_);

//---- Closing a short position   
   SellPositionClose(SELL_Close,Symbol(),Deviation_);

//---- Buying
   BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);

//---- Selling
   SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);
//----
  }

Dans ce cas, les signaux de trading sont reçus d’un seul tampon d’indicateur de couleur (contenant des indices de couleur). Les données de cette mémoire tampon ne peuvent avoir que deux valeurs : 0 - pour le marché ascendant et 1 - pour le marché descendant. Le code de bloc « Recherche de la dernière direction de trading pour obtenir des signaux de clôture de positions » est devenu aussi simple que possible, car une direction de tendance à n’importe quelle barre peut être reçue directement à partir de la cellule appropriée du tampon de l’indicateur.

Au bloc « Exécuter les transactions », les fonctions de fermeture des positions vont en premier, suivies des fonctions d’ouverture. Dans le cas de la séquence inverse, il ne sera possible de conclure les transactions que sur une barre, vous ne pourrez pas les ouvrir simultanément lors des tests en mode « Prix d’ouverture uniquement » ! Par conséquent, les résultats de trading seront sérieusement perturbés.


Test du système de trading

Avant de procéder aux tests du système de trading, un détail important doit être clarifié. Dans le cas où la valeur de la variable d’entrée SignalBar est égale à zéro, l’Expert Advisor obtiendra des transactions exécutant des signaux à partir de la barre courante. Mais le signal de la barre actuelle n’est pas fiable pour indiquer le changement de tendance qui s’est déplacée contre ce signal à la barre précédente. Les signaux sur la barre actuelle peuvent apparaître et disparaître, tandis qu’une tendance peut se déplacer contre de tels signaux pendant assez longtemps. Cela peut être facilement vu, si un Expert Advisor est testé sur toutes les traits avec une visualisation activée et une variable SignalBar égale à zéro. La visualisation du fonctionnement de l’indicateur ASCtrend présente une preuve très claire de ce fait dans un tel cas.

Encore une fois, seul le mode « Chaque trait » convient à une optimisation Expert Advisor avec un signal reçu de la barre courante. Dans le cas où il doit être reçu d’une autre barre déjà fermée, le mode « Prix d’ouverture uniquement » est tout à fait suffisant. Cela accélère considérablement l’analyse du comportement du système de trading sans pertes sérieuses dans sa qualité.

Par conséquent, il est préférable de ne pas utiliser les signaux de la barre courante pour tester et optimiser de tels systèmes de trading!

Alors, testons l’Expert Advisor avec des paramètres par défaut sur EUR/USD depuis le début de l’année jusqu’au début du mois de décembre :

Fig.5. Résultats des tests de Exp_ASCtrend Expert Advisor avec les paramètres par défaut sur EUR/USD H1 

Fig.5. Résultats des tests de Exp_ASCtrend Expert Advisor avec les paramètres par défaut sur EUR/USD H1 

Après avoir modifié un peu les paramètres de l’Expert Advisor dans le Testeur de stratégie, nous pouvons trouver assez facilement la combinaison la plus appropriée des paramètres de l’Expert Advisor pour les données historiques existantes :

 Fig.6. Résultats des tests de Exp_ASCtrend Expert Advisor après optimisation avec de meilleurs paramètres sur EUR/USD H1

Fig.6. Résultats des tests deExp_ASCtrend Expert Advisor après optimisation avec de meilleurs paramètres sur EUR/USD H1

Le processus d’optimisation du système de trading n’a pas de particularités, c’est pourquoi je ne fournirai qu’un seul lien vers l’article décrivant ce processus en détail: « MQL5: Guide de test et d’optimisation des Expert Advisors dans MQL5».

Bien sûr, il serait naïf de s’attendre à des profits exceptionnels d’un système de trading aussi simple. Mais il est tout à fait possible d’obtenir de bons résultats dans le cas où ce système semi-automatique est habilement manipulé et est régulièrement réglé en fonction du comportement Market du jour.

Par exemple, il y a eu une tendance à la hausse sur le graphique EUR/USD S12 en 2011 de janvier à mai. Et elle était facilement détectable à un stade précoce :

Fig.7. Graphique EUR/USD H12 (janvier/mai 2011)

Fig.7. Graphique EUR/USD H12 (janvier/mai 2011)

Il serait intéressant de tester l’Expert Advisor sur cet intervalle de temps avec les paramètres par défaut, la possibilité d’acheter uniquement et l’utilisation de seulement 5 % d’un dépôt (MM=0,05). Voici les résultats de l’Expert Advisor avec de tels paramètres testés sur le graphique H1 :

Fig.8. Résultats des tests de Exp_ASCtrend Expert Advisor avec les paramètres par défaut sur EUR/USD H1 pour janvier/mai 2011 (uniquement les positions longues, MM=0,05) 

Fig.8. Résultats des tests de Exp_ASCtrend Expert Advisor avec les paramètres par défaut sur EUR/USD H1 pour janvier/mai 2011 (uniquement positions longues, MM=0,05)

Bien sûr, dans ce cas, un trader est entièrement responsable de la sélection d’une direction de transaction. Mais si nous gardons à l’esprit que cela devrait être fait en utilisant de grands graphiques temporels, nous ne rencontrerons pratiquement aucune difficulté.


Modification du module de trading pour l’utiliser avec un autre indicateur

Cet article aurait pu se terminer ici, mais sachons que MetaEditor a acquis la possibilité de générer des Expert Advisors basés sur des modules de trading prêts à l’emploi. Le processus de création de tels modules en tenant compte de tout le matériel présenté ici est assez complexe et nécessite une étude distincte. Par conséquent, je vais me concentrer sur les modules de trading déjà créés qui sont complètement analogues aux systèmes de trading que j’ai suggérés. Et seulement après cela, je passerai aux détails de la modification de ces modules en fonction des indicateurs de signal spécifiques tout en évitant les détails inutiles.

Supposons que nous ayons déjà la collection de modules de trading pour les systèmes de signaux sémaphores (MySignals.zip) et que nous voulons créer le module analogue pour un indicateur particulier. Qu’il s’agisse de l’indicateur BykovTrendSignal.mq5 ou autre, qui est un indicateur de signal de sémaphore typique. Tout d’abord, nous devrions trouver l’analogue le plus précis de l’indicateur de cette collection (Indicateurs.zip). Visuellement, nous déterminons que le premier indicateur de cet article (ASCtrend) lui ressemble le plus.  Par conséquent, nous utiliserons le module de trading de cet indicateur pour modification.

Compte tenu de son utilisation dans le code de programme requis, l’indicateur lui-même (BykovTrend) a un ensemble de paramètres d’entrée :

//+----------------------------------------------+
//| Indicator input parameters                   |
//+----------------------------------------------+
input int RISK=3;
input int SSP=9;
//+----------------------------------------------+

Et nous avons besoin des indices des tampons d’indicateurs utilisés pour stocker les signaux pour effectuer des transactions. Dans notre cas, il s’agit de : 0 - pour les signaux de vente et 1 - pour les signaux d’achat.

Maintenant que nous savons quel module doit être utilisé pour la modification, nous le copions dans le dossier \MQL5\Include\Expert\Signal\MySignals\ avec le nom de fichier BykovTrendSignal.mqh, puis l’ouvrons dans MetaEditor. Il existe une expression qui revient régulièrement, notamment « ASCtrend » (le nom de l’indicateur précédent) dans le code utilisé. Elle devrait être remplacée par le nom du nouvel indicateur - « BykovTrend ». Pour ce faire, appuyez simultanément sur les touches « Ctrl » et « H » et effectuez les modifications nécessaires :

 Remplacement du nom de l’indicateur dans le code du module de trading

Fig.9. Remplacement du nom de l’indicateur dans le code du module de trading

La prochaine étape de notre travail est la plus méticuleuse. Nous devons remplacer tout ce qui concerne les paramètres d’entrée de l’indicateur dans le code du module de trading. Le processus est très similaire à ce qui a été indiqué dans l’article « Assistant MQL5 : Comment créer un module de signaux de trading ».

Tout d’abord, nous devrions apporter quelques modifications au bloc commenté de la description de la classe de signaux de trading MQL5 Wizard :

//+----------------------------------------------------------------------+
//| Description of the class                                             |
//| Title=The signals based on BykovTrend indicator                      |
//| Type=SignalAdvanced                                                  |
//| Name=BykovTrend                                                      |
//| Class=CBykovTrendSignal                                              |
//| Page=                                                                |
//| Parameter=BuyPosOpen,bool,true,Permission to buy                     |
//| Parameter=SellPosOpen,bool,true,Permission to sell                   |
//| Parameter=BuyPosClose,bool,true,Permission to exit a long position   |
//| Parameter=SellPosClose,bool,true,Permission to exit a short position |
//| Parameter=Ind_Timeframe,ENUM_TIMEFRAMES,PERIOD_H1,Timeframe          |
//| Parameter=RISK,int,4,Risk level                                      |
//| Parameter=SSP,int,9,SSP                                              |
//| Parameter=SignalBar,uint,1,Bar index for entry signal                |
//+----------------------------------------------------------------------+
//--- wizard description end
//+----------------------------------------------------------------------+
//| CBykovTrendSignal class.                                             |
//| Purpose: Class of generator of trade signals based on                |
//| BykovTrend indicator https://www.mql5.com/ru/code/497/.               |
//|             Is derived from the CExpertSignal class.                 |
//+----------------------------------------------------------------------+

Les deux indicateurs contiennent la même variable d’entrée RISK, on n’y touche pas. Mais dans ces indicateurs, sa valeur par défaut est différente. En fait, cette différence n’est pas critique et peut être laissée inchangée. La ligne de commentaire sur la variable SSP a été ajoutée :

//| Parameter=SSP,int,9,SSP                                    |

Et le lien vers l’indicateur Base de code a été remplacé :

//| Purpose: Class of generator of trade signals based on      |
//| BykovTrend values https://www.mql5.com/ru/code/497/.        |

Maintenant, tout ce qui concerne les changements de paramètres d’entrée devrait être reflété dans la description de la classe de signaux de trading CBykovTrendSignal. Nous avons la ligne de la nouvelle déclaration globale de variable de classe m_SSP dans les paramètres de configurations :

   uint              m_SSP;              // SSP

 et la ligne de la nouvelle déclaration de méthode d’installation des paramètres de configurations SSP() :

   void               SSP(uint value)                         { m_SSP=value;              } 

Tout ce qui concerne la variable d’entrée RISK dans le module de signaux de trading que nous créons est équivalent au module d’entrée et, par conséquent, il n’y a aucun changement dans les blocs de module de trading actuels et autres.

Maintenant, nous passons au constructeur de classe CBykovTrendSignal::CBykovTrendSignal(). L’initialisation d’une nouvelle variable doit être ajoutée dans ce bloc :

   m_SSP=4;

La vérification de l’exactitude de la nouvelle variable doit être effectuée dans CBykovTrendSignal::ValidationSettings() settings parameters verification block:

   if(m_SSP<=0)
     {
      printf(__FUNCTION__+": SSP must be above zero");
      return(false);
     }

Après cela, nous pouvons passer au bloc d’initialisation de l’indicateur BykovTrend - BykovTrendSignal::InitBykovTrend(). Le nouvel indicateur a un nombre différent de variables d’entrée et, par conséquent, la dimension du tableau de paramètres d’entrée déclarés sera également différente :

//--- setting the indicator parameters
   MqlParam parameters[3];

Dans notre cas, nous avons besoin d’une dimension pour le nom de la chaîne d’indicateur et de deux autres pour ses paramètres d’entrée.

Maintenant, nous devons initialiser une nouvelle cellule des tableaux de paramètres d’entrée, en indiquant le type de la variable qui y sera stockée :

   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=m_SSP;

 Après cela, modifiez le nombre de variables d’entrée de 3 dans ce bloc dans l’appel pour l’initialisation de l’indicateur :

//--- object initialization   
   if(!m_indicator.Create(m_symbol.Name(),m_Ind_Timeframe,IND_CUSTOM,3,parameters))

Le nombre de tampons d’indicateurs dans l’indicateur reste le même et égal à deux, par conséquent, il n’est pas nécessaire de changer quoi que ce soit dans la ligne d’initialisation du numéro de tampons d’indicateur dans notre cas :

//--- number of buffers
   if(!m_indicator.NumBuffers(2))  return(false);

Les indicateurs ASCtrend et BykovTrend ont chacun deux tampons d’indicateurs. Les fonctions des tampons sont complètement similaires. Le tampon zéro est utilisé pour stocker les signaux de vente, tandis que le tampon ayant l’indice 1 est utilisé pour stocker les signaux d’achat. Ainsi, il n’est pas nécessaire de changer quoi que ce soit dans les blocs de fonctions pour fournir CBykovTrendSignal::LongCondition() et CBykovTrendSignal::ShortCondition() les signaux de trading, alors le travail sur la modification du module de signaux de trading peut être considéré comme terminé.

Mais en général, tous les indicateurs de sémaphore sont différents et, par conséquent, ces blocs pour différents indicateurs de sémaphore peuvent différer considérablement les uns des autres. L’archive MySignals.zip du module de trading et l’archive Indicators.zip appropriée contiennent suffisamment d’exemples pour créer divers indicateurs. Après examen, il est possible de connaître les détails du processus de remplacement et les versions de code possibles pour cela.

Maintenant, je voudrais me concentrer sur la variable d’entrée Ind_Timeframe du module de signaux de trading. Cette variable permet de télécharger un délai approprié à l’indicateur. Cependant, l’Expert Advisor généré fonctionne selon le délai auquel il a été affecté. Cela signifie que le délai de la variable d'entrée Ind_Timeframe ne doit jamais dépasser une période du graphique sur lequel l’Expert Advisor fonctionne pour assurer le fonctionnement normal du module.

Enfin, je voudrais révéler une autre particularité de la création de modules de signaux de trading. Parfois, des énumérations personnalisées sont implémentées dans le code d’indicateur de base sous forme de types des variables d’entrée du module. Par exemple, l’énumération personnalisée Smooth_Method est utilisée comme type de variable MA_SMethod pour Candles_Smoothed indicateur :

//+-----------------------------------+
//|  Declaration of enumerations      |
//+-----------------------------------+
enum Smooth_Method
  {
   MODE_SMA_,  // SMA
   MODE_EMA_,  // EMA
   MODE_SMMA_, // SMMA
   MODE_LWMA_, // LWMA
   MODE_JJMA,  // JJMA
   MODE_JurX,  // JurX
   MODE_ParMA, // ParMA
   MODE_T3,    // T3
   MODE_VIDYA, // VIDYA
   MODE_AMA,   // AMA
  }; */
//+----------------------------------------------+
//| Indicator input parameters                   |
//+----------------------------------------------+
input Smooth_Method MA_SMethod=MODE_LWMA; // Smoothing method
input int MA_Length=30;                   // Smoothing depth                    
input int MA_Phase=100;                   // Smoothing parameter
                                          // for JJMA varying within the range -100 ... +100,
                                          // for VIDIA it is a CMO period, for AMA it is a slow average period
//+----------------------------------------------+

Dans ce cas, les variables d’entrée de ce type et tous les éléments associés dans le module des signaux de trading (Candles_SmoothedSignal.mqh) doivent être modifiés en variables de types int ou uint. En outre, la procédure inverse d’énumérations personnalisées jusqu’aux paramètres d’entrée de l’Expert Advisor et le remplacement des types de variables d’entrée nécessaires (ExpM_Candles_Smoothed Expert Advisor) doivent être effectués pour faciliter l’utilisation de ces variables d’entrée dans le code déjà généré de l’Expert Advisor achevé :

//+------------------------------------------------------------------+
//|  Declaration of enumerations                                     |
//+------------------------------------------------------------------+
enum Smooth_Method
  {
   MODE_SMA_,  // SMA
   MODE_EMA_,  // EMA
   MODE_SMMA_, // SMMA
   MODE_LWMA_, // LWMA
   MODE_JJMA,  // JJMA
   MODE_JurX,  // JurX
   MODE_ParMA, // ParMA
   MODE_T3,    // T3
   MODE_VIDYA, // VIDYA
   MODE_AMA,   // AMA
  };
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string          Expert_Title         ="Candles_Smoothed"; // Document name
ulong                 Expert_MagicNumber   =29976;              // 
bool                  Expert_EveryTick     =false;              // 
//--- inputs for main signal
input int             Signal_ThresholdOpen =40;                 // Signal threshold value to open [0...100]
input int             Signal_ThresholdClose=20;                 // Signal threshold value to close [0...100]
input double          Signal_PriceLevel    =0.0;                // Price level to execute a deal
input double          Signal_StopLevel     =50.0;               // Stop Loss level (in points)
input double          Signal_TakeLevel     =50.0;               // Take Profit level (in points)
input int             Signal_Expiration    =1;                  // Expiration of pending orders (in bars)
input bool            Signal__BuyPosOpen   =true;               // Candles_Smoothed() Permission to buy
input bool            Signal__SellPosOpen  =true;               // Candles_Smoothed() Permission to sell
input bool            Signal__BuyPosClose  =true;               // Candles_Smoothed() Permission to exit a long position
input bool            Signal__SellPosClose =true;               // Candles_Smoothed() Permission to exit a short position
input ENUM_TIMEFRAMES Signal__Ind_Timeframe=PERIOD_H1;            // Candles_Smoothed() Timeframe
input Smooth_Method   Signal__MA_SMethod   =4;                  // Candles_Smoothed() Smoothing method (1 - 10)
input uint            Signal__MA_Length    =30;                 // Candles_Smoothed() Smoothing depth
input uint            Signal__MA_Phase     =100;                // Candles_Smoothed() Smoothing parameter
input uint            Signal__SignalBar    =1;                  // Candles_Smoothed() Bar index for the entry signal
input double          Signal__Weight       =1.0;                // Candles_Smoothed() Weight [0...1.0]
//--- inputs for money
input double          Money_FixLot_Percent =10.0;               // Percent
input double          Money_FixLot_Lots    =0.1;                // Fixed volume

Dans notre cas, cela a été fait avec la variable d’entrée Signal__MA_SMethod.

Vous pouvez accélérer considérablement la modification du code si vous ouvrez les deux versions de code (ASCtrendSignal.mqh et BykovTrendSignal.mqh) simultanément dans l’éditeur (en plaçant l’une sur le côté gauche et l’autre sur le côté droit) pour comparer soigneusement les deux versions du code.

Conclusion

J’ai placé une quantité suffisante d’Expert Advisors basés sur le système de trading de sémaphores dans l’archive Experts.zip jointe à cet article pour permettre aux créateurs novices d’Expert Advisors de comprendre facilement toutes les fonctionnalités de l’écriture d’un tel code ou au moins de travailler avec des Expert Advisors prêts à l’emploi en utilisant des indicateurs les plus populaires.

Tous les Expert Advisors ci-joints sont également présentés comme des modules de trading pour ceux qui souhaitent utiliser le générateur de stratégies de trading comme base pour leurs propres systèmes de trading. Ces modules sont situés dans MySignals.zip, tandis que les systèmes de trading sur lesquels ils sont basés peuvent être trouvés dans Expertsez.zip. Les indicateurs utilisés dans les Expert Advisors sont placés dans indicateurs.zip. Les chemins d’accès pour l’extraction des fichiers sont les suivants :

  • Experts.zip: "\MQL5\Experts\" ;
  • Expertsez.zip: "\MQL5\Experts\" ; 
  • MySignals.zip: "\MQL5\Include\Expert\Signal\MySignals\" ; 
  • Indicators.zip: "\MQL5\Indicators\" ;
  • SmoothAlgorithms.mqh: "\Include\" ;
  • TradeAlgorithms.mqh: "\Include\".

Redémarrez MetaEditor, puis ouvrez la fenêtre Navigator, ensuite faites un clic droit sur l’étiquette MQL5 et sélectionnez « Compiler » dans le menu contextuel.

Le fichier SmoothAlgorithms.mqh est nécessaire pour la compilation de certains indicateurs à partir d’Indicateurs.zip, tandis que le fichier TradeAlgorithms.mqh est nécessaire pour la compilation de tous les Expert Advisors d’Experts.zip.

Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/358

Fichiers joints |
expertsez.zip (31.51 KB)
mysignals.zip (44.08 KB)
indicators.zip (39.15 KB)
experts.zip (34.67 KB)
Créez votre propre robot de trading en 6 étapes ! Créez votre propre robot de trading en 6 étapes !
Si vous ne savez pas comment les classes de trades se construisent et que vous avez peur des mots tels que « Programmation orientée objet », alors cet article est pour vous. En fait, vous n'avez pas besoin de connaître les détails pour écrire votre propre module de signaux de trading. Suivez simplement quelques règles simples. Tout le reste sera fait par l'assistant MQL5, et vous obtiendrez un robot de trading prêt à l'emploi !
Approche orientée objet pour créer des panneaux multi-délais et multi-devises Approche orientée objet pour créer des panneaux multi-délais et multi-devises
Cet article décrit comment la programmation orientée objet peut être utilisée pour créer des panneaux multi-délais et multi-devises pour MetaTrader 5. L'objectif principal est de créer un panneau universel, qui peut être utilisé pour afficher de nombreux types de données, tels que les prix, les changements de prix, les valeurs des indicateurs ou les conditions d'achat/vente personnalisées sans avoir besoin de modifier le code du panneau lui-même.
MetaTrader 5 - Plus que vous ne pouvez l'imaginer ! MetaTrader 5 - Plus que vous ne pouvez l'imaginer !
Le terminal client MetaTrader 5 a été développé à partir de zéro et surpasse de loin son prédécesseur, c’est bien évident. La nouvelle plateforme de trading offre des opportunités illimitées de trading sur n'importe quel marché financier. De plus, ses fonctionnalités ne cessent de développer pour offrir des fonctionnalités et une commodité encore plus utiles. Il est donc désormais assez difficile de lister tous les nombreux avantages de MetaTrader 5. Nous avons essayé de les décrire brièvement dans un article, et nous avons été surpris du résultat. L'article est loin d'être bref !
Les bases de la programmation orientée objet Les bases de la programmation orientée objet
Vous n'avez pas besoin de savoir ce que sont le polymorphisme, l'encapsulation, etc. pour utiliser la programmation orientée objet (POO)... vous pouvez simplement utiliser ces fonctionnalités. Cet article couvre les bases de la POO avec des exemples pratiques.