English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Transferindo indicadores do MQL4 para o MQL5

Transferindo indicadores do MQL4 para o MQL5

MetaTrader 5Exemplos | 9 janeiro 2014, 14:07
5 592 0
Vasily
Vasily

Introdução

Olá prezados leitores!

No artigo de hoje vou descrever para vocês um algoritmo de transferência de cálculos de preço simples do MQL4 para o MQL5. Olhando por alto a diferença entre o MQL5 e o MQL4, adicionei a biblioteca de funções mql4_2_mql5.mqh; vamos aprender como utilizá-la após ler esse artigo.

1. Preparando um indicador para transferência

Esse artigo é somente sobre cálculos do indicador de transferência; se um indicador contém elementos gráficos ou cálculos de preço mais complexos, você encontrará dificuldades com ele.

Primeiramente, precisamos preparar um código do MQL4 para transferir. Vamos dar uma olhada naquilo que é necessário para isso.

Abra o MetaEditor 4 com um indicador necessário, por exemplo, MACD: e comece a modificar seus parâmetros de entrada:

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

Precisamos trazer tudo para o seguinte estado:

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

No começo da linha os buffers dos indicadores são especificados juntos com os símbolos & antes de seus nomes. A razão é que precisamos passar os links para o arranjo onde todas as mudanças serão realizadas, mas não o próprio arranjo!!!

Depois surgem os parâmetros de entrada. Em nosso indicador do MQL4 altere a seguinte linha:

int start()

para:

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

Como você pode ver, mais dois elementos obrigatórios foram adicionados:

int rates_total, int prev_calculated,

A próxima parte é a linha que formamos anteriormente.

Agora copie a seção inteira para o ú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. Criando um modelo do MQL5 para programas do MQL4

Agora precisamos preparar o ambiente para nossa seção.

Para fazer isso, selecione o item "Novo" do menu no MetaEditor 5 e depois selecione "personalizar indicador".

Crie os parâmetros de entrada (Fig. 1) de acordo com os parâmetros de entrada do indicador do MQL4:

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

Parâmetros de entrada do indicador MACD

Figura 1. Parâmetros de entrada do indicador MACD

Depois crie buffers de indicador (Fig. 2) de acordo com o que está escrito a respeito deles no programa do MQL4:

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

Os buffers do indicador do MACD

Figura 2. Os buffers do indicador do MACD

Agora formamos um modelo para nosso novo indicador.

Você precisa fazer várias modificações nele. Adicione uma linha acima dos parâmetros de entrada:

#include 
//--- input parameters

Para a função:

int OnInit()

adicione a linha:

    InitMql4();
E adicione uma linha que seja responsável por iniciar o ambiente para o programa do MQL4 para o corpo do programa:
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

Como você pode ver, essa função vai devolver o número de barras disponíveis para o ambiente do MQL4; uma nova variável aparece aqui também:

int CountedMQL4;

Essa variável é uma análoga da variável do MQL5.

 prev_calculated,

A variável CountedMQL4 é declarada no arquivo incluído; ela passa a quantidade de dados calculados.

Depois insira nossa seção preparada do MQL4 dentro do modelo formado do MQL5 após o último símbolo.

Agora precisamos iniciar o indicador.

Para fazer isso, adicione a seguinte linha ao corpo do programa:

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

Como você vê, essa linha passará dados, isso é necessário para nosso programa do MQL4, assim como os links para os buffers consequentes, quais nomes pegaremos do modelo criado no MQL5.

O seguinte resultado deve ser conseguido:

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

Esse é apenas o primeiro estágio da transferência; agora vamos começar a depurar o indicador.

3. Peculiaridades de trabalho com buffers de indicador no MQL5

Já que muitas variáveis predefinidas do MQL4 correspondem aos nomes de variáveis predefinidas do MQL5, você deve realizar as seguintes mudanças para a seção transferida do MQL4:

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

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

Com relação às peculiaridades de organização de armazenamento de dados, a referência MQL5 diz o seguinte sobre SetIndexBuffer():

Nota

Depois de se ligar, o arranjo dinâmico buffer[] será indexado como em arranjos comuns, mesmo se a indexação dos timeseries estiver pré-instalada para o arranjo que está ligado. Se você quiser alterar a ordem de acesso aos elementos do arranjo do indicador, utilize a função ArraySetAsSeries() após vincular o arranjo utilizando a função SetIndexBuffer().

Assim, a política inicial de acesso aos buffers do indicador agora corresponde ao trabalho com arranjos comuns, então, você deve sempre adicionar a vinculação:

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

O código resultante é o seguinte:

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

O resultado da execução é mostrado na Fig. 3:

Figura 3. Comparação do indicador MACD reescrito do MQL4 e o padrão no MQL5


4. Exemplo de transferência do indicador estocástico

Vamos criar um novo modelo para nosso indicador no MetaEditor 5 (Fig. 4-5):

Parâmetros de entrada

Figura 4. Parâmetros de entrada

Buffers

Figura 5. Buffers

Durante a depuração compreendemos que vários cálculos da função "OnInit" do MQL4 devem ser deslocados para a função "Iniciar" através de uma simples cópia:

int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
Precisamos alterar também o número de buffers para desenho, já que em nosso programa do MQL4, 2 buffers são utilizados para cálculos internos e outros 2 são utilizados para desenho.
#property indicator_plots   2

E altere os status dos buffers que serão utilizados pelo nosso programa do MQL4 para cálculos internos.

   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
Faça as alterações necessárias:
//+------------------------------------------------------------------+
//|                                              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 
//--- 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 resultados, obtemos um estocástico completo no MQL5 com as estruturas de preço do MQL4.

O resultado de seu trabalho é mostrado na Fig. 6:

Comparação do indicador estocástico reescrito do MQL4 e o padrão estocástico no MQL5.

Figura 6. Comparação do indicador estocástico reescrito a partir do MQL4 e o indicador estocástico padrão no MQL5

5. Exemplo de transferência do indicador RSI

Reúna informações sobre nosso indicador:
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

E crie um template para isso no MetaEditor 5 (Fig. 7-8):

Parâmetro de entrada do indicador RSI

Figura 7. Parâmetro de entrada do indicador RSI

Buffers do indicador RSI

Figura 8. Buffers do indicador RSI

O número total de buffers é 3:

#property indicator_buffers 3

O número dos buffers para plotagem é igual a um:

#property indicator_plots   1

Ajuste os status dos buffers para os cálculos:

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

Organize as partes e faça as mudanças necessárias:

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

Aqui, diferente do indicador anterior, mudamos o nome: agora, ao invés da função habitual int Start() no MQL4

int start()
  {

usamos:

int RSImql4(

no MQL5. Tanto o nome da própria função quanto a linha onde ela é acionada no programa do MQL5 estão alterados.

O resultado do trabalho da biblioteca é mostrado na Fig. 9:

Comparação do indicador RSIc reescrito do MQL4 e o indicador RSI padrão no MQL5.

Figura 9. Comparação do indicador RSIc reescrito a partir do MQL4 e o indicador RSI padrão no MQL5

6. Configurações

Para configurar este módulo, você precisa copiar o arquivo mql4_2_mql5.mqh para a pasta MQL5\Include\.

Arquivos de testes devem ser colocados na pasta MQL5\Indicators.

7. Melhoria

Se desejar, você pode estender a funcionalidade do módulo conectando uma biblioteca do artigo Migrando do MQL4 para o MQL5. Adicione o arquivo InitMQL4.mqh à pasta MQL5\Include e as seguintes linhas antes da entrada de parâmetros:

#include 

Você pode se familiarizar com lista de alterações necessárias no artigo Migrando do MQL4 para o MQL5.

Conclusão

O algoritmo de transferência de construções de preço simples do MQL4 para o MQL5, utilizando a biblioteca especial mql4_2_mql5.mqh, é representado nesse artigo.

Durante a depuração você pode enfrentar pequenos problemas, mas para aqueles acostumados com o MQL4, não será um problema lidar com eles.

Considerando as peculiaridades do acesso de dados no ambiente do MQL5, o recálculo dos indicadores pode levar algum tempo. A razão é que temos que criar e recalcular dados necessários para programas do ambiente do MQL4. Para uma transferência completa de um indicador para o ambiente do MQL5, ele deve ser reescrito considerando as peculiaridades de armazenamento de acesso de dados do MQL5.

Pós-escrito

Quero chamar sua atenção para a frase "Considerando as peculiaridades de acesso de dados no ambiente do MQL5, o recálculo dos indicadores pode levar algum tempo. A razão é que temos que criar e recalcular dados necessários para programas do ambiente do MQL4". Algumas vezes, essa espera pode durar por vários segundos (veja Fig. 10-11):

Figura 10. Os dados não estão calculados                                                                                 Figura 11. O dado está disponível

Ele está conectado a uma característica do terminal de cliente - somente uma cópia de parte do cálculo é criada no cache do terminal na criação do patamar de um indicador. Se esse indicador (com os mesmos parâmetros de entrada) não estiver criado ainda (), o acionamento da

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

função criará um indicador de média móvel; mas somente uma vez.

Da próxima vez, em uma tentativa de criar um indicador já existente, o terminal vai devolver seu patamar.

Assim, o cálculo de um indicador é realizado somente uma vez, e não logo após a criação de seu patamar.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/66

Arquivos anexados |
mql4_2_mql5.mqh (16.45 KB)
macd_mql4.mq5 (4.07 KB)
rsi_mql4.mq5 (4.77 KB)
Aplicação prática de bancos de dados para análise de mercado Aplicação prática de bancos de dados para análise de mercado
Trabalhar com dados se tornou a tarefa principal para o software moderno - tanto para aplicativos autônomos quanto para os de rede. Para solucionar esse problema um software especializado foi criado. São sistemas de gerenciamento de banco de dados (DBMS) que podem estruturar, sistematizar e organizar dados para seu armazenamento e processamento. Quanto aos negócios, a maioria dos analistas não utiliza bancos de dados em seu trabalho. Mas existem tarefas para as quais essa solução teria que ser útil. Este artigo fornece um exemplo de indicadores que podem salvar e carregar dados da partir de bancos de dados com ambas arquiteturas cliente-servidor ou arquivo-servidor.
Criando um jogo de "Snake" no MQL5 Criando um jogo de "Snake" no MQL5
Este artigo descreve um exemplo da programação do jogo "Snake". No MQL5, a programação do jogo tornou-se possível principalmente por causa dos recursos de manuseio de evento. A programação orientada a objeto simplifica em muito este processo. Neste artigo, você aprenderá os recursos de processamento de eventos, os exemplos de uso de classes da Biblioteca MQL5 Padrão e detalhes das chamadas de função periódica.
OOP no MQL5 por exemplo: Processando os avisos e os códigos de erro OOP no MQL5 por exemplo: Processando os avisos e os códigos de erro
O artigo descreve um exemplo de criação de classe para trabalho com os códigos de retorno do servidor de negócio e todos os erros que ocorrem durante a execução do programa MQL. Leia o artigo e você aprenderá como trabalhar com classes e objetos no MQL5. Ao mesmo tempo, esta é uma ferramenta conveniente para manipular erros; e você ainda pode mudar esta ferramenta de acordo com suas necessidades específicas.
Conexão do Expert Advisor com ICQ no MQL5 Conexão do Expert Advisor com ICQ no MQL5
Este artigo descreve o método de troca de informação entre o Expert Advisor e os usuários do ICQ, são apresentados vários exemplos. O material fornecido será interessante para aqueles que queiram receber informações de negócio remotamente de um terminal de cliente através de um cliente ICQ em seus celulares ou PDA.