English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Transfert d'indicateurs de MQL4 vers MQL5

Transfert d'indicateurs de MQL4 vers MQL5

MetaTrader 5Exemples | 16 novembre 2021, 15:48
144 0
Vasily
Vasily

Introduction

Bonjour chers lecteurs !

Dans l'article d'aujourd'hui, je vais vous représenter un algorithme de transfert de calculs de prix simples de MQL4 à MQL5. En jetant un coup d'œil à la différence entre MQL5 et MQL4 j'ai ajouté la bibliothèque de fonctions mql4_2_mql5.mqh; nous saurons l’utiliser après avoir lu cet article.

1. Préparer un Indicateur pour le Transfert

Cet article concerne uniquement le transfert des calculs d'indicateurs ; si un indicateur comporte des éléments graphiques ou des calculs de prix plus complexes, vous rencontrerez des difficultés avec celui-ci.

Tout d'abord, nous devons établir un code MQL4 pour le transfert. Examinons ce dont nous avons besoin pour cela.

Ouvrez MetaEditor 4 avec un indicateur nécessaire, par exemple MACD ; et entamer la modification de ses paramètres d'entrée :

//---- indicator parameters
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;
//---- indicator buffers
double     MacdBuffer[];
double     SignalBuffer[];

Nous devons amener le tout dans l'état suivant :

double &MacdBuffer[],double &SignalBuffer[],int FastEMA,int SlowEMA,int SignalSMA

Au début de la ligne, les tampons d'indicateurs sont indiqués avec les symboles & avant leurs noms. La raison en est que nous devons transmettre les liens vers le tableau où toutes les modifications seront effectuées, mais pas le tableau lui-même !!!

Viennent ensuite les paramètres d'entrée. Dans notre indicateur MQL4, modifiez la ligne suivante :

int start()

à

int start(int rates_total,
         int prev_calculated,
         double &MacdBuffer[],
         double &SignalBuffer[],
         int FastEMA,
         int SlowEMA,
         int SignalSMA)

Comme vous le constatez, deux autres éléments obligatoires sont ajoutés :

int rates_total, int prev_calculated,

La partie suivante est la ligne que nous avons précédemment formée.

Copiez maintenant toute la section jusqu'au dernier symbole.

//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start(int rates_total
         ,int prev_calculated
         ,double &MacdBuffer[]
         ,double &SignalBuffer[]
         ,int FastEMA
         ,int SlowEMA
         ,int SignalSMA)
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
                     -iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);
//---- done
   return(0);
  }
//+------------------------------------------------------------------

2. Création d'un Modèle MQL5 pour les Programmes MQL4

Nous devons maintenant établir l'environnement de notre section.

Pour le faire, sélectionnez l'élément "Nouveau" du menu dans MetaEditor 5, puis sélectionnez "Indicateur personnalisé".

Créez des paramètres d'entrée (fig. 1) en fonction des paramètres d'entrée de l'indicateur MQL4 :

//---- indicator parameters
extern int FastEMA=12;
extern int SlowEMA=26;
extern int SignalSMA=9;

Paramètres d'entrée de l'indicateur MACD

Figure 1. Paramètres d'entrée de l'indicateur MACD

Créez ensuite des tampons indicateurs (fig. 2) en fonction de ce qui est écrit à leur sujet dans le programme MQL4 :

//---- indicator buffers
double     MacdBuffer[];
double     SignalBuffer[];

Les tampons indicateurs de MACD

Figure 2. Les tampons indicateurs de MACD

Nous avons maintenant créé un modèle pour notre nouvel indicateur.

Vous devez y apporter plusieurs modifications. Ajoutez une ligne au-dessus des paramètres d'entrée :

#include <mql4_2_mql5.mqh>
//--- input parameters

 Vers la fonction          

int OnInit()

ajoutez la ligne

    InitMql4();
et ajoutez une ligne chargée du démarrage de l'environnement du programme MQL4 au corps du programme :
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

Comme vous pouvez le constater, cette fonction renverra le nombre de barres disponibles pour l'environnement MQL4 ; une nouvelle variable apparaît ici aussi : 

int CountedMQL4;

Cette variable est un analogue de la variable MQL5

 prev_calculated,

La variable CountedMQL4 est déclarée dans le fichier inclus ; elle transmet la quantité de données calculées.

Insérez ensuite notre section MQL4 créée dans le modèle MQL5 formé après le dernier symbole.

Maintenant, nous devons démarrer l'indicateur.

Pour le faire, ajoutez la ligne suivante au corps du programme :

Start(bars,
      CountedMQL4,
      MacdBuffer,
      SignalBuffer,
      FastEMA,
      SlowEMA,
      SignalSMA);

Comme vous le constatez, cette ligne transmettra les données nécessaires à notre programme MQL4, ainsi que les liens vers les tampons résultants, dont nous prendrons les noms du modèle créé dans MQL5.

Le résultat suivant doit être obtenu :

//+------------------------------------------------------------------+
//|                                                     MACD_MQ4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot MacdBuffer
#property indicator_label1  "MacdBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters
#include <mql4_2_mql5.mqh>
input int      FastEMA=12;
input int      SlowEMA=26;
input int      SignalSMA=9;
//--- indicator buffers
double         MacdBuffer[];
double         SignalBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//---
   InitMql4();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
//---
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

   Start(bars,
         CountedMQL4,
         MacdBuffer,
         SignalBuffer,
         FastEMA,
         SlowEMA,
         SignalSMA);//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int Start(int rates_total,
         int prev_calculated,
         double &MacdBuffer[],
         double &SignalBuffer[],
         int FastEMA,
         int SlowEMA,
         int SignalSMA)
  {
   int limit;
   int counted_bars=IndicatorCounted();
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
                       -iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i);
//---- done
   return(0);
  }

Ce n'est que la première étape du transfert ; nous commençons maintenant à déboguer l'indicateur.

3. Spécificités d’Usage des Tampons d'Indicateurs dans MQL5

Étant donné que de nombreuses variables prédéfinies de MQL4 correspondent aux noms de variables prédéfinies de MQL5, vous devez apporter les modifications suivantes à la section MQL4 transférée :

MQL4
MQL5
IndicatorCounted()
prev_calculated
 Barres  rates_total
 iMA(  iMAMql4(
 iMAOnArray(  iMAOnArrayMql4(

//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 

En ce qui concerne les spécificités de l'organisation du stockage des données, la référence MQL5 dit ce qui suit à propos de SetIndexBuffer() :

Note

Après la liaison, le tableau dynamique buffer[] sera indexé comme dans les tableaux communs, même si l'indexation des séries chronologiques est pré-installée pour le tableau lié. Si vous souhaitez modifier l'ordre d'accès aux éléments du tableau d'indicateurs, utilisez la fonction ArraySetAsSeries() après avoir lié le tableau à l'aide de la fonction SetIndexBuffer().

Ainsi, l’action initiale d'accès aux tampons d'indicateurs correspond désormais au travail avec des tableaux ordinaires, vous devez donc toujours ajouter la liaison :

   ArraySetAsSeries(MacdBuffer,true);
   ArraySetAsSeries(SignalBuffer,true);

Le code résultant est le suivant :

//+------------------------------------------------------------------+
//|                                                    MACD_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot MacdBuffer
#property indicator_label1  "MacdBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#include <mql4_2_mql5.mqh>
//--- input parameters
input int      FastEMA=12;
input int      SlowEMA=26;
input int      SignalSMA=9;
//--- indicator buffers
double         MacdBuffer[];
double         SignalBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//---   
   InitMql4();
//---
   ArraySetAsSeries(MacdBuffer,true);
   ArraySetAsSeries(SignalBuffer,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available for MQL4 programs   
   Start(bars,
         CountedMQL4,
         MacdBuffer,
         SignalBuffer,
         FastEMA,
         SlowEMA,
         SignalSMA);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 
int Start(int rates_total,
         int prev_calculated,
         double &MacdBuffer[],
         double &SignalBuffer[],
         int FastEMA,
         int SlowEMA,
         int SignalSMA)
  {
   int limit;
   int counted_bars=prev_calculated;
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=rates_total-counted_bars;
//---- macd counted in the 1-st buffer
   for(int i=0; i<limit; i++)
      MacdBuffer[i]=iMAMql4(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i)
                    -iMAMql4(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//---- signal line counted in the 2-nd buffer
   for(int i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArrayMql4(MacdBuffer,rates_total,SignalSMA,0,MODE_SMA,i);
//---- done
   return(0);
  }
//+------------------------------------------------------------------+

Le résultat de l'exécution est indiqué dans la fig. 3:

Figure 3. Comparaison de l'indicateur MACD réécrit à partir de MQL4 et de l'indicateur standard en MQL5.


4. Exemple de Transfert de l'Indicateur Stochastique

Créons un nouveau modèle pour notre indicateur dans MetaEditor 5 (fig. 4-5) :

Paramètres d'entrée

Figure 4. Paramètres d'entrée

Tampons

Figure 5. Tampons

Lors du débogage, nous avons compris que plusieurs calculs de la fonction MQL4 "OnInit" devaient être déplacés à l'intérieur de la fonction "Démarrer" par simple copie :

int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
Nous devons également modifier le nombre de tampons pour le dessin car dans notre programme MQL4, 2 tampons sont utilisés pour les calculs en interne et 2 autres pour le dessin.
#property indicator_plots   2

Et modifier l'état des tampons qui seront utilisés par notre programme MQL4 pour les calculs en interne.

   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
Apportez les modifications nécessaires :
//+------------------------------------------------------------------+
//|                                              Stochastic_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 4
#property indicator_plots   2
//--- plot MainBuffer
#property indicator_label1  "MainBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SignalBuffer
#property indicator_label2  "SignalBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

#include <mql4_2_mql5.mqh>
//--- input parameters
input int      Kperiod=14;
input int      Dperiod=5;
input int      Slowing=5;
//--- indicator buffers
double         MainBuffer[];
double         SignalBuffer[];
double         HighesBuffer[];
double         LowesBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MainBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
//---
    InitMql4();
//---
   ArraySetAsSeries(MainBuffer,true);
   ArraySetAsSeries(SignalBuffer,true);
   ArraySetAsSeries(HighesBuffer,true);
   ArraySetAsSeries(LowesBuffer,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int bars=MQL4Run(rates_total,prev_calculated);
// bars - количество баров, доступных mql4-программам
   start(bars,
         CountedMQL4,
         MainBuffer,
         SignalBuffer,
         HighesBuffer,
         LowesBuffer,
         Kperiod,
         Dperiod,
         Slowing);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 
int start(int rates_total,
          int prev_calculated,
          double &MainBuffer[],
          double &SignalBuffer[],
          double &HighesBuffer[],
          double &LowesBuffer[],
          int KPeriod,
          int DPeriod,
          int Slowing)
  {
   int draw_begin1=KPeriod+Slowing;
   int draw_begin2=draw_begin1+DPeriod;
   int    i,k;
   int    counted_bars=prev_calculated;
   double price;
//----
   if(rates_total<=draw_begin2) return(0);
//---- initial zero
   if(counted_bars<1)
     {
      for(i=1;i<=draw_begin1;i++) MainBuffer[rates_total-i]=0;
      for(i=1;i<=draw_begin2;i++) SignalBuffer[rates_total-i]=0;
     }
//---- minimums counting
   i=rates_total-KPeriod;
   if(counted_bars>KPeriod) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double min=1000000;
      k=i+KPeriod-1;
      while(k>=i)
        {
         price=Low[k];
         if(min>price) min=price;
         k--;
        }
      LowesBuffer[i]=min;
      i--;
     }
//---- maximums counting
   i=rates_total-KPeriod;
   if(counted_bars>KPeriod) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double max=-1000000;
      k=i+KPeriod-1;
      while(k>=i)
        {
         price=High[k];
         if(max<price) max=price;
         k--;
        }
      HighesBuffer[i]=max;
      i--;
     }
//---- %K line
   i=rates_total-draw_begin1;
   if(counted_bars>draw_begin1) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double sumlow=0.0;
      double sumhigh=0.0;
      for(k=(i+Slowing-1);k>=i;k--)
        {
         sumlow+=Close[k]-LowesBuffer[k];
         sumhigh+=HighesBuffer[k]-LowesBuffer[k];
        }
      if(sumhigh==0.0) MainBuffer[i]=100.0;
      else MainBuffer[i]=sumlow/sumhigh*100;
      i--;
     }
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   int limit=rates_total-counted_bars;
//---- signal line is simple moving average
   for(i=0; i<limit; i++)
      SignalBuffer[i]=iMAOnArrayMql4(MainBuffer,rates_total,DPeriod,0,MODE_SMA,i);
//----
   return(0);
  }
//+------------------------------------------------------------------+

En conséquence, nous avons obtenu un stochastique à part entière dans MQL5 avec les constructions de prix MQL4.

Le résultat de son travail est indiqué dans la fig. 6 :

Comparaison de l'indicateur Stochastique réécrit à partir de MQL4 et du Stochastique standard en MQL5

Figure 6. Comparaison de l'indicateur Stochastique réécrit à partir de MQL4 et du Stochastique standard en MQL5.

5. Exemple de Transfert de l'Indicateur RSI

Recueillez des informations sur notre indicateur :
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

Et créez-en un modèle dans MetaEditor 5 (fig. 7-8).

Paramètre d'entrée de l'indicateur RSI

Figure 7. Paramètre d'entrée de l'indicateur RSI

Tampons de l'indicateur RSI

Figure 8. Tampons de l'indicateur RSI

Le nombre total de tampons est de 3 :

#property indicator_buffers 3

Le nombre de tampons pour le traçage est égal à un :

#property indicator_plots   1

Définissez l'état des tampons pour les calculs :

   SetIndexBuffer(1,PosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,NegBuffer,INDICATOR_CALCULATIONS)

Disposez les pièces et apportez les modifications nécessaires :

//+------------------------------------------------------------------+
//|                                                     RSI_MQL4.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   1
//--- plot RSIBuffer
#property indicator_label1  "RSIBuffer"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Green
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot PosBuffer
#property indicator_label2  "PosBuffer"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot NegBuffer
#property indicator_label3  "NegBuffer"
#property indicator_type3   DRAW_LINE
#property indicator_color3  Red
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

#include <mql4_2_mql5.mqh>
//--- input parameters
input int      RSIPeriod=14;
//--- indicator buffers
double         RSIBuffer[];
double         PosBuffer[];
double         NegBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,RSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,PosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,NegBuffer,INDICATOR_CALCULATIONS);
//---
   InitMql4(3);

   ArraySetAsSeries(RSIBuffer,true);
   ArraySetAsSeries(PosBuffer,true);
   ArraySetAsSeries(NegBuffer,true);

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available for MQL4 programs
   RSImql4(bars,
           CountedMQL4,
           RSIBuffer,
           PosBuffer,
           NegBuffer,
           RSIPeriod);
   return(rates_total);
  }
//+--------------------+------------------+
//|              MQL4  | MQL5             |
//+--------------------+------------------+
//|IndicatorCounted()  | prev_calculated  |
//|              Bars  | rates_total      |
//|              iMA(  | iMAMql4(         |
//|       iMAOnArray(  | iMAOnArrayMql4(  |
//+--------------------+------------------+ 
int RSImql4(int rates_total,
            int prev_calculated,
            double &RSIBuffer[],
            double &PosBuffer[],
            double &NegBuffer[],
            int RSIPeriod)
  {
   int    i,counted_bars=prev_calculated;
   double rel,negative,positive;
//----fd
   if(rates_total<=RSIPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=RSIPeriod;i++) RSIBuffer[rates_total-i]=0.0;
//----
   i=rates_total-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=rates_total-counted_bars-1;
   while(i>=0)
     {
      double sumn=0.0,sump=0.0;
      if(i==rates_total-RSIPeriod-1)
        {
         int k=rates_total-2;
         //---- initial accumulation
         while(k>=i)
           {
            rel=Close[k]-Close[k+1];
            if(rel>0) sump+=rel;
            else      sumn-=rel;
            k--;
           }
         positive=sump/RSIPeriod;
         negative=sumn/RSIPeriod;
        }
      else
        {
         //---- smoothed moving average
         rel=Close[i]-Close[i+1];
         if(rel>0) sump=rel;
         else      sumn=-rel;
         positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod;
         negative=(NegBuffer[i+1]*(RSIPeriod-1)+sumn)/RSIPeriod;
        }
      PosBuffer[i]=positive;
      NegBuffer[i]=negative;
      if(negative==0.0) RSIBuffer[i]=0.0;
      else RSIBuffer[i]=100.0-100.0/(1+positive/negative);
      i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

Ici, contrairement à l'indicateur précédent, nous avons modifié le nom : maintenant au lieu de l'habituelle fonction int Start() dans MQL4

int start()
  {

nous utilisons

int RSImql4(

in MQL5. Le nom de la fonction elle-même et la ligne où elle est appelée dans le programme MQL5 sont modifiées.

Le résultat du travail de la bibliothèque est indiqué en fig. 9.

Comparaison de l'indicateur RSIc réécrit à partir de MQL4 et de l'indicateur RSI standard en MQL5.

Figure 9. Comparaison de l'indicateur RSIc réécrit à partir de MQL4 et de l'indicateur RSI standard en MQL5.

6. Installer

Pour configurer ce module, vous devez copier le fichier mql4_2_mql5.mqh vers le dossier MQL5\Include\.

Les fichiers de test doivent être placés dans le dossier MQL5\Indicators.

7. Amélioration

Si vous le souhaitez, vous pouvez étendre les fonctionnalités du module en connectant une bibliothèque de l’article de Migration depuis MQL4 vers MQL5 Ajoutez le fichier InitMQL4.mqh au dossier MQL5\Include et les lignes suivantes avant les paramètres d'entrée :

#include <InitMQL4.mqh>

Vous pouvez vous familiariser avec la liste des modifications nécessaires dans l'article Migration depuis MQL4 vers MQL5.

Conclusion

L'algorithme de transfert de constructions de prix simples de MQL4 à MQL5 à l'aide de la bibliothèque spéciale mql4_2_mql5.mqh est représenté dans cet article.

Pendant le débogage, vous pouvez rencontrer de petits problèmes, mais pour ceux qui sont familiers avec MQL4, ce ne sera pas un problème de s’y adapter.

Compte tenu des spécificités de l'accès aux données dans l'environnement MQL5, le recalcul des indicateurs peut prendre un certain temps. La raison en est que nous devons créer et recalculer les données nécessaires pour les programmes de l'environnement MQL4. Pour un transfert complet d'un indicateur vers l'environnement MQL5, il doit être réécrit en tenant compte des spécificités du stockage et de l'accès aux données dans MQL5.

Post Scriptum

Je souhaite attirer votre attention sur la phrase "Compte tenu des spécificités de l'accès aux données dans l'environnement MQL5, le recalcul des indicateurs peut prendre un certain temps. La raison en est que nous devons créer et recalculer les données nécessaires pour les programmes de l'environnement MQL4." Parfois, cette attente peut durer plusieurs secondes (voir fig. 10-11) :

  

Figure 10. Les données ne sont pas calculées Figure 11. Les données sont disponibles

Il est connecté à une fonctionnalité du terminal client - une seule copie de la partie calcul est créée dans le cache du terminal lors de la création d’une poignée d'un indicateur. Si un tel indicateur (avec les mêmes paramètres d'entrée) n'est pas encore créé (), l'appel du 

iMA(Symb,TimFram,iMAPeriod,ma_shift,ma_method,applied_price);

la fonction créera un indicateur de moyenne mobile ; mais une seule fois.

La prochaine fois, lors d'une tentative de création d'un indicateur déjà existant, le terminal renverra simplement sa poignée

Ainsi, le calcul d'un indicateur est effectué une seule fois, et non juste après la création de sa poignée

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

Fichiers joints |
mql4_2_mql5.mqh (16.45 KB)
macd_mql4.mq5 (4.07 KB)
rsi_mql4.mq5 (4.77 KB)
Application Pratique des Bases de Données pour l'Analyse des Marchés Application Pratique des Bases de Données pour l'Analyse des Marchés
Travailler avec des données est devenu la tâche principale des logiciels modernes, à la fois pour les applications autonomes et en réseau. Pour résoudre ce problème, un logiciel spécialisé a été créé. Ce sont des Systèmes de Gestion de Bases de Données (SGBD), qui peuvent structurer, systématiser et organiser les données pour leur stockage et leur traitement informatique. Quant au trading, la plupart des analystes n'utilisent pas de bases de données dans leur travail. Mais il y a des tâches où une telle solution devrait être pratique. Cet article fournit un exemple d'indicateurs, qui peuvent enregistrer et charger des données à partir de bases de données à la fois avec des architectures client-serveur et serveur de fichiers.
Créer un jeu "Serpent" en MQL5 Créer un jeu "Serpent" en MQL5
Cet article décrit un exemple de programmation de jeu "Snake". Dans MQL5, la programmation du jeu est devenue possible principalement grâce aux fonctionnalités de gestion des événements. La programmation orientée-objet simplifie considérablement ce processus. Dans cet article, vous allez apprendre les fonctionnalités de traitement des événements, les exemples d'utilisation des classes Standard MQL5 Library et les détails des appels de fonction périodiques.
POO en MQL5 par exemple : Traitement des Codes d'Avertissement et d'Erreur POO en MQL5 par exemple : Traitement des Codes d'Avertissement et d'Erreur
L'article décrit un exemple de création d'une classe pour travailler avec les codes de retour du serveur trade et toutes les erreurs qui se produisent lors de l'exécution du programme MQL. Lisez l'article et vous apprendrez à travailler avec des classes et des objets en MQL5. En même temps, c'est un outil pratique pour gérer les erreurs ; et vous pouvez modifier davantage cet outil en fonction de vos besoins spécifiques.
Connexion de l'Expert Advisor avec ICQ en MQL5 Connexion de l'Expert Advisor avec ICQ en MQL5
Cet article décrit la méthode d'échange d'informations entre l'Expert Advisor et les utilisateurs d' ICQ, plusieurs exemples sont présentés. La documentation fournie sera intéressante pour ceux qui souhaitent recevoir des informations de trading à distance depuis un terminal client, via un client ICQ dans leur téléphone mobile ou PDA.