English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Les Principes du Calcul Économique des Indicateurs

Les Principes du Calcul Économique des Indicateurs

MetaTrader 5Indicateurs | 17 novembre 2021, 15:31
138 0
Nikolay Kositsin
Nikolay Kositsin

Introduction

L’idée de préserver les ressources dans l’un ou l’autre segment des activités pratiques des personnes - est peut-être l’un des sujets les plus importants et les plus urgents sur la voie du développement humain et du progrès. La programmation en MQL5, à cet égard, ne fait pas exception. Bien sûr, si l’ensemble de tâches se limite uniquement au trading visuel, de nombreux défauts de programmation peuvent passer inaperçus.

Mais tout ce qui concerne le trading automatisé nécessite initialement une écriture du code économique maximale, sinon, le processus de test et d’optimisation des robots de trading peut s’allonger sur une si longue période de temps, qu’il serait pratiquement impossible d’attendre leur achèvement. L’idée de créer quelque chose de valeur dans ce type de situation semble douteuse.

Donc, avant de se lancer dans l’implémentation de stratégies de trading, il serait logique de mieux se familiariser avec ces détails de la programmation, qui ont un effet sur le temps d’optimisation et de test des Expert Advisors. Et puisque la majorité des Expert Advisors contiennent des appels aux indicateurs de l’utilisateur dans leurs codes, alors je suppose, nous devrions commencer par eux.

En général, il n’y a pas beaucoup de points pertinents, qui doivent être gardés à l’esprit lors de l’élaboration d’indicateurs, il est donc plus logique de simplement examiner chacun d’eux dans l’ordre.

Recalcul sur chaque tick d’indicateur de ceux qui n’ont pas encore été calculés, les barres fraichement apparues dans les indicateurs classiques

L’essence même des indicateurs classiques, tels que RSI, ADX, ATR, CCI, etc., est que sur les barres fermées, le calcul de ces indicateurs ne peut être effectué qu’une seule fois, et après cela, les calculs ne peuvent être effectués que sur les barres nouvellement émergentes. La seule exception est la barre ouverte actuelle, sur laquelle le calcul est effectué à maintes reprises à chaque coche, jusqu’à ce que cette barre soit fermée.

Le moyen le plus simple de savoir s’il est raisonnable de calculer les indicateurs sur des barres non calculées - est de comparer dans le testeur de stratégie, les résultats de l’exécution de tels indicateurs (optimisés) avec les indicateurs, calculés sur toutes les barres, tout le temps (non optimisés).

Cela se fait assez aisément Un Expert Advisor est créé avec la fonction vide onInit () et OnTick (). Tout ce que vous avez à faire est d’écrire l’appel dans l’Expert Advisor de la version requise de l’indicateur optimisé ou non optimisé, et d’apprécier les résultats des exécutions dans le testeur de ces experts dans les deux cas. A titre d’exemple, je vais prendre l’indicateur SMA.mq5 de mon article «User Indicators in MQL5 for Beginners », dans lequel je vais faire un remplacement de ligne.  

   if (prev_calculated == 0) // if this is the first start, then make a recalculation of all existing bars
    first = MAPeriod - 1 + begin;
   else first = prev_calculated - 1; // on all subsequent starts, make calculations only on newly appeared bars

sur 

   first = MAPeriod -  1  + Begin;  / / On all ticks the bars are being recalculated 

En conséquence, j’obtiens une version non optimisée du code de programmation (SMA !!!!!!. mq5), qui, contrairement à l’original, recalculera toutes ses valeurs sur chaque coche. Strictement parlant, les versions du code expert dans les deux cas sont pratiquement identiques, donc je ne fournirai qu’une seule d’entre elles (SMA_Test.mq5)

//+------------------------------------------------------------------+
//|                                                     SMA_Test.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
int Handle;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//----+
   //----+ Obtaining the indicator handle
   Handle = iCustom(Symbol(), 0, "SMA");
   if (Handle == INVALID_HANDLE)
     Print(" Not able to obtain the indicator handle SMA");
//----+
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//----+
    //--- Release the indicator handle
    IndicatorRelease(Handle);
//----+   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//----+
   double SMA[1];
   //----+ Using the indicator handle, copy the values of the indicator 
                   // buffer in a specially prepared for this statistical array
   CopyBuffer(Handle, 0, 0, 1, SMA);
//----+
  }
//+------------------------------------------------------------------+

Nous pouvons démarrer les tests maintenant. Il convient de noter que dans tous les tests de cet article, nous utiliserons un mode de simulation des changements de barre, qui est aussi proche que possible de la réalité - « Chaque tick »!

Fig.1 Configurations de test de l’Expert Advisor SMA_Test 

Voici le résultat de l’exécution d’un indicateur optimisé dans le testeur :

Fig.2 Le résultat du test del’Expert Advisor SMA_Test 

La couleur rouge indique le temps pendant lequel le test a été effectué avec succès. Je ne peux pas dire que c’est trop! Mais pour l’accomplissement des tests, l’indicateur SMA !!!!!!. mq5 nous avons dû attendre très longtemps!

Fig.3 Le résultat du test de l’Expert Advisor SMA !!!!!! _Test 

Fondamentalement, le temps de traitement du test dans ce cas diffère du test précédent de plus de 500 fois. Et ce malgré le fait qu’une durée de test suffisamment courte a été sélectionnée. Mais alors que lors des tests de l’Expert Advisor, nous pouvons supporter des coûts de calcul aussi importants, nous ferions mieux d’oublier l’optimisation de leurs paramètres!

Et par conséquent, c’est la preuve la plus éloquente du fait qu’un code économiquement rédigé - n’est pas seulement un passe-temps pour les professionnels dans le domaine de la programmation, mais plutôt une approche assez actuelle pour écrire votre propre code.

Sur Internet, il existe tout un site Web Overclockers.ru dédié à l’accélération des ordinateurs personnels afin de maximiser ses performances. Le moyen de base de cette pratique est l’utilisation de composants informatiques beaucoup plus coûteux pour augmenter la vitesse d’horloge du processeur et de la mémoire RAM.

Une fois cela fait, un système de refroidissement par eau plus coûteux, ou même une immersion dans un processeur à azote liquide, est utilisé pour ce processeur surcadencé. Le résultat de telles actions est double, voire trois fois plus de performances du PC.

Une écriture compétente et économique du code peut souvent nous aider à réaliser beaucoup, tout en consentant très peu d’efforts. Bien sûr, cette méthode n’est pas en mesure de transformer un Celleron300A en un Core 2 Quad Q6600, mais elle nous permet de faire fonctionner un PC régulier, à budget standard, d’une manière qui ne serait attendue que d’un ordinateur haut de gamme!

Recalcul répété de la barre fermée actuelle dans certains indicateurs, pas tout à fait classiques

Et tout serait génial si cette méthode d’optimisation du code de programme était adaptée à tous les indicateurs sans distinction! Mais, hélas, ce n’est pas vrai. Il existe tout un groupe d’indicateurs qui conformément à une telle approche, ne commencent normalement à calculer qu’une seule fois, lors du chargement de l’indicateur sur des données historiques déjà existantes.

Et sur toutes les barres qui ont émergé après le chargement de l’indicateur, ses valeurs s’avèrent complètement erronées. La principale cause pour laquelle cela se produit est que certaines variables du code de l’indicateur dépendent de ces indicateurs, qui avaient les mêmes variables après le calcul de l’indicateur sur la barre précédente. Officiellement, il se présentera comme suit:

                                                                                                                                                                                                                           

certaine variable(barre) = Fonction(certaine variable(bar - 1))

 

  • SomeVariable() — la valeur d’une variable pour une barre ;
  • bar - numéro de barre, sur lequel le calcul est effectué.

Pour des raisons évidentes, dans le code réel, ces dépendances ont une forme fonctionnelle moins claire. Mais l’essence de cela ne change pas, par exemple, pour déplacer T3 (indicateur non optimisé - T3 !!!!!!. mq5) la partie du code, pertinente pour nous, ressemble à ceci

   e1 = w1 * series + w2 * e1;
   e2 = w1 * e1 + w2 * e2;
   e3 = w1 * e2 + w2 * e3;
   e4 = w1 * e3 + w2 * e4;
   e5 = w1 * e4 + w2 * e5;
   e6 = w1 * e5 + w2 * e6;
   //----  
   T3 = c1 * e6 + c2 * e5 + c3 * e4 + c4 * e3;

Les variables e1, e2, e3, e4, e5, e6 ont précisément une telle dépendance fonctionnelle, ce qui implique l’utilisation de ce code pour le calcul de chaque nouvelle barre une seule fois! Mais la barre actuelle, à travers un calcul similaire, sera ignorée à plusieurs reprises jusqu’à ce qu’elle soit fermée.

Et les valeurs de ces variables sur la barre actuelle changeront tout le temps, bien que pour la barre actuelle, avant de la modifier, elles devraient rester telles qu’elles étaient après le calcul sur la barre précédente!

Et par conséquent, les valeurs de ces variables sur la barre précédente (par rapport à la barre actuelle) doivent être enregistrées dans les variables statiques, et les transférer pour être réutilisées jusqu’à la prochaine modification de la barre, sur laquelle les avant-dernières valeurs des variables doivent être à nouveau enregistrées e1, e2, e3, e4, e5 , e6.

Le code supplémentaire, qui effectue des manipulations similaires avec les valeurs, est assez simple. Tout d’abord, vous devez déclarer les variables statiques locales pour stocker les valeurs dans la fonction OnCalculate ()

   //---- declare the static variables for storing the valid values of the coefficients
   static double e1_, e2_, e3_, e4_, e5_, e6_;

Après cela, faire la mémorisation des valeurs des variables dans le cycle sur la barre actuelle avant tout calcul, au moment où le nombre de barres nouvellement apparues est supérieur à zéro:

     //---- memorize the values of variables before the run on the current bar
     if (rates_total != prev_calculated && bar == rates_total - 1)
      {
       e1_ = e1;
       e2_ = e2;
       e3_ = e3;
       e4_ = e4;
       e5_ = e5;
       e6_ = e6;
      }

Et avant le bloc de l’opérateur de cycle, restaurez les valeurs des variables par transformation inverse :

   //---- restore the values of the variables
   e1 = e1_;
   e2 = e2_;
   e3 = e3_;
   e4 = e4_;
   e5 = e5_;
   e6 = e6_;

Assez naturellement, l’initialisation de départ des coefficients calculés ne se fait qu’une seule fois, au premier démarrage de la fonction OnCalculate (), et maintenant l’initialisation n’est pas faite des coefficients eux-mêmes, mais des variables statiques correspondantes.

//---- calculating the starting number first for the cycle of recalculation of bars
   if (prev_calculated == 0) // verification of the first start of the indicator calculation
    {
     first = begin; // the starting number for calculating all of the bars
     //---- the starting initialization of calculated coefficients
     e1_ = price[first];
     e2_ = price[first];
     e3_ = price[first];
     e4_ = price[first];
     e5_ = price[first];
     e6_ = price[first];
    }

En conséquence, l’indicateur final T3.mq5 a commencé à entamé les calculs de la manière la plus rentable. Tout serait rien, mais ce n’est pas toujours que des dépendances fonctionnelles similaires peuvent être si facilement identifiées. Dans ce cas, les valeurs de toutes les variables indicatrices peuvent être mémorisées dans des variables statiques et restaurées de la même manière.

Et ce n’est qu’après que nous pourrons commencer à deviner quelles variables doivent vraiment être récupérées et pour lesquelles il n’y a pas un tel besoin. Pour ce faire, nous devons accrocher au graphique les versions non optimisées et optimisées de l’indicateur et vérifier leur travail, en supprimant progressivement de la liste de récupération une variable à la fois. En fin de compte, il ne nous reste que ces variables, qui doivent vraiment être récupérées.

Naturellement, j’ai fourni cette version de la logique pour travailler avec le code du programme des indicateurs normaux, dans lequel il y a un recalcul de la barre actuelle et des barres émergentes. Pour les indicateurs, qui repeignent et se tournent vers l’avenir, nous ne serons pas en mesure de créer une méthode analogue, très standard et simple de code d’optimisation, en raison des caractéristiques uniques de ces indicateurs. Et la majorité des rédacteurs Expert Advisor expérimentés n’en voient pas vraiment le besoin. Par conséquent, c’est là que nous pouvons considérer l’analyse détaillée de ces indicateurs comme étant achevée.

Caractéristiques des appels d’indicateurs, qui peuvent rendre le code MQL5 excessivement lent 

Il semblerait que la tâche soit terminée, nous avons un indicateur optimisé, qui compte les barres de la manière la plus économique, et maintenant il suffit d’écrire quelques lignes de code, et d’appeler cet indicateur dans le code de l’Expert Advisor ou de l’indicateur pour obtenir les valeurs calculées à partir du tampon de l’indicateur.

Mais ce n’est pas aussi évident qu’il n’y paraît si on l’abordait dans une affaire formelle, sans prendre la peine de comprendre quel type d’opérations se cachent derrière ces quelques lignes de code.

Les spécificités de l’obtention des valeurs de l’utilisateur et des indicateurs techniques, tout comme à partir des séries chronologiques dans MQL5, sont que cela se fait en copiant les données dans les tableaux de variables des utilisateurs. Cela peut conduire à une accumulation de données complètement inutiles, pour les comptes courants.

Le moyen le plus simple de vérifier tout cela sur une mise sous séquestre de données spécifique à partir d’un indicateur technique. À titre d’exemple, nous pouvons prendre l’iAMA mobile et construire, sur la base de cet indicateur technique, un indicateur personnalisé AMkA.

Pour copier les données, nous utiliserons la première version de l’appel de fonction CopyBuffer (), avec une requête à la position de départ et le nombre d’éléments requis pour le copiage. Dans l’indicateur AMkA, l’incrémentation Mobile sur la barre actuelle est traitée à l’aide d’un indicateur technique Écart type, et puis, pour obtenir les signaux de trading, cet incrément est comparé à la valeur totale de l’écart type traitée.

Par conséquent, dans le cas le plus simple pour l’implémentation de l’indicateur AMkA, vous devez d’abord créer un indicateur, dans lequel le tampon de l’indicateur contenait la valeur de l’incrémentation en mouvement (indicateur dAMA). Et puis, dans un autre indicateur, en utilisant la poignée de l’indicateur avec des incréments AMA, nous obtenons la valeur résultante, traitée par l’indicateur d’écart type .

Le processus de création d’indicateurs analogues a déjà été examiné en détail dans divers articles sur ces sujets, je ne vais donc pas m’arrêter dessus, et analyser uniquement les détails de l’accès aux tampons d’indicateurs de l’indicateur appelé, dans le code d’un autre indicateur.

Dans la vaste ressource d’Internet, nous voyons déjà l’émergence d’exemples MQL5, dans lesquels leurs auteurs copient littéralement tout le contenu des tampons d’indicateurs dans les tableaux dynamiques intermédiaires. Et après cela, toutes les valeurs, une par une, sont transférées dans les tampons d’indicateurs finaux à partir de ces tableaux intermédiaires, à l’aide de l’opérateur de cycle.

Pour résoudre notre problème, cette approche semble la plus simple

   if (CopyBuffer(AMA_Handle, 0, 0, rates_total, Array) <= 0) return(0);
   ArrayCopy(AMA_Buffer, Array, 0, 0, WHOLE_ARRAY);

(Indicateur dAMA !!!!!!. mq5) Ou comme ça 

   if (CopyBuffer(AMA_Handle, 0, 0, rates_total, Array) <= 0) return(0);
   
   for(bar = 0; bar < rates_total; bar++)
    {
     AMA_Buffer[bar] = Array[bar];
     /*
      here is the code of indicator calculations
    */     
    }

Mais quel est le prix d’une solution aussi modeste ? Tout d’abord, il serait préférable d’acquérir un peu de compréhension de ce qui serait la ligne de conduite rationnelle maximale. Tout d’abord, il n’y a pas de raison sérieusement avancée d’utiliser le tableau intermédiaire Array [], et les données doivent être copiées directement dans le tampon indicateur AMA [].

Deuxièmement, à chaque coche d’indicateur, il est nécessaire de copier les valeurs uniquement dans trois cas:

  • des barres nouvellement apparues
  • à partir de barres fermées,
  • à partir des barres ouvertes actuelles.

Les valeurs restantes dans le tampon de l’indicateur existent déjà, et il n’y a aucun sens à les réécrire plusieurs fois. 

//--- calculation of the required number of copied data
   int to_copy;
   if(prev_calculated > rates_total || prev_calculated <= 0)// verification for the first start of indicator calculation
        to_copy = rates_total - begin; // calculated number of all bars
   else to_copy = rates_total - prev_calculated + 1; // calculated number of only new bars

//--- copy the reappearing data into the indicator buffer AMA_Buffer[]
   if (CopyBuffer(AMA_Handle, 0, 0, to_copy, AMA_Buffer) <= 0)
    return(0); 

 Il est tout à fait naturel que le code final dans ce cas soit un peu plus complexe (Indicateur dAMA.mq5), mais nous pouvons maintenant utiliser la méthodologie, proposée par moi au début de cet article, pour effectuer des tests dans les deux cas, et tirer les conclusions appropriées. Cette fois, augmentons la durée de test à un an.

Fig.4 Configurations de test de l’Expert Advisor dAMA_Test
 

Enfin, après avoir réussi le test dans le journal de stratégie du testeur, nous obtenons le temps nécessaire pour tester l’Expert Advisor dAMA_Test

Fig.5 Le résultat du test d l’Expert Advisor dAMA_Test

Le temps de passage de l’essai qui en résulte est de 43 937 ms est dans une fourchette raisonnable. Ce qui, malheureusement, ne peut pas être dit sur le temps analogue résultant de passage du test avec l’Expert Advisor dAMA !!!!!! _ Essai

Fig.6 Le résultat de passage du test expert dAMA !!!!!! _
  

Le temps de passage du test est de 960 625 ms, soit vingt fois plus long que dans le cas précédent. La conclusion semble assez évidente. Le code doit être écrit de la manière la plus économique, afin qu’il n’effectue aucun calcul inutile!
L’indicateur AMkA, élaboré sur les principes décrits ci-dessus, ne démontre rien de nouveau, donc je vais m’arrêter uniquement sur les détails du copiage des données dans ce cas.

//---- declaring local arrays
   double dAMA_Array[], StdDev_Array[];
//---- indexation of elements in arrays just like in time series
   ArraySetAsSeries(dAMA_Array, true);
   ArraySetAsSeries(StdDev_Array, true);

//--- calculation of the number of copied data
   int to_copy;
   if(prev_calculated > rates_total || prev_calculated <= 0)// verification of the first start of indicator calculation
        to_copy = rates_total - begin; // calculated number of all bars
   else to_copy = rates_total - prev_calculated + 1; // calculated number of only new bars
   
//--- copy the newly appeared data into the indicator buffer and local dynamic arrays
   if(CopyBuffer(dAMAHandle,   1, 0, to_copy, AMABuffer   ) <= 0) return(0);
   if(CopyBuffer(dAMAHandle,   0, 0, to_copy, dAMA_Array  ) <= 0) return(0);
   if(CopyBuffer(StdDevHandle, 0, 0, to_copy, StdDev_Array) <= 0) return(0);

Tout est fait de manière complètement analogue, sauf que maintenant les données sont copiées dans un seul tampon d’indicateur et deux tableaux dynamiques déclarés localement pour les calculs intermédiaires. 

L’implémentation de tous les calculs d’indicateurs dans l’indicateur, comme l’un des moyens d’optimisation 

Tout cela est très intéressant, mais une structure aussi complexe d’appels successifs d’utilisateurs et d’indicateurs techniques semble un peu trop suspicieuse. Et il devrait être mesuré d’une manière ou d’une autre. Mais pour ce faire, cela ne ferait pas de mal d’avoir le code de l’indicateur AMkA, qui serait situé dans l’indicateur de l’utilisateur, et n’utiliserait pas les appels pour d’autres indicateurs.

Pour un programmeur qui a bien assimilé le processus d’écriture d’indicateurs sur MQL5, ce problème ne nécessite pas beaucoup d’efforts. Tout d’abord, le code de l’indicateur de l’utilisateur AMA.mq5 est écrit, puis les éléments nécessaires du code y sont ajoutés pour l’implémentation de l’indicateur AMkA_.mq5. Nous recevons un autre deuxième grand cycle de calcul d’indicateur, dans lequel le tableau d’utilisateurs est chargé avec l’incrément de l’indicateur AMA,

   //---- the main cycle of calculating the AMkA indicator
   for(bar = first; bar < rates_total; bar++)
    {
     //---- load the increments of the AMA indicator into the array for intermediate calculations
     for(iii = 0; iii < ama_period; iii++)
      dAMA[iii] = AMABuffer[bar - iii - 0] - AMABuffer[bar - iii - 1]; 

ensuite, ce tableau est utilisé pour effectuer des opérations, analogues au calcul de l’indicateur technique StDev basé sur les données de l’indicateur dAMA.mq5.

     //---- find the simple average of increments of AMA
     Sum = 0.0;
     for(iii = 0; iii < ama_period; iii++)
      Sum += dAMA[iii];
     SMAdif = Sum / ama_period;
     
     //---- find the sum of the square differences of increments and the average
     Sum = 0.0;
     for(iii = 0; iii < ama_period; iii++)
      Sum += MathPow(dAMA[iii] - SMAdif, 2);
     
     //---- determine the final value of the meansquare deviation of StDev from the increment of AMA
     StDev = MathSqrt(Sum / ama_period);

Le reste du code est absolument analogue au code de l’indicateur AMkA.mq5 et ne présente aucun intérêt particulier pour nous. Nous pouvons maintenant commencer à tester les indicateurs AMkA_.mq5 et AMkA.mq5 à l’aide d’Expert Advisors AMkA__Test.mq5 et AMkA_Test.mq5.

Il n’y a pas de difficultés liées au teste d’indicateur AMkA_.mq5, et le temps de test est bien dans le cadre acceptable

Fig.7 Le résultat de  passage du test à l’aide de l’Expert Advisor AMkA__Test
 

Mais l’indicateur AMkA.mq5 était incroyablement lent

Fig.8 Le résultat de  passage du test à l’aide de l’Expert Advisor AMkA_Test
 

Son résultat s’est avéré être jusqu’à sept fois pire que celui de son « frère ». Quels autres commentaires peuvent-ils y avoir? La conclusion est assez évidente: que l’élaboration de tells constructions aussi complexes, consistant en plusieurs appels consécutifs d’indicateurs, l’un à l’autre, n’est pas très prudente et ne convient que pour des tests préliminaires!

Évidemment, ces résultats ont été obtenus sur une version de test du terminal client, et il est difficile de se prononcer à l’heure actuelle à quoi tout cela ressemblera à l’avenir. Mais en ce qui concerne le prochain championnat de robots de trading, on peut assez clairement affirmer qu’il s’agit d’un sujet pertinent et efficace.

Quelques caractéristiques d’appel d’indicateurs à partir des Expert Advisors

Tout ce qui est lié à l’optimisation de l’accès aux données de l’utilisateur et aux indicateurs techniques dans le code de programmation des indicateurs, est également applicable à l’optimisation de l’accès aux données de l’utilisateur et aux indicateurs techniques dans le code de programme des Expert Advisors. En plus des situations déjà présentées, le code Expert Advisor a un autre facteur, qui peut considérablement affecter les tests et l’optimisation des systèmes de trading.

Un grand nombre d’Expert Advisors traitent généralement les données de l’indicateur uniquement au moment du changement de barre, et pour cette raison, dans ces Expert Advisors, il n’est pas nécessaire d’afficher la fonction CopyBuffer () pour chaque coche.

Dans cette situation, il est nécessaire que les Expert Advisors obtiennent les données des tampons d’indicateurs uniquement lors d’un changement de barre. Ainsi, les appels des indicateurs doivent être situés dans le bloc derrière les parenthèses, dont l’accès n’est autorisé qu’une seule fois pour chaque modification de la barre, si toutes les données nécessaires du tampon d’indicateurs sont copiées avec succès dans les tableaux pour les calculs intermédiaires.

La meilleure chose qui sert de filtre est une fonction utilisateur, qui renvoie une unité logique à un moment où il y a eu un changement de la barre actuelle. Le fichier IsNewBar.mqh contient ma version assez universelle de cette fonction :

bool IsNewBar
            (
             int Number, // Number of call to the function IsNewBar in the program code of the expert Advisor
             string symbol, // The chart symbol on which the data calculation is done
             ENUM_TIMEFRAMES timeframe // Timeframe of the chart on which the data calculation is done
            )

Lorsque vous utilisez cette fonction dans le code Expert Advisor, elle peut ressembler à ceci :

    //---- declaration of a static variable - array for storing the values of the AMA indicator
    static double AMA_Array[3];

    //---- calling up the AMA indicator for copying its values into the AMA_Array array
    if (IsNewBar(0, Symbol(), 0))
     {
      CopyBuffer(AMA_Handle, 0, 1, 3, AMA_Array); 
     }

Mais il est beaucoup plus rationnel d’agir différemment dans ce cas. Le fait est que lorsque vous appelez le CopyBuffer (), les données du tableau AMA_Array [] peuvent ne pas être copiées, et dans ce cas, vous devrez appeler cette fonction pour chaque coche jusqu’à ce qu’il y ait une option réussie pour copier les données, qui est implémentée par une certaine complication du filtre

   //---- declaration of a static variable - array for storing values of the AMA indicator
   static double AMA_Array[3];
    
   //---- declaration of the static variable for storing the results of copying the data from the AMA indicator
   static bool Recount;

   //---- calling up the AMA indicator for copying its values into the AMA_Array array
   if (IsNewBar(0, Symbol(), 0) || Recount)
     {
      if (CopyBuffer(AMA_Handle, 0, 1, 3, AMA_Array) < 0)
       {
        Recount = true; // attempt of data copying was unsuccessful 
        return; // exit the function OnTick()
       }
      
      //---- All operations of copying from the indicator buffers are successfully completed
           // there is no need for returning to this block until the next bar change
      Recount = false;
     }

Maintenant que les coordonnées de l’appel rationnel de la fonction de copie des valeurs d’indicateur dans le code de l’Expert Advisor sont claires, vous pouvez tester les avantages de l’application de la fonction IsNewBar () dans les Expert Advisors.

Nous avons donc deux options d’Expert Advisors, disponibles pour être testées dans le testeur de stratégie, la première - AMA_Test.ex5. Il copie les données du tampon de l’indicateur à chaque coche.

Fig.9 Le résultat de  passage du test avec l’Expert Advisor AMA_Test

Le second - IsNewBar_AMA_Test.mq5 copie les données uniquement lors d’un changement de barre.

Fig.10 Le résultat de  passage du test avec l’Expert Advisor IsNewBar_AMA_Test

Oui Les résultats du test sont quelque peu décevants. Il s’avère que l’appel d’une fonction IsNewBar () sur chaque coche est beaucoup plus coûteux que de copier les données dans trois cellules du tableau de l’utilisateur! 

Ici, Je voudrais attirer votre attention sur une autre partie importante, mais apparemment discrète, de l’indicateur. Le fait est que si nous obtenons la poignée de l’indicateur dans la fonction OnInit (), alors, que nous copions ou non les données de cet indicateur dans la fonction OnTick (), ses calculs sur une barre encore non calculée et actuelle, seront toujours effectués sur chaque coche.

Donc, si notre Expert Advisor ne nécessite pas les valeurs d’indicateurs comptées de la barre ouverte actuelle, il est préférable, en termes de gain de temps, de désactiver le calcul de ces valeurs. Cela se fait assez facilement - réduire d’un la bordure droite du cycle principal de recomptage de barres dans l’indicateur Avant les changements, ce cycle dans l’indicateur AMA.mq5 ressemblait à ceci

   //---- main cycle of indicator calculation
   for(bar = first; bar < rates_total; bar++)

Et après le changement, cela ressemblera à ceci  

   //---- main cycle of indicator calculation
   for(bar = first; bar < rates_total - 1; bar++)

Indicateur AMA_Ex.mq5. Vous pouvez maintenant tester cet indicateur (Expert Advisor AMA_Ex_Test.mq5)

Fig.11 Le résultat de la passage du test avec l’Expert Advisor AMA_Ex_Test 

Bien sûr, ce résultat est meilleur que le test de l’indicateur AMA de 21%, ce qui n’est pas trop mal, mais si nous y réfléchissons, ce résultat pourrait être bien meilleur.

Conclusion

En fin de compte, l’efficacité du code d’un programme est un paramètre assez objectif. L’efficacité peut être mesurée, analysée logiquement et, dans certains cas, considérablement augmentée. Les méthodes par lesquelles cela se fait ne sont pas très compliquées. Il suffit de faire preuve de patience et de faire plus que les pratiques qui affectent directement la rentabilité du système de trading automatisé.

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

Fichiers joints |
mql5.zip (23.38 KB)
L'utilisation de ORDER_MAGIC pour trader avec différents Expert Advisors sur un seul instrument L'utilisation de ORDER_MAGIC pour trader avec différents Expert Advisors sur un seul instrument
Cet article examine les questions du codage de l’information, en utilisant l’identification magique, ainsi que la division, l’assemblage et la synchronisation du trading automatique des différents Expert Advisors. Cet article sera intéressant pour les débutants, ainsi que pour les traders les plus expérimentés, car il traite la question des positions virtuelles, ce qui peut être utile dans l’implémentation des systèmes complexes de synchronisation d’Expert Advisors et de diverses stratégies.
Tester la performance du Calcul des Moyennes Mobiles dans MQL5 Tester la performance du Calcul des Moyennes Mobiles dans MQL5
Un certain nombre d'indicateurs sont apparus depuis la création du premier indicateur de Moyenne Mobile. Beaucoup d'entre eux utilisent des méthodes de lissage similaires, mais la performance de différents algorithmes de Moyennes Mobiles n'ont pas été étudiées. Dans cet article, nous examinerons les différentes manières d'utiliser les Moyennes Mobiles dans MQL5 et comparerons leurs performance.
Une bibliothèque pour créer un graphique via l'API Google Chart Une bibliothèque pour créer un graphique via l'API Google Chart
La création de différents types de diagrammes est une partie essentielle des analyses de l’état du marché et du test d'un système de trading. Fréquemment, afin de créer un beau diagramme, il est nécessaire d'organiser les données de sortie dans un fichier, après quoi elles sont utilisées dans des applications telles que MS Excel. Ce n'est pas très pratique et nous prive de la possibilité de mettre à jour dynamiquement les données. L'API Google Charts a fourni les moyens de créer des graphiques en mode en ligne, en envoyant une requête spéciale au serveur. Dans cet article, nous tentons d'automatiser le processus de création d'une telle demande et d'obtention d'un graphique du serveur Google.
Création d’un Expert Advisor, qui trade sur un certain nombre d’instruments Création d’un Expert Advisor, qui trade sur un certain nombre d’instruments
Le concept de diversification des actifs sur les marchés financiers est vieux et a toujours attiré les traders débutants. Dans cet article, l’auteur propose une approche extrêmement simple d’une élaboration d’un Expert Advisor multi-devises, pour une première introduction à cette direction des stratégies de trading.