Création d'un Indicateur Multidevise à l'Aide d'un Certain Nombre de Tampons d'Indicateurs Intermédiaires

Alexey Klenov | 17 novembre, 2021

Introduction

Tout a commencé lorsque j'ai entendu parler pour la première fois des indicateurs de bloc dans l'article Base Théorique de la Construction d'Indicateurs de Bloc pour le FOREX. C'était très intéressant pour moi à l'époque, et j'ai décidé d'écrire quelque chose de similaire en termes d'analyse multi-marchés. Dans un premier temps, j'ai implémenté ma propre version de l'indicateur, nom de code MultiCurrencyIndex, dans lequel les valeurs calculées des indices de devises sont utilisées pour calculer les taux des indicateurs classiques (RSI, MACD, CCI). 

Et maintenant je vais vous dire comment j'ai transféré cet indicateur vers une nouvelle plateforme, MetaTrader 5 en complément de MQL5, sauf qu'au lieu de calculer le CCI, je vais calculer l'indicateur de Stochastique (Stochastic Oscillator), qui est plus prospectif ( À mon avis).

Commençons par quelques définitions.

Dollar Index - - double valeur calculée par la formule, généreusement offerte par Neutron.

La formule de calcul de l'indice USD,

où il y a USD / YYY - toutes les cotations directes, telles que USD / CHF, XXX / USD - toutes en amont, telles que EUR / USD.

D'autres indices sont calculés à partir des valeurs des paires de devises clôturées, comprenant USD.

Lignes principales - deux lignes de l'indicateur, reflétant les données calculées, liées directement au graphique actuel. Par exemple, sur le graphique EURUSD, il y aura des lignes de devises EUR et USD.

Lignes supplémentaires - autres lignes indicatrices calculées, non liées au graphique actuel. Par exemple, pour le même graphique EURUSD, ce seront les lignes des devises GBP, CHF, JPY, CAD, AUD et NZD.

Clôture - la valeur du cours de clôture de la barre de la période actuelle (tapez double) pour la paire de devises nécessaire.

Commençons.

La définition du problème

Pour commencer, nous devons définir le problème.

  1. Synchronisez les graphiques des paires de devises concernées de cette période.
  2. Accédez aux données de clôture de sept paires de devises : EURUSD, GBPUSD, USDCHF, USDJPY, USDCAD, AUDUSD, NZDUSD, et placez-les dans les tampons d'indicateurs, élaborés pour les calculs auxiliaires.
  3. Sur la base des données obtenues dans l’élément (2), calculez pour la barre courante l'indice du dollar.
  4. Connaissant l'indice du dollar pour la barre actuelle, calculez les indices de devises restants.
  5. Effectuez les calculs de données (éléments 3 et 4) un nombre de fois requis pour la durée désignée de l'historique.
  6. En fonction de la destination de l'indicateur, calculez les valeurs des devises pour chacun des indices sélectionnés :
    • Indice de Force Relative (indice de force relative, RSI);
    • Moyennes mobiles de convergence/divergence (Moyenne mobile de convergence/divergence, MACD) ;
    • Oscillateur stochastique (oscillateur stochastique);
    • À l'avenir, la liste pourrait être complétée.

Pour cela nous aurons besoin de :

31 Buffer de l'indicateur

Pour sélectionner la destination d'un indicateur, nous allons faire une énumération de type énuméré :

enum Indicator_Type
  {
   Use_RSI_on_indexes             = 1, // RSI of the index  
   Use_MACD_on_indexes            = 2, // MACD from the index  
   Use_Stochastic_Main_on_indexes = 3  // Stochastic on the index
  };
Ensuite, à l'aide de la commande d'entrée, dans la fenêtre des préférences de l'indicateur, nous dériverons pour les sélections de l'utilisateur de cette liste 
input Indicator_Type ind_type=Use_RSI_on_indexes;  // type of the indicator from the index

Il est possible de rendre plus conviviale la façon d’afficher des noms des paramètres d'entrée sur l'onglet "Entrées". Pour le faire, nous utilisons le commentaire urgent, qui doit être placé après la description du paramètre d'entrée, dans la même ligne. Ainsi, les paramètres d'entrée peuvent être comparés à des noms plus facilement compréhensibles pour l'utilisateur.

Les mêmes règles s'appliquent à la liste des commandes enum . C'est-à-dire que si le nom mnémonique est associé à un commentaire, comme le montre notre exemple, à la place du nom mnémonique, le contenu de ce commentaire sera affiché . Cela offre une flexibilité supplémentaire dans l'écriture de programmes avec des descriptions claires des paramètres d'entrée.

Les développeurs ont essayé de fournir à l'utilisateur final des moyens pratiques de travailler avec le programme MQL5, en s'assurant qu'il voit des noms de paramètres compréhensibles au lieu de ce qui est écrit dans le code. Plus d'informations peuvent être trouvées ici.

Figure 1. Sélection du type d'indicateur

Figure 1. Sélection du type d'indicateur

Nous mettons à disposition de l'utilisateur un choix de devises nécessaires au rendu de l'indicateur et de sa couleur :

input bool USD=true;
input bool EUR=true;
input bool GBP=true;
input bool JPY=true;
input bool CHF=true;
input bool CAD=true;
input bool AUD=true;
input bool NZD=true;

input color Color_USD = Green;            // USD line color
input color Color_EUR = DarkBlue;         // EUR line color
input color Color_GBP = Red;             // GBP line color
input color Color_CHF = Chocolate;        // CHF line color
input color Color_JPY = Maroon;           // JPY line color
input color Color_AUD = DarkOrange;       // AUD line color
input color Color_CAD = Purple;          // CAD line color
input color Color_NZD = Teal;            // NZD line color

Figure 2. Sélection de la couleur des lignes indicatrices

Figure 2. Sélection de la couleur des lignes indicatrices

Quelques autres paramètres configurables :

input string rem000        =  ""; // depending on the type of the indicator
input string rem0000       =  ""; // requires a value :
input int rsi_period       =   9; // period RSI
input int MACD_fast        =   5; // period MACD_fast
input int MACD_slow        =  34; // period MACD_slow
input int stoch_period_k   =   8; // period Stochastic %K
input int stoch_period_sma =   5; // period of smoothing for Stochastics %K
input int shiftbars        = 500; // number of bars for calculating the indicator

Figure 3. Paramètres de l'indicateur

Figure 3. Paramètres de l'indicateur

Une limite de 500 barres pour le calcul de l'indicateur est artificielle, mais elle suffit à démontrer le concept du calcul. Mais nous devons nous rappeler que chaque tampon d'indicateur nécessite de la mémoire, et un affichage d'une très grande taille variable (en millions de barres), peut entraîner un manque de mémoire de l'ordinateur.

Tampons d’indicateur:

double  EURUSD[], // quotes
        GBPUSD[],
        USDCHF[],
        USDJPY[],
        AUDUSD[],
        USDCAD[],
        NZDUSD[];   
               
double    USDx[], // indexes
          EURx[],
          GBPx[],
          JPYx[],
          CHFx[],
          CADx[],
          AUDx[],
          NZDx[];
                         
double USDplot[], // results of currency lines
       EURplot[],
       GBPplot[],
       JPYplot[],
       CHFplot[],
       CADplot[],
       AUDplot[],
       NZDplot[]; 

double USDStoch[], // buffers of intermediate data schotastics by the close/close type without smoothing
       EURStoch[],
       GBPStoch[],
       JPYStoch[],
       CHFStoch[],
       CADStoch[],
       AUDStoch[],
       NZDStoch[];
Nous aurons également besoin de quelques variables globales (au niveau de l'indicateur) :
int              i,ii;
int           y_pos=0; // Y coordinate variable for the informatory objects  
datetime   arrTime[7]; // Array with the last known time of a zero valued bar (needed for synchronization)  
int        bars_tf[7]; // To check the number of available bars in different currency pairs  
int        countVal=0; // Number of executable Rates  
int           index=0;
datetime  tmp_time[1]; // Intermediate array for the time of the bar 

Et maintenant, nous arrivons à une fonctionnalité assez longue OnInit, à l'aide de laquelle nous allons distribuer les tampons d'indicateurs en fonction de leurs objectifs.

Puisque les calculs initiaux passent par l'indice du dollar, alors pour l' USD nous établissons simplement la possibilité de désactiver le rendu des tampons de l'indicateur de devise.

Cela ressemble à ceci :

if(USD)
  {
   countVal++;
   SetIndexBuffer(0,USDplot,INDICATOR_DATA);               // array for rendering
   PlotIndexSetString(0,PLOT_LABEL,"USDplot");              // name of the indicator line (when selected with a mouse)
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,shiftbars);       // from which we begin rendering
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);         // drawing style (line)
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Color_USD);       // color of line rendering
   if(StringFind(Symbol(),"USD",0)!=-1)
     {PlotIndexSetInteger(0,PLOT_LINE_WIDTH,wid_main);}    // if the symbol name contains USD 
                                                       // then draw a line of appropriate width 
   else
     {PlotIndexSetInteger(0,PLOT_LINE_STYLE,style_slave);}
   ArraySetAsSeries(USDplot,true);                       // indexation of array as a timeseries   
   ArrayInitialize(USDplot,EMPTY_VALUE);                  // zero values 
   f_draw("USD",Color_USD);                            // rendering in the indicator information window 
  }
SetIndexBuffer(15,USDx,INDICATOR_CALCULATIONS);            // array of dollar index for calculations
                                                      // (is not displayed in the indicator as a line) 
ArraySetAsSeries(USDx,true);                            // indexation of an array as a time series
ArrayInitialize(USDx,EMPTY_VALUE);                       // zero values

if(ind_type==Use_Stochastic_Main_on_indexes)
  {
   SetIndexBuffer(23,USDstoch,INDICATOR_CALCULATIONS);     // if the destination of the indicator as a Use_Stochastic_Main_on_indexes,
                                                           // then this intermediate array is needed
   ArraySetAsSeries(USDstoch,true);                        // indexation of array as a time series
   ArrayInitialize(USDstoch,EMPTY_VALUE);                  // zero values
  }
Pour la devise EUR, le code de fonction OnInit ressemble à ceci :
if(USD)
  {
   countVal++;
   SetIndexBuffer(0,USDplot,INDICATOR_DATA);              // array for rendering
   PlotIndexSetString(0,PLOT_LABEL,"USDplot");             // name of the indicator line (when selected with a mouse)
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,shiftbars);       // from which we begin rendering
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);         // drawing style (line)
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Color_USD);       // color of line rendering
   if(StringFind(Symbol(),"USD",0)!=-1)
     {PlotIndexSetInteger(0,PLOT_LINE_WIDTH,wid_main);}    // if the symbol name contains USD 
                                                       // then draw a line of appropriate width 
   else
     {PlotIndexSetInteger(0,PLOT_LINE_STYLE,style_slave);}
   ArraySetAsSeries(USDplot,true);                       // indexation of array as a timeseries
   ArrayInitialize(USDplot,EMPTY_VALUE);                  // zero values 
   f_draw("USD",Color_USD);                             // rendering in the indicator information window 
  }
SetIndexBuffer(15,USDx,INDICATOR_CALCULATIONS);             // array of dollar index for calculations
                                                       // (is not displayed in the indicator as a line) 
ArraySetAsSeries(USDx,true);                             // indexation of an array as a time series
ArrayInitialize(USDx,EMPTY_VALUE);                        // zero values

if(ind_type==Use_Stochastic_Main_on_indexes)
  {
   SetIndexBuffer(23,USDstoch,INDICATOR_CALCULATIONS);      // if the destination of the indicator as a Use_Stochastic_Main_on_indexes,
                                                       // then this intermediate array is needed
   ArraySetAsSeries(USDstoch,true);                      // indexation of array as a time series
   ArrayInitialize(USDstoch,EMPTY_VALUE);                 // zero values
  }

if(EUR)
  {
   countVal++;
   SetIndexBuffer(1,EURplot,INDICATOR_DATA);              // array for rendering
   PlotIndexSetString(1,PLOT_LABEL,"EURplot");             // name of the indicator line (when pointed to with a mouse)
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,shiftbars);       // which we begin rendering from
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);         // drawing style (lines)
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,Color_EUR);       // the color of rendering lines
   if(StringFind(Symbol(),"EUR",0)!=-1)
     {PlotIndexSetInteger(1,PLOT_LINE_WIDTH,wid_main);}    // if the symbol name contains EUR
                                                       // then we draw a line of the appropriate width 
   else
     {PlotIndexSetInteger(1,PLOT_LINE_STYLE,style_slave);}  // if the symbol name does NOT contain EUR,
                                                       // then we draw a line of an appropriate style (on the crosses)
   ArraySetAsSeries(EURplot,true);                       // indexation of the array as a time series
   ArrayInitialize(EURplot,EMPTY_VALUE);                  // zero values
   SetIndexBuffer(8,EURUSD,INDICATOR_CALCULATIONS);        // data of Close currency pair EURUSD
   ArraySetAsSeries(EURUSD,true);                        // indexation of the array as a time series
   ArrayInitialize(EURUSD,EMPTY_VALUE);                   // zero values
   SetIndexBuffer(16,EURx,INDICATOR_CALCULATIONS);         // array of the EURO index for calculations
                                                      // (not displayed on the indicator as a line) 
   ArraySetAsSeries(EURx,true);
   ArrayInitialize(EURx,EMPTY_VALUE);
   if(ind_type==Use_Stochastic_Main_on_indexes)
     {
      SetIndexBuffer(24,EURstoch,INDICATOR_CALCULATIONS);   // if the indicator destination as a Use_Stochastic_Main_on_indexes,
                                                       // then this intermediate array is needed
      ArraySetAsSeries(EURstoch,true);                   // indexation of the array as a time series
      ArrayInitialize(EURstoch,EMPTY_VALUE);              // zero values
     }
   f_draw("EUR",Color_EUR);                            // rendering in the indicator information window
  }
Par analogie avec l' EUR, le code aura la même apparence que les devises, telles que GBP, JPY, CHF, CAD, AUD et NZD, déplaçant les indices des tampons indicateurs. Le code de ces devises se trouve dans le fichier joint de l'indicateur.

Ceci termine la description de l'initialisation de l'indicateur.

Ensuite, nous aurons besoin de certaines fonctionnalités utilisateur personnalisées :

Brève description de chacun d'entre eux :

Paramètres d’entrée

double f_RSI(double &buf_in[], int period,int shift),

buf_in[] - type de tableau double (comme les séries chronologiques), période - période d'indicateur RSI, décalage - pour quelle barre d'index nous calculons l'indicateur. Renvoie une valeur de type double.

Paramètres d’entrée

double f_MACD(double &buf_in[], int period_fast,int period_slow,int shift),

buf_in[] - tableau de type double (comme les séries chronologiques), period_fast - period fast МА, period_slow- period slow МА, décalage - pour quelle barre d'index nous calculons l'indicateur. Renvoie une valeur de type double.

Paramètres d’entrée

double SimpleMA(const int position,const int period,const double &price[]),

position - pour quelle barre d'index nous calculons l'indicateur. period - période de l'indicateur SMA, price[] - tableau de temps double (comme les séries chronologiques). Renvoie une valeur de type double.

Paramètres d’entrée

double f_Stoch(double &price[], int period_k, int shift),

price[] - tableau de type double (comme les séries chronologiques), period_fast - ligne d'indicateur de période %K, décalage - pour quelle barre d'index nous calculons l'indicateur. Renvoie une valeur de type double.

Paramètres d’entrée

int f_draw(string name, color _color)

nom - nom d’objet, _couleur - couleur d’objet La fonction est à titre informatif. A partir du haut du coin droit de la fenêtre d'affichage et plus bas, cette fonction affiche les noms des devises concernées. Le texte de la devise est de la même couleur que la ligne indicatrice, relative à cette devise.

Paramètres d’entrée

int f_comment(string text)

text - Le texte qui doit être placé dans le coin inférieur droit de l'indicateur. Une sorte de barre d'état du travail de l'indicateur.

Enfin, la conclusion et l'une des fonctions les plus importantes :

Absence de paramètres d’entrée.

Dans MetaTrader 5, l'historique est stocké sous la forme de données de de TF pour chaque outil. Par conséquent, avant de lancer le programme, tous les graphiques nécessaires (affectés) sont construits, sur la base des mêmes données de minute TF, une fois le terminal ouvert. La construction intervient également lorsque le trafic actuel TF est commuté ou lors d'une tentative d'accès au graphique de la TF via le code de programme MQL5.

Par conséquent:

La première partie de cette tâche est implémentée à l'aide de la fonction intégrée Bars, qui renvoie le nombre de barres dans l'historique par la période correspondante au symbole. Il suffit d'utiliser la version de cette fonction, qui est illustrée ci-dessous.

int  Bars(
   string          symbol_name,   // symbol name
   ENUM_TIMEFRAMES   timeframe    // period
   );

Dans le, spécialement annoncé pour ce tableau, nous recueillons le nombre de barres disponibles pour toutes les paires de devises concernées. Nous vérifions chaque valeur pour la quantité minimale d’historique nécessaire (la variable "nombre de barres pour le calcul de l'indicateur" dans les paramètres de l'indicateur). Si le nombre de barres disponibles dans l'historique d'un instrument est inférieur à la valeur de cette variable, alors nous considérons que la construction n'a pas abouti et réexaminons le nombre de données disponibles. Une fois qu'il y a plus d'historique disponible, pour toutes les paires de devises, que celles demandé par l'utilisateur - alors nous pouvons affirmer que cette partie de l'initialisation a été effectuée avec succès.

La deuxième partie de la tâche de synchronisation est implémentée en utilisant la fonction CopyTime.

 Dans un tableau spécialement créé à cet effet, nous copions l'ouverture de la barre zéro de chaque instrument concerné. Si tous les éléments de ce tableau sont identiques et ne sont pas égaux à 0, considérons que notre barre zéro est synchronisée, et commençons le calcul. Pour comprendre davantage comment cela est mis en œuvre, consultez le code de l'indicateur ci-joint.

Ceci conclut la description des fonctions supplémentaires et nous passons à l'implémentation de la fonction OnCalculate . Puisqu’ il s'agit d'un indicateur multi-devises, nous aurons besoin de la deuxième version de la requête de cette fonction.

int OnCalculate(const int     rates_total, // size of incoming time series
                const int prev_calculated, // processing of bars on the previous request
                const datetime&    time[], // Time
                const double&      open[], // Open
                const double&      high[], // High
                const double&       low[], // Low
                const double&     close[], // Close
                const long& tick_volume[], // Tick Volume
                const long&      volume[], // Real Volume
                const int&       spread[]  // Spread
   );

Déterminez le nombre de barres nécessaires au calcul :

   int limit=shiftbars;

   if(prev_calculated>0)
     {limit=1;}
   else
     {limit=shiftbars;}

Synchronise les graphiques des paires de devises :

   init_tf();

Ensuite, à l'aide de la fonction CopyClose, nous copions les données Close de toutes les paires de devises nécessaires, dans les tampons d'indicateurs, enregistrés spécialement pour cela. (Pour en savoir davantage sur l'accès aux données d'autres TF de l'outil actuel et/ou d'un autre outil, se trouve dans Aide )

Si, pour une quelconque raison, la fonction n'a pas copié les données et a renvoyé une réponse -1, du coup,nous affichons un message d'erreur de paire de devises dans le commentaire et attendons la réception d'un nouveau tick pour l'instrument actuel.

   if (EUR){copied=CopyClose("EURUSD",PERIOD_CURRENT,0,shiftbars,EURUSD); if (copied==-1){f_comment("Wait...EURUSD");return(0);}}
   if (GBP){copied=CopyClose("GBPUSD",PERIOD_CURRENT,0,shiftbars,GBPUSD); if (copied==-1){f_comment("Wait...GBPUSD");return(0);}}
   if (CHF){copied=CopyClose("USDCHF",PERIOD_CURRENT,0,shiftbars,USDCHF); if (copied==-1){f_comment("Wait...USDCHF");return(0);}}
   if (JPY){copied=CopyClose("USDJPY",PERIOD_CURRENT,0,shiftbars,USDJPY); if (copied==-1){f_comment("Wait...USDJPY");return(0);}}
   if (AUD){copied=CopyClose("AUDUSD",PERIOD_CURRENT,0,shiftbars,AUDUSD); if (copied==-1){f_comment("Wait...AUDUSD");return(0);}}
   if (CAD){copied=CopyClose("USDCAD",PERIOD_CURRENT,0,shiftbars,USDCAD); if (copied==-1){f_comment("Wait...USDCAD");return(0);}}
   if (NZD){copied=CopyClose("NZDUSD",PERIOD_CURRENT,0,shiftbars,NZDUSD); if (copied==-1){f_comment("Wait...NZDUSD");return(0);}}  

Ensuite dans le cycle (de 0 à la limite) nous produisons :

for (i=limit-1;i>=0;i--)
   {
      //calculation of USD index
      USDx[i]=1.0;
      if (EUR){USDx[i]+=EURUSD[i];}         
      if (GBP){USDx[i]+=GBPUSD[i];}
      if (CHF){USDx[i]+=1/USDCHF[i];}
      if (JPY){USDx[i]+=1/USDJPY[i];}
      if (CAD){USDx[i]+=1/USDCAD[i];}
      if (AUD){USDx[i]+=AUDUSD[i];}
      if (NZD){USDx[i]+=NZDUSD[i];}
      USDx[i]=1/USDx[i];
      //calculation of other currency values
      if (EUR){EURx[i]=EURUSD[i]*USDx[i];}
      if (GBP){GBPx[i]=GBPUSD[i]*USDx[i];}
      if (CHF){CHFx[i]=USDx[i]/USDCHF[i];}
      if (JPY){JPYx[i]=USDx[i]/USDJPY[i];}
      if (CAD){CADx[i]=USDx[i]/USDCAD[i];}
      if (AUD){AUDx[i]=AUDUSD[i]*USDx[i];}
      if (NZD){NZDx[i]=NZDUSD[i]*USDx[i];}
   }

Les données sont placées dans les tampons indicateurs appropriés. Vérifiez quel type d'indicateur a été sélectionné par l'utilisateur lors de l'initialisation, et sur cette base, faites des calculs pertinents.

S’il y a une envie de regarder le RSI des index a été démontrée, alors exécutez le code ci-dessous :

if (ind_type==Use_RSI_on_indexes)
   {
      if (limit>1){ii=limit - rsi_period - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
            if (USD){USDplot[i]=f_RSI(USDx,rsi_period,i);}
            if (EUR){EURplot[i]=f_RSI(EURx,rsi_period,i);}
            if (GBP){GBPplot[i]=f_RSI(GBPx,rsi_period,i);}
            if (CHF){CHFplot[i]=f_RSI(CHFx,rsi_period,i);}
            if (JPY){JPYplot[i]=f_RSI(JPYx,rsi_period,i);}
            if (CAD){CADplot[i]=f_RSI(CADx,rsi_period,i);}
            if (AUD){AUDplot[i]=f_RSI(AUDx,rsi_period,i);}
            if (NZD){NZDplot[i]=f_RSI(NZDx,rsi_period,i);}                  
         }
   }  

Si nous voulions voir le MACD par les index, alors nous allons ici (mais jusqu'à présent il n'est implémenté que sur la base de SimpleMA, et sera implémenté sur la base d' EMA plus tard):

if (ind_type==Use_MACD_on_indexes)
   {
      if (limit>1){ii=limit - MACD_slow - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
           if (USD){USDplot[i]=f_MACD(USDx,MACD_fast,MACD_slow,i);}
           if (EUR){EURplot[i]=f_MACD(EURx,MACD_fast,MACD_slow,i);}
           if (GBP){GBPplot[i]=f_MACD(GBPx,MACD_fast,MACD_slow,i);}
           if (CHF){CHFplot[i]=f_MACD(CHFx,MACD_fast,MACD_slow,i);}
           if (JPY){JPYplot[i]=f_MACD(JPYx,MACD_fast,MACD_slow,i);}
           if (CAD){CADplot[i]=f_MACD(CADx,MACD_fast,MACD_slow,i);}
           if (AUD){AUDplot[i]=f_MACD(AUDx,MACD_fast,MACD_slow,i);}
           if (NZD){NZDplot[i]=f_MACD(NZDx,MACD_fast,MACD_slow,i);}                  
         }
   } 

Si Stochastis, vous devez d'abord calculer la ligne % K, et puis la lisser à l’aide de la méthode SimpleMA. La ligne finale lissée doit être affichée sur le graphique.

if (ind_type==Use_Stochastic_Main_on_indexes)
   {
      if (limit>1){ii=limit - stoch_period_k - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
           if (USD){USDstoch[i]=f_Stoch(USDx,rsi_period,i);}
           if (EUR){EURstoch[i]=f_stoch(EURx,stoch_period_k,i);}
           if (GBP){GBPstoch[i]=f_stoch(GBPx,stoch_period_k,i);}
           if (CHF){CHFstoch[i]=f_stoch(CHFx,stoch_period_k,i);}
           if (JPY){JPYstoch[i]=f_stoch(JPYx,stoch_period_k,i);}
           if (CAD){CADstoch[i]=f_stoch(CADx,stoch_period_k,i);}
           if (AUD){AUDstoch[i]=f_stoch(AUDx,stoch_period_k,i);}
           if (NZD){NZDstoch[i]=f_stoch(NZDx,stoch_period_k,i);}                  
         }
      if (limit>1){ii=limit - stoch_period_sma - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
            if (USD){USDplot[i]=SimpleMA(i,stoch_period_sma,USDstoch);}
            if (EUR){EURplot[i]=SimpleMA(i,stoch_period_sma,EURstoch);}
            if (GBP){GBPplot[i]=SimpleMA(i,stoch_period_sma,GBPstoch);}
            if (CHF){CHFplot[i]=SimpleMA(i,stoch_period_sma,CHFstoch);}
            if (JPY){JPYplot[i]=SimpleMA(i,stoch_period_sma,JPYstoch);}
            if (CAD){CADplot[i]=SimpleMA(i,stoch_period_sma,CADstoch);}
            if (AUD){AUDplot[i]=SimpleMA(i,stoch_period_sma,AUDstoch);}
            if (NZD){NZDplot[i]=SimpleMA(i,stoch_period_sma,NZDstoch);}                  
          }                     
   }       

Ceci achève le calcul des indicateurs. Les figures 4 à 6 présentent quelques images des différents types d'indicateurs.

Figure 4. RSI par les indices

Figure 4. RSI par les indices

Figure 5. MACD par les indices de devises

Figure 5. MACD par les indices de devises

Figure 6. Stochastis par les indices de devises

Figure 6. Stochastis par les indices de devises

Conclusion

Lors de l'implémentation de l'indicateur MultiCurrencyIndex, j'ai utilisé un nombre illimité de tampons d'indicateurs dans MQL5, ce qui a considérablement simplifié le code. Cet article est un exemple d'une approche pareille. Pour des données fiables d'un indicateur, j'ai démontré un algorithme de synchronisation de différents instruments par rapport à la barre zéro. J'ai également démontré l'un des algorithmes possibles d'accès aux données d'autres instruments, par rapport au symbole auquel l'indicateur est attaché.

Étant donné que le but de l'article était de démontrer la possibilité de travailler avec une énorme quantité de tampons d'indicateurs ; la fonction ci-dessus de calculer les indicateurs par les tableaux de données des utilisateurs, n'était pas le moyen optimal pour éviter de surcharger le lecteur. Mais c'était suffisant pour effectuer les calculs nécessaires.

Il existe de nombreux avantages et inconvénients de l'analyse de bloc du marché Forex. Les systèmes de trading, axés sur cette approche, sont disponibles gratuitement, et il y a des discussions à ce sujet sur divers forums, y compris sur MQL4.Community. Par conséquent, les principes de trading par cet indicateur ne sont pas pris en compte dans cet article.