English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Trasferimento di Indicatori da MQL4 a MQL5

Trasferimento di Indicatori da MQL4 a MQL5

MetaTrader 5Esempi | 16 dicembre 2021, 10:18
107 0
Vasily
Vasily

Introduzione

Ciao cari lettori!

Nell'articolo di oggi ti rappresenterò un algoritmo per trasferire semplici calcoli di prezzo da MQL4 a MQL5. Con uno sguardo alla differenza tra MQL5 e MQL4 ho aggiunto la libreria di funzioni mql4_2_mql5.mqh; impareremo come usarlo dopo aver letto questo articolo.

1. Preparazione di un Indicatore per il Trasferimento

Questo articolo riguarda solo il trasferimento dei calcoli degli indicatori; se un indicatore contiene elementi grafici o calcoli di prezzo più complessi, avrai difficoltà.

Prima di tutto, dobbiamo preparare un codice MQL4 per il trasferimento. Diamo un'occhiata a ciò di cui abbiamo bisogno.

Apri MetaEditor 4 con un indicatore necessario, ad esempio MACD; e inizia a modificare i suoi parametri di input:

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

Dobbiamo portare tutto al seguente stato:

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

All'inizio della riga i buffer degli indicatori sono specificati insieme ai simboli & prima dei loro nomi. Il motivo è che dobbiamo passare i collegamenti all'array in cui verranno eseguite tutte le modifiche, ma non l'array stesso!!!

Poi vengono i parametri di input. Nel nostro indicatore MQL4 cambia la seguente riga:

int start()

a

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

Come vedete, si aggiungono altri due elementi obbligatori:

int rates_total, int prev_calculated,

La parte successiva è la linea che abbiamo formato in precedenza.

Ora copia l'intera sezione sull'ultimo simbolo.

//+------------------------------------------------------------------+
//| 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. Creazione di un modello MQL5 per i programmi MQL4

Ora dobbiamo preparare l'ambiente per la nostra sezione.

Per farlo, seleziona la voce "Nuovo" del menu in MetaEditor 5, quindi seleziona "Indicatore personalizzato".

Creare parametri di input (fig. 1) in base ai parametri di input dell'indicatore MQL4:

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

Parametri di input dell'indicatore MACD

Figura 1. Parametri di inputdell'indicatore MACD

Quindi creare buffer indicatori (fig. 2) in base a quanto scritto su di essi nel programma MQL4:

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

I buffer degli indicatori del MACD

Figura 2. I buffer indicatori di MACD

Ora abbiamo formato un modello per il nostro nuovo indicatore.

È necessario apportare diverse modifiche ad esso. Aggiungi una riga sopra i parametri di input:

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

Alla funzione:

int OnInit()

aggiungi la riga

    InitMql4();
e aggiungi una riga che è responsabile dell'avvio dell'ambiente per il programma MQL4 al corpo del programma:
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

Come puoi vedere, questa funzione restituirà il numero di barre disponibili per l'ambiente MQL4; anche qui compare una nuova variabile: 

int CountedMQL4;

Questa variabile è un analogo della variabile MQL5

 prev_calculated,

La variabile CountedMQL4 è dichiarata nel file incluso; passa la quantità di dati calcolati.

Quindi inserisci la nostra sezione MQL4 preparata nel modello MQL5 formato dopo l'ultimo simbolo.

Ora dobbiamo avviare l'indicatore.

Per farlo, aggiungi la seguente riga al corpo del programma:

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

Come vedi, questa riga passerà i dati necessari per il nostro programma MQL4, così come i collegamenti ai buffer risultanti i cui nomi prenderemo dal modello creato in MQL5.

Si dovrebbe ottenere il seguente risultato:

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

Questa è solo la prima fase del trasferimento; ora iniziamo il debug dell'indicatore.

3. Peculiarità di Lavorare con Indicatori Buffer in MQL5

Poiché molte variabili predefinite di MQL4 corrispondono ai nomi delle variabili predefinite di MQL5, è necessario apportare le seguenti modifiche alla sezione MQL4 trasferita:

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

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

Per quanto riguarda le peculiarità dell'organizzazione dell'archiviazione dei dati, il riferimento MQL5 dice quanto segue su SetIndexBuffer():

Nota:

Dopo il legame, il buffer[] dell'array dinamico verrà indicizzato come nei comuni array, anche se l'indicizzazione delle timeserie è pre-installata per l'array legato. Se si desidera modificare l'ordine di accesso agli elementi dell'array indicatore, utilizzare la funzione ArraySetAsSeries() dopo aver legato l'array utilizzando la funzione SetIndexBuffer().

Pertanto, la politica iniziale di accesso ai buffer degli indicatori ora corrisponde a lavorare con gli array ordinari, quindi dovresti sempre aggiungere l'associazione:

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

Il codice risultante è il seguente:

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

Il risultato dell'esecuzione è mostrato nella fig. 3:

Figura 3. Confronto tra l'indicatore MACD riscritto da MQL4 e quello standard in MQL5.


4. Esempio di Trasferimento dell'Indicatore Stocastico

Creiamo un nuovo modello per il nostro indicatore in MetaEditor 5 (fig. 4-5):

Parametri di input

Figura 4. Parametri di Input

Buffer

Figura 5. Buffer

Durante il debug abbiamo scoperto che diversi calcoli della funzione MQL4 "OnInit" dovrebbero essere spostati all'interno della funzione "Start" mediante una semplice copia:

int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
Inoltre è necessario modificare il numero di buffer per il disegno poiché nel nostro programma MQL4 vengono utilizzati 2 buffer per i calcoli interni e altri 2 per il disegno.
#property indicator_plots   2

E cambia lo stato dei buffer che verranno utilizzati dal nostro programma MQL4 per i calcoli interni.

   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
Apportare le modifiche necessarie:
//+------------------------------------------------------------------+
//|                                              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);
  }
//+------------------------------------------------------------------+

Di conseguenza abbiamo ottenuto uno stocastico completo in MQL5 con le costruzioni di prezzo MQL4.

Il risultato del suo funzionamento è mostrato nella fig. 6:

Confronto tra l'indicatore Stocastico riscritto da MQL4 e lo Stocastico standard in MQL5.

Figura 6. Confronto tra l'indicatore Stocastico riscritto da MQL4 e lo Stocastico standard in MQL5.

5. Esempio di Trasferimento dell'Indicatore RSI

Raccogli informazioni sul nostro indicatore:
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

E crea un modello per esso in MetaEditor 5 (fig. 7-8).

Parametro di input dell'indicatore RSI

Figura 7. Parametro di input dell'indicatore RSI

Buffer dell'indicatore RSI

Figura 8. Buffer dell'indicatore RSI

Il numero totale di buffer è 3:

#property indicator_buffers 3

Il numero di buffer per la stampa è uguale a uno:

#property indicator_plots   1

Imposta lo stato dei buffer per i calcoli:

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

Disporre le parti e apportare le modifiche necessarie:

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

Qui, a differenza dell'indicatore precedente, abbiamo cambiato il nome: ora invece della solita funzione int Start() in MQL4

int start()
  {

usiamo

int RSImql4(

in MQL5. Sia il nome della funzione stessa che la riga in cui viene chiamata nel programma MQL5 vengono modificati.

Il risultato del lavoro della libreria è mostrato in fig. 9.

Confronto tra l'indicatore RSIc riscritto da MQL4 e l'indicatore RSI standard in MQL5.

Figura 9. Confronto tra l'indicatore RSIc riscritto da MQL4 e l'indicatore RSI standard in MQL5.

6. Setup

Per configurare questo modulo, è necessario copiare il file mql4_2_mql5.mqh nella cartella MQL5\Include\.

I file di test devono essere inseriti nella cartella MQL5\Indicators.

7. Miglioramento

Se lo desideri, puoi estendere le funzionalità del modulo collegando una libreria dall'articolo Migrazione da MQL4 a MQL5. Aggiungere il file InitMQL4.mqh alla cartella MQL5\Include e le seguenti righe prima dei parametri di input:

#include <InitMQL4.mqh>

È possibile conoscere l'elenco delle modifiche necessarie nell'articolo Migrazione da MQL4 a MQL5.

Conclusione

In questo articolo è rappresentato l'algoritmo di trasferimento di semplici costruzioni di prezzo da MQL4 a MQL5 utilizzando la speciale libreria mql4_2_mql5.mqh.

Durante il debug potresti riscontrare piccoli problemi, ma per coloro che hanno familiarità con MQL4 non sarà un problema affrontarli.

Considerando le peculiarità dell'accesso ai dati in ambiente MQL5, il ricalcolo degli indicatori potrebbe richiedere del tempo. Il motivo è che dobbiamo creare e ricalcolare i dati necessari per i programmi dall'ambiente MQL4. Per un trasferimento a tutti gli effetti di un indicatore nell'ambiente MQL5 dovrebbe essere riscritto considerando le peculiarità della memorizzazione e dell'accesso ai dati in MQL5.

Post Scriptum

Voglio attirare la vostra attenzione sulla frase "Considerare le peculiarità dell'accesso ai dati in ambiente MQL5, il ricalcolo degli indicatori potrebbe richiedere del tempo. Il motivo è che dobbiamo creare e ricalcolare i dati necessari per i programmi dall'ambiente MQL4." A volte questa attesa può durare diversi secondi (vedi fig. 10-11):

  

Figura 10. I dati non vengono calcolati Figura 11. I dati sono disponibili

È collegato a una funzionalità del terminale client: viene creata solo una copia della parte di calcolo nella cache del terminale durante la creazione dell'handle di un indicatore. Se tale indicatore (con gli stessi parametri di input) non è ancora stato creato (), la chiamata della 

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

funzione creerà un indicatore di media mobile; ma solo una volta.

La prossima volta, nel tentativo di creare un indicatore già esistente, il terminale restituirà semplicemente il suo handle.

Così, il calcolo di un indicatore viene eseguito solo una volta, e non subito dopo la creazione della sua maniglia.

Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/66

File allegati |
mql4_2_mql5.mqh (16.45 KB)
macd_mql4.mq5 (4.07 KB)
rsi_mql4.mq5 (4.77 KB)
Applicazione Pratica dei Database per l'Analisi dei Mercati Applicazione Pratica dei Database per l'Analisi dei Mercati
Lavorare con i dati è diventato il compito principale del software moderno, sia per applicazioni standalone che di rete. Per risolvere questo problema è stato creato un software specializzato. Si tratta di Database Management Systems (DBMS), in grado di strutturare, sistematizzare e organizzare i dati per l'archiviazione e l'elaborazione del proprio computer. Per quanto riguarda il trading, la maggior parte degli analisti non utilizza database nel proprio lavoro. Ma ci sono compiti in cui una soluzione del genere dovrebbe essere utile. Questo articolo fornisce un esempio di indicatori, in grado di salvare e caricare dati da database sia con architetture client-server che file-server.
Creazione di un Gioco "Snack" in MQL5 Creazione di un Gioco "Snack" in MQL5
Questo articolo descrive un esempio di programmazione del gioco "Snake". In MQL5, la programmazione del gioco è diventata possibile principalmente grazie alle funzionalità di gestione degli eventi. La programmazione orientata agli oggetti semplifica notevolmente questo processo. In questo articolo imparerai le funzionalità di elaborazione degli eventi, gli esempi di utilizzo delle classi della libreria Standard MQL5 e i dettagli delle chiamate di funzione periodiche.
OOP in MQL5 come Esempio: Elaborazione dei Codici di Avviso e di Errore OOP in MQL5 come Esempio: Elaborazione dei Codici di Avviso e di Errore
L'articolo descrive un esempio di creazione di una classe per lavorare con i codici di ritorno del server di trading e tutti gli errori che si verificano durante l'esecuzione del programma MQL. Leggi l'articolo e imparerai come lavorare con classi e oggetti in MQL5. Allo stesso tempo, questo è uno strumento conveniente per la gestione degli errori; e puoi modificare ulteriormente questo strumento in base alle tue esigenze specifiche.
Collegamento di Expert Advisor con ICQ in MQL5 Collegamento di Expert Advisor con ICQ in MQL5
Questo articolo descrive il metodo di scambio di informazioni tra l'Expert Advisor e gli utenti ICQ, vengono presentati diversi esempi. Il materiale fornito sarà interessante per coloro che desiderano ricevere informazioni di trading in remoto da un terminale del cliente, tramite un client ICQ nel proprio telefono cellulare o PDA.