English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Göstergeleri MQL4'ten MQL5'e Aktarma

Göstergeleri MQL4'ten MQL5'e Aktarma

MetaTrader 5Örnekler | 15 Aralık 2021, 09:46
153 0
Vasily
Vasily

Giriş

Merhaba, sevgili okuyucu!

Bugünkü makalemde size basit fiyat hesaplamalarını MQL4'ten MQL5'e aktarma algoritmasını açıklayacağım. MQL5 ve MQL4 arasındaki farka bir göz atarak, mql4_2_mql5.mqh işlevler kitaplığını ekledim; bu makaleyi okuduktan sonra bunun nasıl kullanılacağını öğreneceğiz.

1. Aktarma için Gösterge Hazırlama

Bu makale yalnızca gösterge hesaplamalarının aktarılmasıyla ilgilidir; bir gösterge grafik öğeleri veya daha karmaşık fiyat hesaplamaları içeriyorsa bununla ilgili zorluklarla karşılaşırsınız.

İlk olarak, aktarım için bir MQL4 kodu hazırlamamız gerekiyor. Bunun için neye ihtiyacımız olduğuna bir göz atalım.

MetaEditor 4'ü gerekli bir göstergeyle açın, örneğin MACD ve giriş parametrelerini değiştirmeye başlayın:

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

Tümünü aşağıdaki duruma getirmemiz gerekiyor:

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

Satırın başında, göstergelerin arabellekleri adlarından önce & sembolleri ile birlikte belirtilir. Bunun nedeni, tüm değişikliklerin yapılacağı diziye bağlantıları iletmemiz gerekmesidir; ancak dizinin kendisine değil!!!

Ardından giriş parametreleri gelir. MQL4 göstergemizde aşağıdaki satırı değiştirin:

int start()

şuna

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

Gördüğünüz gibi, iki zorunlu öğe daha eklendi:

int rates_total, int prev_calculated,

Bir sonraki kısım, daha önce oluşturduğumuz satırdır.

Şimdi tüm bölümü son sembole kopyalayın.

//+------------------------------------------------------------------+
//| 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. MQL4 Programları için MQL5 Şablonu Oluşturma

Şimdi bölümümüz için ortamı hazırlamamız gerekiyor.

Bunu yapmak için MetaEditor 5'teki menünün "Yeni" öğesini seçin, ardından "Özel gösterge"yi seçin.

MQL4 göstergesinin giriş parametrelerine göre giriş parametreleri oluşturun (şek. 1):

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

MACD göstergesinin giriş parametreleri

Şekil 1. MACD göstergesinin giriş parametreleri

Ardından, MQL4 programında onlara ilişkin yazılanlara göre gösterge arabellekleri oluşturun (şek. 2):

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

MACD'nin gösterge arabellekleri

Şekil 2. MACD'nin gösterge arabellekleri

Şimdi yeni göstergemiz için bir şablon oluşturduk.

Üzerinde birkaç değişiklik yapmanız gerekiyor. Giriş parametrelerinin üzerine bir satır ekleyin:

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

İşlev için:

int OnInit()

satırı ekleyin

    InitMql4();
ve programın gövdesine MQL4 programı için ortamı başlatmaktan sorumlu bir satır ekleyin:
int bars=MQL4Run(rates_total,prev_calculated);
// bars - number of bars available to MQL4 programs

Gördüğünüz gibi, bu işlev MQL4 ortamı için mevcut olan çubukların sayısını döndürecektir; burada da yeni bir değişken ortaya çıkar: 

int CountedMQL4;

Bu değişken, MQL5 değişkeninin bir analogudur.

 prev_calculated,

CountedMQL4 değişkeni içerilen dosyada bildirilir; hesaplanan veri miktarını iletir.

Daha sonra hazırladığımız MQL4 bölümümüzü oluşan MQL5 şablonuna son sembolden sonra ekleyin.

Şimdi göstergeyi başlatmamız gerekiyor.

Bunu yapmak için programın gövdesine aşağıdaki satırı ekleyin:

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

Gördüğünüz gibi, bu satır MQL4 programımız için gerekli olan verileri ve ayrıca adlarını MQL5'te oluşturulan şablondan alacağımız sonuç arabelleklerinin bağlantılarını iletecektir.

Aşağıdaki sonuç elde edilmelidir:

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

Bu aktarımın sadece ilk aşaması; şimdi göstergede hata ayıklamaya başlıyoruz.

3. MQL5'te Gösterge Arabellekleriyle Çalışmanın Özellikleri

MQL4'ün önceden tanımlanmış birçok değişkeni, MQL5'in önceden tanımlanmış değişkenlerinin adlarına karşılık geldiği için, aktarılan MQL4 bölümünde aşağıdaki değişiklikleri yapmalısınız:

MQL4
MQL5
IndicatorCounted()
prev_calculated
 Çubuklar rates_total
 iMA( iMAMql4(
 iMAOnArray( iMAOnArrayMql4(

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

Veri depolama düzenlemesinin özellikleriyle ilgili olarak, MQL5 referansı SetIndexBuffer() hakkında şunları belirtir:

Not

Bağlamadan sonra, buffer[] dinamik dizisi, timeseries indekslemesi bağlı dizi için önceden yüklenmiş olsa dahi, genel dizilerdeki gibi indekslenecektir. Gösterge dizisinin öğelerine erişim sırasını değiştirmek istiyorsanız, SetIndexBuffer() işlevini kullanarak diziyi bağladıktan sonra ArraySetAsSeries() işlevini kullanın.

Dolayısıyla, gösterge arabelleklerine erişmenin ilk politikası şimdi sıradan dizilerle çalışmaya karşılık gelir; bu nedenle her zaman bağlamayı eklemelisiniz:

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

Ortaya çıkan kod aşağıdaki gibidir:

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

Yürütmenin sonucu, şek. 3'te gösterilmiştir:

Şekil 3. MQL4'ten yeniden yazılan MACD göstergesi ile MQL5'teki standart göstergenin karşılaştırması.


4. Stokastik Göstergeyi Aktarma Örneği

MetaEditor 5'teki göstergemiz için yeni bir şablon oluşturalım (şek. 4-5):

Giriş parametreleri

Şekil 4. Giriş parametreleri

Arabellekler

Şekil 5. Arabellekler

Hata ayıklama sırasında MQL4 "OnInit" işlevinden yapılan birkaç hesaplamanın basit kopyalamayla "Başlat" işlevinin içine taşınması gerektiğini anladık:

int draw_begin1=KPeriod+Slowing;
int draw_begin2=draw_begin1+DPeriod;
Ayrıca, MQL4 programımızda dahili hesaplamalar için 2 arabellek ve çizim için 2 arabellek kullanıldığı için çizim için arabellek sayısını değiştirmemiz gerekiyor.
#property indicator_plots   2

Ve dahili hesaplamalar için MQL4 programımız tarafından kullanılacak arabelleklerin durumunu değiştirin.

   SetIndexBuffer(2,HighesBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowesBuffer,INDICATOR_CALCULATIONS);
Gerekli değişiklikleri yapın:
//+------------------------------------------------------------------+
//|                                              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);
  }
//+------------------------------------------------------------------+

Sonuç olarak, MQL4 fiyat yapıları ile MQL5'te tam donanımlı bir stokastik elde ettik.

Çalışmasının sonucu, şek. 6'da gösterilmiştir:

MQL4'ten yeniden yazılan Stokastik gösterge ile MQL5'teki standart Stokastik'in karşılaştırması.

Şekil 6. MQL4'ten yeniden yazılan Stokastik gösterge ile MQL5'teki standart Stokastik'in karşılaştırması.

5. RSI Göstergesini Aktarma Örneği

Göstergemiz hakkında bilgi toplayın:
//---- input parameters
extern int RSIPeriod=14;
//---- buffers
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];

Ve bunun için MetaEditor 5'te bir şablon oluşturun (şek. 7-8).

RSI göstergesinin giriş parametresi

Şekil 7. RSI göstergesinin giriş parametresi

RSI göstergesinin arabellekleri

Şekil 8. RSI göstergesinin arabellekleri

Toplam arabellek sayısı 3'tür:

#property indicator_buffers 3

Çizim için arabellek sayısı bire eşittir:

#property indicator_plots   1

Hesaplamalar için arabelleklerin durumunu ayarlayın:

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

Parçaları düzenleyin ve gerekli değişiklikleri yapın:

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

Burada, önceki göstergeden farklı olarak, adı değiştirdik: MQL4'teki normal int Start() işlevinin yerine

int start()
  {

MQL5'i

int RSImql4(

kullanıyoruz. MQL5 programında hem işlevin adı hem de çağrıldığı satır değiştirilir.

Kitaplık çalışmasının sonucu, şek. 9'da gösterilmiştir.

MQL4'ten yeniden yazılan RSIc göstergesi ile MQL5'teki standart RSI göstergesinin karşılaştırması.

Şekil 9. MQL4'ten yeniden yazılan RSIc göstergesi ile MQL5'teki standart RSI göstergesinin karşılaştırması.

6. Ayarlama

Bu modülü ayarlamak için, mql4_2_mql5.mqh dosyasını MQL5\Include\ klasörüne kopyalamanız gerekir.

Test dosyaları MQL5\Indicators klasörüne yerleştirilmelidir.

7. İyileştirme

Dilerseniz modülün işlevselliğini MQL4'ten MQL5'e Geçiş makalesinden bir kitaplığa bağlanarak genişletebilirsiniz. InitMQL4.mqh dosyasını MQL5\Include klasörüne ekleyin ve giriş parametrelerinden önce aşağıdaki satırları ekleyin:

#include <InitMQL4.mqh>

Gerekli değişikliklerin listesini MQL4'ten MQL5'e Geçiş makalesinde bulabilirsiniz.

Sonuç

Bu makalede özel mql4_2_mql5.mqh kitaplığı kullanılarak basit fiyat yapılarının MQL4'ten MQL5'e aktarılmasının algoritması açıklanmıştır.

Hata ayıklama sırasında küçük sorunlar yaşayabilirsiniz ama MQL4 hakkında bilgi sahibi olanlar için bunların üstesinden gelmek sorun olmayacaktır.

MQL5 ortamında verilere erişmenin özellikleri göz önünde bulundurulduğunda, göstergelerin yeniden hesaplanması biraz zaman alabilir. Bunun nedeni, programlar için gerekli verileri MQL4 ortamından oluşturup yeniden hesaplamamız gerekmesidir. Bir göstergenin MQL5 ortamına tam donanımlı aktarımı için, bunun, MQL5'te veri depolama ve erişme özellikleri dikkate alınarak yeniden yazılması gerekir.

Post Scriptum

"MQL5 ortamında verilere erişmenin özellikleri göz önünde bulundurulduğunda, göstergelerin yeniden hesaplanması biraz zaman alabilir. Bunun nedeni, programlar için gerekli verileri MQL4 ortamından oluşturup yeniden hesaplamamız gerekmesidir." ifadesine dikkatinizi çekmek istiyorum. Bazen bu bekleme birkaç saniye sürebilir (bkz. şek. 10-11):

  

Şekil 10. Veri hesaplanmaz                                                                                                  Şekil 11. Veri mevcut

Bu, istemci terminalinin bir özelliğine bağlıdır - bir göstergenin tanıtıcısı oluşturulurken terminalin önbelleğinde hesaplama bölümünün yalnızca bir kopyası oluşturulur. Böyle bir gösterge (aynı giriş parametreleriyle) henüz oluşturulmamışsa (), 

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

işlevin çağrısı sadece bir kez hareketli bir ortalama göstergesi oluşturacaktır.

Bir dahaki sefere, zaten var olan bir gösterge oluşturma girişiminde, terminal yalnızca tanıtıcısını döndürecektir.

Bu nedenle, bir göstergenin hesaplanması, tanıtıcısı oluşturulduktan hemen sonra değil, yalnızca bir kez gerçekleştirilir.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/66

Ekli dosyalar |
mql4_2_mql5.mqh (16.45 KB)
macd_mql4.mq5 (4.07 KB)
rsi_mql4.mq5 (4.77 KB)
Piyasa Analizi için Veritabanlarının Pratik Uygulaması Piyasa Analizi için Veritabanlarının Pratik Uygulaması
Verilerle çalışmak, hem bağımsız hem de ağ uygulamaları için modern yazılımların ana görevi haline geldi. Bu sorunu çözmek için özel bir yazılım oluşturuldu. Bunlar, bilgisayar depolama ve işlemeleri için verileri yapılandırabilen, sistematikleştirebilen ve düzenleyebilen Veritabanı Yönetim Sistemleridir (DBMS). Alım satım işlemine gelince, analistlerin çoğu çalışmalarında veritabanlarını kullanmaz. Ancak böyle bir çözümün işe yaraması gereken görevler vardır. Bu makale, hem istemci-sunucu hem de dosya-sunucu mimarileriyle veritabanlarından veri kaydedebilen ve yükleyebilen göstergelere ilişkin bir örnek sağlar.
MQL5'te "Yılan" Oyunu Oluşturma MQL5'te "Yılan" Oyunu Oluşturma
Bu makalede, bir "Yılan" oyun programlama örneği açıklanmaktadır. MQL5'te oyun programlama, öncelikle olay işleme özellikleri nedeniyle mümkün hale geldi. Nesne yönelimli programlama bu süreci büyük ölçüde basitleştirir. Bu makalede olay işleme özelliklerini, Standart MQL5 Kitaplık sınıflarının kullanım örneklerini ve periyodik işlev çağrılarının detaylarını öğreneceksiniz.
Örnek olarak MQL5'te OOP: Uyarı ve Hata Kodlarını İşleme Örnek olarak MQL5'te OOP: Uyarı ve Hata Kodlarını İşleme
Makalede, alım satım sunucusu dönüş kodlarıyla çalışmak için bir sınıf oluşturma örneği ve MQL programının çalıştırılması sırasında meydana gelen tüm hatalar açıklanmaktadır. Makaleyi okuduktan sonra MQL5'te sınıflar ve nesnelerle nasıl çalışacağınızı öğreneceksiniz. Aynı zamanda bu, hataları işlemek için uygun bir araçtır ve bu aracı özel ihtiyaçlarınıza göre daha da değiştirebilirsiniz.
Expert Advisor'ın MQL5'te ICQ ile Bağlantısı Expert Advisor'ın MQL5'te ICQ ile Bağlantısı
Bu makalede, Expert Advisor ve ICQ kullanıcıları arasındaki bilgi alışverişi yöntemi açıklanmakta olup birkaç örnek sunulmaktadır. Sunulan materyal, bir istemci terminalinden, bir ICQ istemcisi aracılığıyla cep telefonlarına veya PDA'larına alım satım bilgilerini uzaktan almak isteyen kişiler için ilgi çekici olacaktır.