Descargar MetaTrader 5

Transferir Indicadores de MQL4 a MQL5

18 febrero 2014, 14:52
Vasily
0
1 026

Introducción

¡Hola, queridos lectores!

El el artículo de hoy, les mostraré un algoritmo de transferencia de cálculos de precio simple de MQL4 a MQL5. Viendo las diferencias entre MQL5 y MQL4, añadí la biblioteca de funciones mql4_2_mql5.mqh; así, aprenderemos a usarla en este artículo.

1. Preparar un Indicador para la Transferencia

Este artículo trata solo sobre la transferencia de cálculos de indicador; si un indicador contiene elementos gráficos o cálculos de precio más complejos, tendrá dificultades con ello.

En primer lugar, debemos preparar un código MQL4 para la transferencia. Veamos qué necesitamos para ello.

Abra MetaEditor 4 con un indicador necesario, como por ejemplo MACD, y comience a modificar sus parámetros de entrada:

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

Debemos llevarlo todo al siguiente estado:

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

Al principio de la línea, los buffers de los indicadores se especifican junto con los símbolos & antes de sus nombres. La razón de ello es que necesitamos pasar los enlaces al array donde se harán todos los cambios, ¡pero no el array mismo!

A continuación vienen los parámetros de entrada. En nuestro indicador MQL4, cambie la siguiente línea:

int start()

a

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

Como puede ver, se añaden dos elementos obligatorios más:

int rates_total, int prev_calculated,

La siguiente parte es la línea que formamos anteriormente.

Ahora, copie la sección entera en el último símbolo.

//+------------------------------------------------------------------+
//| 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. Crear una Plantilla MQL5 para programas MQL4

Ahora debemos preparar el entorno para nuestra sección.

Para ello, seleccione el elemento "New" ("Nuevo") del menú en MetaEditor 5, y después seleccione "Custom Indicator" ("Indicador Personalizado").

Cree los parámetros de entrada (fig. 1) de acuerdo con los parámetros de entrada del indicador MQL4:

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

Parámetros de entrada del indicador MACD

Figura 1. parámetros de entrada del indicador MACD

A continuación cree buffers de indicador (fig. 2) de acuerdo con lo que se ha escrito sobre ellos en el programa MQL4:

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

Los buffers de indicador de MACD

Figura 2. Los buffers de indicador de MACD

Ahora ya hemos formado una plantilla para nuestro nuevo indicador.

Deberá realizar varias modificaciones en él. Añada una línea por encima de los parámetros de entrada:

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

A la función:

int OnInit()

añada la línea

    InitMql4();
y añada una línea responsable del inicio del entorno para el programa MQL4 al cuerpo del programa:
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

Como puede ver, esta función devolverá un número de barras accesible para el entorno MQL4; asimismo, aquí aparece una nueva variable: 

int CountedMQL4;

Esta variable es análoga de la variable MQL5

 prev_calculated,

La variable CountedMQL4 se declara en el archivo incluido; pasa la cantidad de datos calculados.

A continuación, inserte nuestra sección MQL4 preparada en la plantilla MQL5 ya formada después del último símbolo.

Ahora debemos iniciar el indicador.

Para ello, añada la siguiente línea al cuerpo del programa:

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

Como puede ver, esta línea pasará datos necesarios para nuestro programa MQL4, así como los enlaces a los buffers resultantes, cuyos nombres tomaremos de la plantilla creada en MQL5.

Obtendremos el siguiente resultado:

//+------------------------------------------------------------------+
//|                                                     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);
  }

Esta es solo la primera fase de la transferencia; ahora empezaremos con el proceso de depuración del indicador.

3. Peculiaridades del Trabajo con buffers de indicador en MQL5

Puesto que muchas variables predefinidas de MQL4 se corresponden con los nombres de variables predefinidas de MQL5, debería realizar los siguientes cambios a la sección de MQL4 transferida:

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

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

En cuanto a las peculiaridades de la organización de almacenamiento de datos, la documentación de referencia de MQL5 dice lo siguiente acerca de SetIndexBuffer():

Nota

Tras la vinculación, el array dinámico buffer[] se indexará como arrays comunes, aún si la indexación de timeseries está preinstalada para el array vinculado. Si desea cambiar el orden de acceso a los elementos del array del indicador, use la función ArraySetAsSeries() tras vincular el array usando la función SetIndexBuffer().

Por tanto, la política inicial de acceso a los buffers de indicador hora se corresponde con el trabajo con arrays ordinarios, de modo que debe añadir siempre la vinculación:

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

El código resultante es el siguiente:

//+------------------------------------------------------------------+
//|                                                    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);
  }
//+------------------------------------------------------------------+

El resultado de la ejecución se muestra en la fig. 3:

Figura 3. Comparación del indicador MACD reescrito de MQL4 y el estándar en MQL5.


4. Ejemplo de Transferencia del Indicador Stochastic (Estocástico)

Creemos una nueva plantilla para nuestro indicador en MetaEditor 5 (fig. 4-5):

Parámetros de entrada

Figura 4. Parámetros de entrada

Buffers

Figura 5. Buffers

Durante el proceso de depuración, descubrimos que varios cálculos de la función de MQL4 "OnInit" se deben mover dentro de la función "Start" simplemente copiándolos:

int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
Asimismo, debemos cambiar el número de buffers para dibujar, puesto que en nuestro programa MQL4 se usan 2 buffers para cálculos internos y otros 2 para dibujar.
#property indicator_plots   2

Y cambie el estado de los buffers que se usarán en el programa MQL4 para cálculos internos.

   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
Haga los cambios necesarios:
//+------------------------------------------------------------------+
//|                                              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);
  }
//+------------------------------------------------------------------+

Como resultado, obtuvimos un Stochastic completo en MQL5 con las construcciones de precio de MQL4.

El resultado de su trabajo se muestra en la fig. 6:

Comparación del Indicador Stochastic reescrito de MQL4 y el Stochastic estándar en MQL5.

Figura 6. Comparación del Indicador Stochastic reescrito de MQL4 y el Stochastic estándar en MQL5.

5. Ejemplo de Transferencia del Indicador RSI

Reúna información sobre nuestro indicador:
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

Y cree una plantilla para ello en MetaEditor 5 (fig. 7-8).

Parámetro de entrada del Indicador RSI

Figura 7. Parámetro de entrada del Indicador RSI

Buffers del Indicador RSI

Figura 8. Buffers del Indicador RSI

El número total de buffers es 3:

#property indicator_buffers 3

El número de buffers para representar es igual a:

#property indicator_plots   1

Configure el estado de los buffers para los cálculos:

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

Distribuya las partes y haga los cambios necesarios:

//+------------------------------------------------------------------+
//|                                                     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);
  }
//+------------------------------------------------------------------+

Aquí, a diferencia del indicador anterior, cambiamos el nombre: ahora, en lugar de la función normal int Start() en MQL4

int start()
  {

usaremos

int RSImql4(

en MQL5. Tanto el nombre de la función misma como la línea en la que se a llama en el programa MQL5 han cambiado.

El resultado de trabajar en la biblioteca se muestra en la fig. 9.

Comparación del Indicador RSI reescrito de MQL4 y el Indicador RSI estándar en MQL5.

Figura 9. Comparación del Indicador RSI reescrito de MQL4 y el Indicador RSI estándar en MQL5.

6. Configuración

Para configurar este módulo, debe copiar el archivo mql4_2_mql5.mqh en la carpeta MQL5\Include\.

Los archivos de prueba se deben c olocar en la carpeta MQL5\Indicators.

7. Mejora

Si lo desea, puede extender la funcionalidad del módulo conectando una biblioteca del artículo Migrating from MQL4 to MQL5 (Traslado de MQL4 a MQL5). Añada el archivo InitMQL4.mqh a la carpeta MQL5\Include y las siguientes líneas antes de los parámetros de entrada:

#include <InitMQL4.mqh>

Puede familiarizarse con la lista de cambios necesarios en el artículo Migrating from MQL4 to MQL5 (Traslado de MQL4 a MQL5).

Conclusión

En este artículo se muestra el algoritmo para transferir construcciones de precio simple de MQL4 a MQL5 usando la biblioteca especial mql4_2_mql5.mqh.

Durante el proceso de depuración es posible que experimente algunos problemas, pero a aquellos que ya conocen MQL4 no les costará salir adelante.

Teniendo en cuenta las peculiaridades de acceso a datos en el entorno MQL5, el recálculo de los indicadores puede llevar algún tiempo. Esto es así porque debemos crear y recalcular datos necesarios para programas del entorno MQL4. Para una transferencia completa de un indicador al entorno MQL5, este debería reescribirse a causa de las peculiaridades de almacenamiento y acceso de datos en MQL5.

Post Scriptum

Me gustaría llamar su atención sobre la frase "Teniendo en cuenta las peculiaridades de acceso a datos en el entorno MQL5, el recálculo de los indicadores puede llevar algún tiempo. Esto es así porque debemos crear y recalcular datos necesarios para programas del entorno MQL4." A veces, esta espera puede durar varios segundos (vea fig. 10-11):

  

Figura 10. Los datos no se calcularon                                                                                             Figura 11. Los datos están accesibles

Está conectado a una herramienta del terminal de cliente: solo una copia de la parte del cálculo se crea en la caché del terminal durante la creación de un identificador de un indicador. Si este indicador (con los mismosparámetros de entrada) no se ha creado todavía (), la llamada a la función 

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

creará un indicador de media móvil, pero solo una vez.

En la siguiente ocasión que se dé un intento de crear un indicador ya existente, el terminal simplemente devolverá su identificador.

De este modo, el cálculo de un indicador se realiza solo una vez, y no justo después de la creación de su identificador.

Traducción del ruso hecha por MetaQuotes Software Corp.
Artículo original: https://www.mql5.com/ru/articles/66

Archivos adjuntos |
mql4_2_mql5.mqh (16.45 KB)
macd_mql4.mq5 (4.07 KB)
rsi_mql4.mq5 (4.77 KB)
Crear un juego de la "Serpiente" en MQL5 Crear un juego de la "Serpiente" en MQL5

Este artículo describe un ejemplo de programación del juego de la "Serpiente". En MQL5, la programación para juegos se hizo posible principalmente a causa de sus herramientas para controlar eventos. La programación orientada al objeto simplifica inmensamente este proceso. En este artículo aprenderá sobre las herramientas de procesamiento de eventos, los ejemplos de uso de las clases de la Biblioteca MQL5 Estándar y detalles de llamadas de funciones periódicas.

Conexión del Asesor Experto con ICQ en MQL5 Conexión del Asesor Experto con ICQ en MQL5

Este artículo describe el método de intercambio de información entre el Asesor Experto y usuarios de ICQ, y presenta varios ejemplos. El material facilitado resultará interesante para aquellos que deseen recibir información de trading remotamente de un terminal de cliente, a través de un ICQ client en su teléfono móvil o PDA.

Aplicación Práctica de Bases de Datos para Análisis de Mercados Aplicación Práctica de Bases de Datos para Análisis de Mercados

Trabajar con datos se ha convertido en la principal tarea para el software moderno, tanto para aplicaciones independientes como para aplicaciones de red. Para resolver este problema se creó un software especializado. Se trata de los Sistemas de Gestión de Bases de Datos (Database Management Systems o DBMS), que pueden estructurar datos para su almacenamiento en el ordenador y su procesamiento. En lo que se refiere a trading, la mayoría de analistas no usan bases de datos en su trabajo. Pero hay tareas donde esta solución resultaría muy práctica. Este artículo facilita un ejemplo de indicadores que puede guardar y cargar datos de bases de datos tanto con arquitecturas de servidor de cliente como de servidor de archivos.

Cómo crear un experto en sólo unos minutos con ayuda de EA Tree: Parte 1 Cómo crear un experto en sólo unos minutos con ayuda de EA Tree: Parte 1

El programa EA Tree es el primer instrumento que permite construir el código de un asesor, sobre la base del método de esquema de bloques "drag and drop". La creación de asesores en EA Tree se lleva a cabo mediante la construcción de bloques que pueden contener funciones del lenguaje MQL5, indicadores técnicos y personalizados, o valores numéricos. Las salidas de los bloques pueden conectarse con las entradas de otros bloques, formando un "árbol de bloques". En base al árbol de bloques, el programa EA Tree genera el código fuente del asesor, que después puede ser compilado en la plataforma comercial MetaTrader 5.