English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Yeni Başlayanlar için MQL5'te Dijital Filtrelerin Pratik Uygulaması

Yeni Başlayanlar için MQL5'te Dijital Filtrelerin Pratik Uygulaması

MetaTrader 5Örnekler | 10 Aralık 2021, 17:12
155 0
Nikolay Kositsin
Nikolay Kositsin

Giriş

Önceki makalemde basit göstergenin bir kod analizini yaptım ve bu göstergenin MetaTrader 5 İstemci Terminali ile etkileşimini kısmen ele aldım. Şimdi, daha ileri gitmeden önce, MetaEditor'daki "Araç Kutusu" penceresinin "Hatalar" sekmesindeki expert derleme sonuçlarına daha yakından bakmalıyız. Buradan, daha önce önerdiğim SMA göstergesinin kodunu daha fazla incelemeye başlayabilirsiniz.

Gösterge derleme hataları

Bizim durumumuzda, kodun iki sürümünden herhangi birini derlerken, bir değişiklik olmaması durumunda, derleme işlemi beklenen sonuçla oldukça düzgündür:


Herhangi bir hata yok; .mq5 uzantılı gösterge dosyası ile birlikte .ex5 uzantılı benzer bir dosya ortaya çıktı.

Tipik olarak, kodla çalışırken hatalardan kaçınamazsınız. Bunlar programcılar tarafından düzenli olarak yapılırlar. Bu amaçla MetaEditor, derlenmiş kodu her tür hatayı kontrol etmek için yerleşik bir mekanizmaya sahiptir ve bu hataları bulduğunda, oluşturulan hataların tam bir listesini verecektir.

Bir hatanın konumunu tespit etmek için, "Araç Kutusu" penceresinde hatanın içeriğinin bulunduğu uygun satıra çift tıklamanız yeterlidir. Derleyici çoğu durumda, uygun simgesini kullanarak hatanın bulunduğu kod satırını doğru bir şekilde belirtir.

Bir şeyi göz önünde bulundurmalısınız. Koddaki bir hata, bir dizi derleme hatası oluşturabilir. Bu nedenle, hata dizisini ortadan kaldırmak için derleyicinin hata bulduğu ilk satıra gitmek ve kodu düzeltmek yeterlidir. Oldukça doğal olarak, bu tür birçok derleme hatası dizisi olabilir. Dolayısıyla, koddaki bir hatayı düzelttikten sonra onu yeniden derlemeliyiz ve derleyici hata bulursa, "Araç Kutusu" penceresinin "Hatalar" sekmesinde ilk satırı aramalıyız:

Belki de bunu anlamanın en etkili yöntemi, derleyicinin bilinçli olarak yapılan hatalara nasıl tepki vereceğini incelemek için kodumuz üzerinde anlamlı, yıkıcı bir etki olacaktır. Teknik oldukça basittir; kodun belirli bir bölümünde hatayı yapın, MetaEditor'da "Derle" düğmesine basın ve derlemenin sonucunu izleyin. Kod üzerinde bu tür bir yıkıcı etkinin sonucunu sezgisel olarak hatırlamanız daha iyi olacaktır. Her durumda, bu, MQL5 koduyla çalışırken daha sonraki uygulamalarda faydalı olabilir.

Göstergenin kaynak kodundaki olası yıkıcı değişikliklerin listesi şu şekildedir:

  1. Herhangi bir işleç veya değişkende boşluk bırakmak.
  2. Noktalı virgül ";" işaretini silmek.
  3. Kodun farklı bölümlerine ";" işareti eklemek.
  4. Bir işleci silmek.
  5. Bir kaşlı ayracı veya parantezi çıkarmak veya eklemek.
  6. Virgül "," işaretini kaldırmak.
  7. OnCalculate() işlevine fazladan bir giriş parametresi eklemek.
  8. Bir değişkeni sıfıra bölmek.
  9. "if" işleç satırında "==" işaretini "=" olarak değiştirmek.
  10. Bir değişkende artış yönünü çubuk++'dan çubuk--'ye değiştirmek.

Doğal olarak derleyici her zaman hatanın yapıldığı yeri tam bulamaz. Bu nedenle, bu tür durumlarla nasıl başa çıkılacağını anlamak için bu ön çalışmayı yapmaya değer. Hatalarla ilgili bir açıklama daha - MetaEditor derleyicisi yalnızca MQL5 dilinin hatalarını belirler ve çoğu durumda mantıksal programlama hatalarını bulamaz!

MQL5 kelime dağarcığı

Herhangi bir kişiyi dinlerseniz, söz konusu kişinin insan dilinin tüm zenginliğine rağmen, düşüncelerini ve ihtiyaçlarını ifade eden araçların yalnızca küçük bir kısmını kullandığını anlarsınız. Çoğu durumda, gerçekte kullanılan kelime dağarcığının mevcut olandan önemli ölçüde daha az olduğu ortaya çıkar. Aynı prensip MQL5'e de uygulanabilir. Başlangıçta, MQL5 dili konusunda uzmanlaşma aşamasında, bu programlama dilinin en sık kullanılan işleçlerine ve ifadelerine alışmalısınız. Ve bu dili öğrendikçe, gerçek kelime dağarcığınızın sınırlarını yavaş yavaş genişletebilirsiniz.

Örneğin, dört tür değişken kullanabilirsiniz; (int, double, bool, string), if-else koşullu işleci, for döngü işleci, {} compound işleci ve return işleci. Ayrıca noktalı virgülü ";" ve virgülü "," kullanmayı da iyice öğrenmelisiniz. Belki de matematiksel ve trigonometrik işlevleri öğrenmek mantıklı olacaktır. Bu araçlar, ilk programlama becerilerinizi eğitmek ve uygulamak için fazlasıyla yeterli!

Daha fazla gösterge iyileştirme

MetaTrader İstemci Terminali'nde görüntülenen iyileştirilen göstergenin MQL5 özellikleri oldukça basit ve standarttır. Bunlar, genel düzeydeki işleçlerden oluşurlar:

//---- Indicator's author
#property copyright "2010, MetaQuotes Software Corp."
//---- Author's web-site link
#property link      "https://www.mql5.com"
//---- Indicator version number
#property version   "1.00"
//---- Drawing the indicator in the main window
#property indicator_chart_window
//---- One buffer is used for calculating and drawing the indicator
#property indicator_buffers 1
//---- Only one graphical plotting is used
#property indicator_plots   1
//---- Drawing the indicator as line
#property indicator_type1   DRAW_LINE
//---- Red is used as indicator's line color
#property indicator_color1  Red
//---- Indicator line is continuous curve
#property indicator_style1  STYLE_SOLID
//---- Indicator line thickness is equal to 1
#property indicator_width1  1
//---- Displaying indicator's label
#property indicator_label1  "SMA"

Ve OnInit() işlev çağrılarından:

//---- Variable initialization for indicator's short name
   string shortname;
   StringConcatenate(shortname,"FATL(",FATLShift,")");
//--- Creating labels to display in Data Window
   PlotIndexSetString(0,PLOT_LABEL,shortname);
//--- Creating name to display in a separate window and in tool-tip
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- Defining accuracy of displaying indicator's values
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- Prohibition of displaying blank values
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
StringConcatenate() işlevi, bu formülü kullanarak gösterge adının dizesini birleştirir:
   shortname = shortname + "SMA(" + MAPeriod + "," + MAShift + ")";

Bir Göstergeyi Diğerine Uygulamak adlı makaledeki önerilere göre, PlotIndexSetInteger() işlev çağrısını OnCalculate() işlevine eklemek herhangi bir sorun teşkil etmez:

//---- Calculating the 'first' starting number for the bars recalculation loop
   if(prev_calculated==0)        // Checking the first start of the indicator calculation
     {
      first=FATLPeriod-1+begin;  // Starting number for calculation of all bars
      //--- Increasing the start of data position by 'begin' bars, because the 
      //    calculations are based on data of another indicator
      if(begin>0)
         PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin+FATLPeriod);
     }
   else first=prev_calculated-1; // Starting number for calculation of new bars
Bu ek kod satırlarının eklenmesinden sonra göstergemizin boyutunun biraz artması ve biraz daha karmaşık hale gelmesi doğaldır, ancak artık daha kullanıcı dostu bir arayüze sahip olacaktır.

Yeni göstergeler oluşturmak için bir şablon olarak önceki çalışmanın sonucu

Tüm bunlar kesinlikle ilginç, ancak oldukça doğal bir soru var: Neden tekerleği icat edip, İstemci Terminalinde iki sürüm halinde mevcut olan gösterge kodunu tekrarlayalım? Moving Average.mq5 teknik göstergesi ve Custom Moving Average.mq5 özel göstergesi şeklinde. Yanıt basit. Daha önce önerdiğim SMA gösterge kodunu şablon olarak kullanarak benzer göstergelerin kodunu nasıl hızlı bir şekilde yazacağınızı öğrenmek; böylece entelektüel kaynaklarınızdan mümkün olduğunca tasarruf etmek! Örneğin, Finware adresinden FATL gibi bir dijital filtre için MQL5'te kod yazmayı deneyebilirsiniz.

Genel olarak, dijital filtreyi hesaplama formülü şu şekildedir:

FİLTRE = TOPLAM (K(i) * KAPANIŞ (i), FilterPeriod)

Burada:

  • TOPLAM — Toplam.
  • K(i) — Ağırlık katsayısı.
  • KAPANIŞ (i) — Mevcut çubuğun Kapanış fiyatı.
  • FilterPeriod — Ortalama alma için çubuk sayısı. 

Bu formül, SMA gösterge formülünden pek farklı değildir:

SMA = TOPLAM ((1 / MAPeriod ) * KAPANIŞ (i), MAPeriod)

Aradaki fark, dijital filtre ile hesaplamaların yapıldığı dönemin kesinlikle sabit olması ve belirli dijital filtre ve K(i) ağırlık katsayıları için ayrı olmasıdır. Ağırlık katsayıları ve dijital filtre dönemi, özel algoritmalar kullanılarak hesaplanır. Bu algoritmaları analiz etmek bu makalenin kapsamı dışındadır; bu nedenle kendimizi FATL dijital filtresi için hazır değerler kullanmakla sınırlayacağız. Dijital sinyal filtreleme fikriyle ilgilenenler Digital Methods Generator web sitesini (Rusça) ziyaret edebilirler. MQL4'teki bir FATL göstergesi varyantının formülü bir sır değildir:

     FATL =  0.4360409450 * Close[bar + 0]
           + 0.3658689069 * Close[bar + 1]
           + 0.2460452079 * Close[bar + 2]
           + 0.1104506886 * Close[bar + 3]
           - 0.0054034585 * Close[bar + 4]
           - 0.0760367731 * Close[bar + 5]
           - 0.0933058722 * Close[bar + 6]
           - 0.0670110374 * Close[bar + 7]
           - 0.0190795053 * Close[bar + 8]
           + 0.0259609206 * Close[bar + 9]
           + 0.0502044896 * Close[bar + 10]
           + 0.0477818607 * Close[bar + 11]
           + 0.0249252327 * Close[bar + 12]
           - 0.0047706151 * Close[bar + 13]
           - 0.0272432537 * Close[bar + 14]
           - 0.0338917071 * Close[bar + 15]
           - 0.0244141482 * Close[bar + 16]
           - 0.0055774838 * Close[bar + 17]
           + 0.0128149838 * Close[bar + 18]
           + 0.0226522218 * Close[bar + 19]
           + 0.0208778257 * Close[bar + 20]
           + 0.0100299086 * Close[bar + 21]
           - 0.0036771622 * Close[bar + 22]
           - 0.0136744850 * Close[bar + 23]
           - 0.0160483392 * Close[bar + 24]
           - 0.0108597376 * Close[bar + 25]
           - 0.0016060704 * Close[bar + 26]
           + 0.0069480557 * Close[bar + 27]
           + 0.0110573605 * Close[bar + 28]
           + 0.0095711419 * Close[bar + 29]
           + 0.0040444064 * Close[bar + 30]
           - 0.0023824623 * Close[bar + 31]
           - 0.0067093714 * Close[bar + 32]
           - 0.0072003400 * Close[bar + 33]
           - 0.0047717710 * Close[bar + 34]
           + 0.0005541115 * Close[bar + 35]
           + 0.0007860160 * Close[bar + 36]
           + 0.0130129076 * Close[bar + 37]
           + 0.0040364019 * Close[bar + 38]; 

MQL5'te gösterge arabelleklerindeki çubuklar, MQL4'tekine zıt yönde hesaplanır. Dolayısıyla, bu formülü MQL5 göstergelerinde kullanmak için parantez içindeki arttırma işlemini eksiltme işlemiyle değiştirmeliyiz. MQL5'te Close[] zaman serisi dizisinin olmaması nedeniyle, onu daha uygun bir varyantla değiştirmeliyiz - price[]. MetaEditor'da aşağıdaki menü komutunu kullanarak bu görevi otomatikleştirmek oldukça doğaldır:

Düzenli olarak karşılaşılan Kapanış [çubuk + ifadesi fiyat [çubuk - ile değiştirilmelidir:

Bu iletişim kutusunda "Tümünü Değiştir" düğmesine tıklayın. Sonuç olarak, MQL5'te FATL gösterge hesaplaması için gerekli formülü elde ederiz:

     FATL =  0.4360409450 * price[bar - 0]
           + 0.3658689069 * price[bar - 1]
           + 0.2460452079 * price[bar - 2]
           + 0.1104506886 * price[bar - 3]
           - 0.0054034585 * price[bar - 4]
           - 0.0760367731 * price[bar - 5]
           - 0.0933058722 * price[bar - 6]
           - 0.0670110374 * price[bar - 7]
           - 0.0190795053 * price[bar - 8]
           + 0.0259609206 * price[bar - 9]
           + 0.0502044896 * price[bar - 10]
           + 0.0477818607 * price[bar - 11]
           + 0.0249252327 * price[bar - 12]
           - 0.0047706151 * price[bar - 13]
           - 0.0272432537 * price[bar - 14]
           - 0.0338917071 * price[bar - 15]
           - 0.0244141482 * price[bar - 16]
           - 0.0055774838 * price[bar - 17]
           + 0.0128149838 * price[bar - 18]
           + 0.0226522218 * price[bar - 19]
           + 0.0208778257 * price[bar - 20]
           + 0.0100299086 * price[bar - 21]
           - 0.0036771622 * price[bar - 22]
           - 0.0136744850 * price[bar - 23]
           - 0.0160483392 * price[bar - 24]
           - 0.0108597376 * price[bar - 25]
           - 0.0016060704 * price[bar - 26]
           + 0.0069480557 * price[bar - 27]
           + 0.0110573605 * price[bar - 28]
           + 0.0095711419 * price[bar - 29]
           + 0.0040444064 * price[bar - 30]
           - 0.0023824623 * price[bar - 31]
           - 0.0067093714 * price[bar - 32]
           - 0.0072003400 * price[bar - 33]
           - 0.0047717710 * price[bar - 34]
           + 0.0005541115 * price[bar - 35]
           + 0.0007860160 * price[bar - 36]
           + 0.0130129076 * price[bar - 37]
           + 0.0040364019 * price[bar - 38];

Şimdi hesaplama algoritmasının ele alındığı göstergeyi kodlamaya başlayabiliriz. Bunun için öncelikle MetaEditor'da SMA_1_en.mq5 göstergesini açın ve FATL_en.mq5 olarak kaydedin. Gösterge şablonu hazır; şimdi içindeki gösterge hesaplama algoritmasını değiştirmemiz ve değişkenlerde çoğunlukla yüzeysel olmak üzere bazı değişiklikler yapmamız gerekiyor. FATL filtre hesaplaması için son bahsedilen formülün tüm bloğunu seçip Windows panosuna kopyalamalısınız. Ardından, FATL.mq5 gösterge kodunda, gösterge arabelleğinin son başlatılması dışında döngü işleci içindeki kodun tamamını kaldırın:

//---- Main loop of indicator calculation
   for(bar=first; bar<rates_total; bar++)
     {
     


      //---- Indicator buffer's cell initialization with FATL value
      ExtLineBuffer[bar]=FATL;
     }

Silinen bu kod yerine, Windows panosundan FATL dijital filtre hesaplama algoritmasını yapıştıracağız. Yukarıda anlattığım değiştirme prosedürünü kullanarak SMA sözcüğünü daha uygun FATL ile değiştirmeliyiz. Yapılacak işlem kesinlikle aynı; MAPeriod ve MAShift giriş değişkenlerinin adlarını sırasıyla FATLPeriod ve FATLShft ile değiştirmeliyiz. FATLPeriod değişkeni, 39'a eşit sabit bir değere sahip olduğu için harici değişkenlerden kaldırılmalıdır. Aynı sebepten dolayı, OnInit() işlevinde StringConcatenate() işlecinden kaldırılmalıdır. Artık iii yerel değişkenine gerek yok; bu nedenle kaldırılabilir. Son olarak, gösterge çizgisinin rengini mavi olarak değiştirebilir ve çizginin kendisini biraz daha kalın hale getirebilirsiniz.

SMA_1_en.mq5 koduyla yapılan bu basit işlemeden sonra, istenen FATL_en.mq5 gösterge kodunu alırız:

//+------------------------------------------------------------------+
//|                                                      Fatl_en.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
//---- Indicator's author
#property copyright "2010, MetaQuotes Software Corp."
//---- Author's web-site link
#property link      "https://www.mql5.com"
//---- Indicator version number
#property version   "1.00"
//---- Drawing the indicator in the main window
#property indicator_chart_window
//---- One buffer is used for calculating and drawing the indicator
#property indicator_buffers 1
//---- Only one graphical plotting is used
#property indicator_plots   1
//---- Drawing the indicator as line
#property indicator_type1   DRAW_LINE
//---- Blue is used as indicator's line color
#property indicator_color1  Blue
//---- Indicator line is continuous curve
#property indicator_style1  STYLE_SOLID
//---- Indicator line thickness is equal to 2
#property indicator_width1  2
//---- Displaying indicator's label
#property indicator_label1  "FATL"

//---- Input parameters of indicator
input int FATLShift=0; // FATL horizontal shift in bars

//---- Declaring and initializing a variable to store the number of calculated bars
int FATLPeriod=39;

//---- Declaration of dynamic array, which will be 
//     used later as indicator buffer
double ExtLineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
void OnInit()
  {
//----+
//---- Transformation of ExtLineBuffer dynamic array into indicator buffer
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
//---- Horizontal shift of indicator by FATLShift
   PlotIndexSetInteger(0,PLOT_SHIFT,FATLShift);
//---- Setting the position from which the drawing of indicator will start
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,FATLPeriod);
//---- Variable initialization for indicator's short name
   string shortname;
   StringConcatenate(shortname,"FATL(",FATLShift,")");
//--- Creating labels to display in Data Window
   PlotIndexSetString(0,PLOT_LABEL,shortname);
//--- Creating name to display in a separate window and in tool-tip
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- Defining accuracy of displaying indicator's values
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- Prohibition of displaying blank values
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//----+
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,     // amount of history in bars at the current tick
                const int prev_calculated, // amount of history in bars at the previous tick
                const int begin,           // beginning number of reliable count of bars
                const double &price[]      // price array for indicator calculation
                )
  {
//----+   
//---- Check if the number of bars is sufficient for calculation
   if(rates_total<FATLPeriod-1+begin)
      return(0);

//---- Declaring local variables
   int first,bar;
   double Sum,FATL;

//---- Calculating the 'first' starting number for the bars recalculation loop
   if(prev_calculated==0)        // Checking the first start of the indicator calculation
     {
      first=FATLPeriod-1+begin;  // Starting number for calculation of all bars
      //--- Increasing the start of data position by 'begin' bars, because the 
      //    calculations are based on data of another indicator
      if(begin>0)
         PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin+FATLPeriod);
     }
   else first=prev_calculated-1; // Starting number for calculation of new bars

//---- Main loop of indicator calculation
   for(bar=first; bar<rates_total; bar++)
     {
      //---- 
      FATL=0.4360409450*price[bar-0]
           + 0.3658689069 * price[bar - 1]
           + 0.2460452079 * price[bar - 2]
           + 0.1104506886 * price[bar - 3]
           - 0.0054034585 * price[bar - 4]
           - 0.0760367731 * price[bar - 5]
           - 0.0933058722 * price[bar - 6]
           - 0.0670110374 * price[bar - 7]
           - 0.0190795053 * price[bar - 8]
           + 0.0259609206 * price[bar - 9]
           + 0.0502044896 * price[bar - 10]
           + 0.0477818607 * price[bar - 11]
           + 0.0249252327 * price[bar - 12]
           - 0.0047706151 * price[bar - 13]
           - 0.0272432537 * price[bar - 14]
           - 0.0338917071 * price[bar - 15]
           - 0.0244141482 * price[bar - 16]
           - 0.0055774838 * price[bar - 17]
           + 0.0128149838 * price[bar - 18]
           + 0.0226522218 * price[bar - 19]
           + 0.0208778257 * price[bar - 20]
           + 0.0100299086 * price[bar - 21]
           - 0.0036771622 * price[bar - 22]
           - 0.0136744850 * price[bar - 23]
           - 0.0160483392 * price[bar - 24]
           - 0.0108597376 * price[bar - 25]
           - 0.0016060704 * price[bar - 26]
           + 0.0069480557 * price[bar - 27]
           + 0.0110573605 * price[bar - 28]
           + 0.0095711419 * price[bar - 29]
           + 0.0040444064 * price[bar - 30]
           - 0.0023824623 * price[bar - 31]
           - 0.0067093714 * price[bar - 32]
           - 0.0072003400 * price[bar - 33]
           - 0.0047717710 * price[bar - 34]
           + 0.0005541115 * price[bar - 35]
           + 0.0007860160 * price[bar - 36]
           + 0.0130129076 * price[bar - 37]
           + 0.0040364019 * price[bar - 38];

      //---- Indicator buffer's cell initialization with FATL value
      ExtLineBuffer[bar]=FATL;
     }
//----+     
   return(rates_total);
  }
//+------------------------------------------------------------------+

Göstergeyi derledikten sonra, İstemci Terminali'nde grafik üzerinde test edilebilir:

FATL göstergesinin ortaya çıkan kodunun diğer benzer filtreleri oluşturmak için bir şablon olarak kullanılabilmesi doğaldır. Ama şimdi sorun çok daha kolay. Kodumuzda filtre hesaplama formülünü değiştirmek, FATL sözcüğünü DIGFILTER ile değiştirmek ve (şimdi) DIGFILTERPeriod değişkenini dijital filtrenin gerekli boyutuyla başlatmak yeterlidir.

İstemci Terminali'nde dijital filtreler oluşturmak için ortak çözüm

Az önce ele aldığımız gösterge, genel dijital sinyal filtreleme sorununu çözmenin tek bir varyantıdır. Tek bir gösterge kullanarak herhangi bir dijital filtre oluşturmaya olanak tanıyan ortak bir çözümü temsil eden bir göstergeye sahip olmak güzel olurdu. Bu sorun uzun zaman önce MetaTrader 4 İstemci Terminali için Sergei Ilyuhin tarafından DF.dll modülü kullanılarak çözüldü. Dolayısıyla, MetaTrader 5 İstemci Terminali'ndeki sorunumuzu çözmek için onu kullanmak kolay olacaktır. Bu modülde DigitalFilter() işlevi tanıtılmıştır:

DigitalFilter(int FType, int P1, int D1, int A1, int P2, int D2, int A2, double Ripple, int Delay, double& array[]); 

Bu, dijital filtre katsayılarını array[] dizisi olarak almanızı sağlar. İşlev, dijital filtre katsayılarını referans (bu dizide bu değişken türünün bildirilmesinden sonraki '&' işareti) kullanarak 1500 boyutunda bu diziye yazar. İşlev, on giriş parametresinin değerlerini alır ve dijital filtrenin boyutunu döndürür. Dolayısıyla, bu, evrensel dijital filtreyi oluşturmak için oldukça yeterlidir. Tüm sorun, mevcut göstergede DLL içe aktarımını genel düzeyde düzenlemeye, gösterge başlatma kod bloğundaki katsayı dizisini elde etmeye ve OnCalculate() içinde evrensel filtre hesaplamasını çalıştıran bu katsayılar temeline indirgenmektedir. DigitalFilter() işlevinin giriş değişkenleri, göstergenin giriş değişkenlerine yerleştirilmelidir. Bunu şimdi yapacağız.

DF.dll dosyasını içe aktarmak herhangi bir zorluk yaratmaz. Bu, yalnızca üç kod satırıdır:

//---- DLL import
#import "DF.dll"
int DigitalFilter(int FType, int P1, int D1, int A1, int P2, int D2, int A2, double Ripple, int Delay, double& array[]); 
#import

Bundan sonra, DigitalFilter() işlevinin tüm harici değişkenlerini göstergenin giriş değişkenleri haline getireceğiz:

//---- Input parameters of indicator
input FType_ FType=LPF;     //Filter Type
                            //0 - Low-Pass Filter (FATL / SATL / KGLP), 1 - High-Pass Filter (KGHP), 
                            //2 - Band-Pass Filter (RBCI / KGBP), 3 - Band-Stop Filter (KGBS)
input int    P1 = 28;       //Cut-off period 1, in bars
input int    D1 = 19;       //Transient process cut-off period 1, in bars
input int    A1 = 40;       //Fading in delay band 1, in dB
input int    P2 = 0;        //Cut-off period 2, in bars
input int    D2 = 0;        //Transient process cut-off period 2, in bars
input int    A2 = 0;        //Fading in delay band 2, in dB
input int    Delay=0;       //Delay, in bars
input double Ripple=0.08;   //Beats in bandwidth, in dB
input int    FILTERShift=0; //Moving Average horizontal shift, in bars

Genel düzeyde FILTERPeriod değişkenini başlatma olmadan bildireceğiz:

//---- Declaring and initializing a variable to store the number of calculated bars
int FILTERPeriod;

Genel düzeyde, filtre katsayılarını depolamak için dinamik bir dizi bildireceğiz:

//---- Declaration of dynamic array, which will be 
//     used later as indicator buffer
double FILTERTable[];

Şimdi OnInit() işlevinin bloğuna geçelim. DigitalFilter() işlevinin parametresi olarak FILTERTable[] dizisini kullanmak pek mantıklı değil. Bunun için bunu, 1500 öğeye kadar boyutlandıracağız; OnCalculate() işlevi bloğunda bunların yalnızca 100 - 200'ü kullanılacaktır. Böyle bir durumda yerel olarak bildirilen Array[1500] dizisini OnInit() işlevi içinde kullanmak daha iyi olacaktır. Bu diziden gerekli miktarda veri FILTERTable[] dizisine yazılacaktır. OnInit() işlevinden çıktıktan sonra, büyük Array[] dizisi yok edilecek ve gerekli veriler FILTERTable[] dizisinde kalacaktır; bu, FILTERPeriod dijital filtresinin uzunluğuna eşit bir boyuta sahip olacaktır. Bu amaç için kullanılan kodun varyantı şu şekildedir:

//---- Calculation of digital filter coefficients and determining the size of FILTERTable[] buffer
   double Array[1500];
   FILTERPeriod=DigitalFilter(FType,P1,D1,A1,P2,D2,A2,Ripple,Delay,Array);
//----  Changing the size of FILTERTable[] buffer for required number of digital filter coefficients
   if(FILTERPeriod<=0)
     {
      Print("Input parameters are incorrect. Indicator can't operate!");
      return;
     }
//---- Copying data from temporary array with size of 1500 to the main array with size of FILTERPeriod
   ArrayCopy(FILTERTable,Array,0,0,FILTERPeriod);

OnCalculate() işlevinde filtre hesaplama kodu oldukça basittir:

      //---- Digital filter calculation formula
      FILTER=0.0;
      for(iii = 0; iii<FILTERPeriod; iii++)
         FILTER+= FILTERTable[iii] * price[bar - iii];

Bu gösterge kodunun son sürümü DFilter_en.mq5 dosyasında sunulmaktadır. Bu göstergenin arayüzü biraz geliştirilebilir. Gerçek şu ki göstergenin giriş değişkeni 0 ila 3 arasında değerler alır.

input int FType = 0; //Тип фильтра
                     //0 - ФНЧ (FATL/SATL/KGLP), 1 - ФВЧ (KGHP), 2 - полосовой (RBCI/KGBP), 3 - режекторный (KGBS)

Bu değerler sayısal formda değil, filtrenin adları olarak çok daha kolay algılanır: 0 - Düşük Geçiren Filtre (FATL/SATL/KGLP), 1 - Yüksek Geçiren Filtre (KGHP), 2 - Bant Geçiren Filtre (RBCI/KGBP), 3 - Bant Durduran Filtre (KGBS). MQL5'te böyle bir durum için, numaralandırmalar olarak adlandırılan özel türde değişkenler vardır. Bizim durumumuzda, göstergenin giriş parametrelerinden önce numaralandırmayı bildirmeli ve başlatmalıyız:

//---- Declaration and initialization of digital filters types
enum FType_ //Filter Type
  {
   LPF, //Low-Pass Filter (FATL/SATL/KGLP)
   HPF, //High-Pass Filter (KGHP)
   BPF, //Band-Pass Filter (RBCI/KGBP)
   BSF, //Band-Stop Filter (KGBS)
  };

Bundan sonra, gösterge harici parametre bildiriminde kullanılan değişkenin türünü değiştirmeliyiz:

input FType_ FType = LPF; //Filter Type

Sonuç olarak, gösterge iletişim kutusunda bu parametrenin değerlerinin seçilmesi aşağıdaki gibi görünür:

Numaralandırma bildiriminde olduğu gibi, adlandırılmış sabitleri tek satırlık açıklamalar takip eder; daha sonra bunlar giriş parametreleri olarak seçilmelidir. Artık evrensel dijital filtre kaynak kodunun son sürümüne sahibiz:

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2010, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
/*
 * <<< DIGITAL FILTERS FOR METATRADER 5 >>> *
 *
 * DF.dll file should be placed in "\MetaTrader 5\MQL5\Libraries\" folder.
 * DF.dll requires three additional DLLs, containing a block of mathematical 
 * processing - bdsp.dll, lapack.dll, mkl_support.dll.
 * These DLLs must be installed in "C:\Windows\System32\" folder for 
 * Windows 32-bit operating systems or in "C:\Windows\SysWOW64\" folder 
 * for Windows 64-bit operating systems.
 *
 * Before using, make sure that:
 * 
 * 1. "Allow DLL import" option is enabled in Client Terminal settings 
 *    (Tools->Options->Expert Advisors tab).
 * 2. In "C:\Windows\System32\" or in "C:\Windows\SysWOW64\" folders the
 *    Bdsp.dll, lapack.dll and mkl_support.dll auxiliary math libraries are present.
 *
 * Description of input parameters:
 * 
 * Ftype  - Filter Type: 0 - Low-Pass Filter (FATL/SATL/KGLP), 1 - High-Pass Filter (KGHP),
 *          2 - Band-Pass Filter (RBCI / KGBP), 3 - Band-Stop Filter (KGBS)
 * P1     - Cut-off period P1, in bars
 * D1     - Transient process cut-off period D1, in bars
 * A1     - Fading in delay band A1, in dB
 * P2     - Cut-off period P2, in bars
 * D2     - Transient process cut-off period D2, in bars
 * A2     - Fading in delay band A2, in dB
 * Ripple - Beats in bandwidth, in dB
 * Delay  - Delay, in bars
 *
 * For Low-Pass Filter and HPF the values of P2, D2, A2 are ignored
 *
 * Conditions:
 * Low-Pass Filter:                       P1>D1
 * High-Pass Filter:                      P1<D1
 * Band-Pass Filter and Band-Stop Filter: D2>P2>P1>D1
 */
//+------------------------------------------------------------------+
//|      Digital Low Pass (FATL/SATL, KGLP) Filter    DFilter_en.mq5 | 
//|                    Digital Filter: Copyright (c) Sergey Ilyukhin |
//|                           Moscow, qpo@mail.ru  http://fx.qrz.ru/ |
//|                              MQL5 CODE: 2010,   Nikolay Kositsin |
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+
//---- Indicator's author
#property copyright "2005, Sergey Ilyukhin, Moscow"
//---- Author's web-site link
#property link      "http://fx.qrz.ru/"
//---- Indicator version number
#property version   "1.00"
//---- Drawing the indicator in main window
#property indicator_chart_window
//---- One buffer is used for calculating and drawing the indicator
#property indicator_buffers 1
//---- Only one graphical plotting is used
#property indicator_plots   1
//---- Drawing the indicator as line
#property indicator_type1   DRAW_LINE
//---- Blue is used as indicator's line color
#property indicator_color1  DarkViolet
//---- Indicator line is continuous curve
#property indicator_style1  STYLE_SOLID
//---- Indicator line thickness is equal to 2
#property indicator_width1  2
//---- Displaying indicator's label
#property indicator_label1  "DFilter"
//---- Declaration and initialization of digital filters types
enum FType_ //Filter Type
  {
   LPF, //Low-Pass Filter (FATL/SATL/KGLP)
   HPF, //High-Pass Filter (KGHP)
   BPF, //Band-Pass Filter (RBCI/KGBP)
   BSF, //Band-Stop Filter (KGBS)
  };

//---- Input parameters of indicator
input FType_ FType=LPF;     //Filter Type
                            //0 - Low-Pass Filter (FATL / SATL / KGLP), 1 - High-Pass Filter (KGHP), 
                            //2 - Band-Pass Filter (RBCI / KGBP), 3 - Band-Stop Filter (KGBS)
input int    P1 = 28;       //Cut-off period 1, in bars
input int    D1 = 19;       //Transient process cut-off period 1, in bars
input int    A1 = 40;       //Fading in delay band 1, in dB
input int    P2 = 0;        //Cut-off period 2, in bars
input int    D2 = 0;        //Transient process cut-off period 2, in bars
input int    A2 = 0;        //Fading in delay band 2, in dB
input int    Delay=0;       //Delay, in bars
input double Ripple=0.08;   //Beats in bandwidth, in dB
input int    FILTERShift=0; //Moving Average horizontal shift, in bars

//---- DLL Import
#import "DF.dll"
int DigitalFilter(int FType,int P1,int D1,int A1,int P2,int D2,int A2,double Ripple,int Delay,double &array[]);
#import

//---- Declaring and initializing a variable to store the number of calculated bars
int FILTERPeriod;

//---- Declaration of dynamic array, which will be 
//     used later as indicator buffer
double ExtLineBuffer[];

//---- Declaring and initializing an array for the digital filter coefficients
double FILTERTable[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+  
void OnInit()
  {
//----+
//---- Transformation of ExtLineBuffer dynamic array into indicator buffer
   SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
//---- Horizontal shift of indicator by FILTERShift
   PlotIndexSetInteger(0,PLOT_SHIFT,FILTERShift);
//---- Setting the position from which the drawing of indicator will start
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,FILTERPeriod);
//---- Variable initialization for indicator's short name
   string shortname;
   StringConcatenate(shortname,"FILTER(",FILTERShift,")");
//---- Creating label to display in Data Window
   PlotIndexSetString(0,PLOT_LABEL,shortname);
//---- Creating name to display in a separate window and in tool-tip
   IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//---- Defining accuracy of displaying indicator's values
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- Prohibition of empty values plotting
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---- Calculation of digital filter coefficients and determining the size of FILTERTable[] buffer
   double Array[1500];
   FILTERPeriod=DigitalFilter(FType,P1,D1,A1,P2,D2,A2,Ripple,Delay,Array);
//----  Changing the size of FILTERTable[] buffer for required number of digital filter coefficients
   if(FILTERPeriod<=0)
     {
      Print("Input parameters are incorrect. Indicator can't operate!");
      return;
     }
//---- Copying data from temporary array with size of 1500 to the main array with size of FILTERPeriod
   ArrayCopy(FILTERTable,Array,0,0,FILTERPeriod);
//----+
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,     // amount of history in bars at the current tick
                const int prev_calculated, // amount of history in bars at the previous tick
                const int begin,           // beginning number of reliable count of bars
                const double &price[]      // price array for indicator calculation
                )
  {
//----+   
//---- Check if the number of bars is sufficient for calculation
   if(rates_total<FILTERPeriod-1+begin)
      return(0);

//---- Declaring local variables
   int first,bar,iii;
   double Sum,FILTER;

//---- Calculating the 'first' starting number for the bars recalculation loop
   if(prev_calculated==0)         // Checking the first start of the indicator calculation
     {
      first=FILTERPeriod-1+begin; // Starting number for calculation of all bars
      //---- Increasing the start of data position by 'begin' bars, 
      //     because the calculations are based on data of another indicator
      if(begin>0)
         PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin+FILTERPeriod);
     }
   else first=prev_calculated-1;  // Starting number for calculation of new bars

//---- Main loop of indicator calculation
   for(bar=first; bar<rates_total; bar++)
     {
      //---- Digital filter calculation formula
      FILTER=0.0;
      for(iii = 0; iii<FILTERPeriod; iii++)
         FILTER+= FILTERTable[iii] * price[bar - iii];

      //---- Indicator buffer's cell initialization with FILTER value
      ExtLineBuffer[bar]=FILTER;
     }
//----+     
   return(rates_total);
  }
//+------------------------------------------------------------------+
Yalnızca İstemci Terminali aracılığıyla bu tür evrensel dijital filtrenin MQL5 uygulaması, FinWare şirketinden herhangi bir dijital filtreye olan ihtiyacı tamamen ortadan kaldırır. Bu, bu göstergelerin kullanılmasında yeni olanaklar sunan önemli bir kolaylıktır.

Sonuç

Kod ile yapılan tüm bu işlemlerden sonra birçok ayrıntı elde edildi. Ancak, bu sürecin bu ayrıntılarına daha yakından bakıldığında, en basit şeylerin analiziyle başlayıp basitten karmaşığa anlamlı ve planlı bir geçiş yapmaya devam edersek, her şey mükemmel bir şekilde mantıklı ve anlaşılır çalışır.

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

Ekli dosyalar |
dll.rar (1302.47 KB)
sma__en.mq5 (3.56 KB)
sma_1_en.mq5 (4.51 KB)
fatl_en.mq5 (6.08 KB)
dfilter_0_en.mq5 (8.17 KB)
dfilter_en.mq5 (8.42 KB)
MQL5: MetaTrader 5'te Emtia Vadeli İşlemler Ticaret Komisyonu (CFTC) Raporlarının Analizi ve İşlenmesi MQL5: MetaTrader 5'te Emtia Vadeli İşlemler Ticaret Komisyonu (CFTC) Raporlarının Analizi ve İşlenmesi
Bu makalemizde, CFTC rapor analizi için bir araç geliştireceğiz. Şu sorunu çözeceğiz: CFTC rapor verilerinin, Komisyon tarafından sağlanan veri dosyalarından bir ara işleme ve dönüştürme olmadan doğrudan kullanılmasına olanak tanıyan bir gösterge geliştirmek. Ayrıca, bu, farklı amaçlar için kullanılabilir: Verileri bir gösterge olarak çizmek, diğer göstergelerdeki verilerle devam etmek, otomatik analiz için script dosyalarında, alım satım stratejilerinde kullanılmak üzere Expert Advisor'larda.
WCF Hizmetlerini Kullanarak МetaTrader 5'ten .NET Uygulamalarına Fiyat Tekliflerini Dışa Aktarma WCF Hizmetlerini Kullanarak МetaTrader 5'ten .NET Uygulamalarına Fiyat Tekliflerini Dışa Aktarma
MetaTrader 5'ten kendi uygulamanıza fiyat tekliflerinin dışa aktarılmasını düzenlemek ister misiniz? MQL5-DLL birleşimi, bu tür çözümler oluşturmanıza olanak tanır! Bu makalede size fiyat tekliflerini MetaTrader 5'ten .NET'te yazılmış uygulamalara dışa aktarmanın yollarından biri gösterilecektir. Benim için bu platformu kullanarak fiyat tekliflerinin dışa aktarımını uygulamak daha ilginç, mantıklı ve kolaydı. Ne yazık ki, sürüm 5 hala .NET'i desteklemiyor; bu nedenle eski günlerde olduğu gibi .NET destekli win32 dll'yi ara katman olarak kullanacağız.
MQL5'te olay işleme: MA dönemini anında değiştirme MQL5'te olay işleme: MA dönemini anında değiştirme
13. dönemli basit MA (Hareketli Ortalama) göstergesinin bir grafiğe uygulandığını varsayalım. Ve dönemi 20 olarak değiştirmek istiyoruz, ancak gösterge özellikleri iletişim kutusuna gidip 13 ila 20 sayısını düzenlemek istemiyoruz: Fare ve klavyeyi kullanarak bu sıkıcı işlemleri yapmaktan sıkıldık. Ve özellikle gösterge kodunu açıp değiştirmek istemiyoruz. Tüm bunları tek bir düğmeye basarak yapmak istiyoruz; sayısal tuş takımının yanındaki "yukarı oklara" basarak. Bu makalede bunun nasıl yapılacağını anlatacağım.
MQL5'te Gösterge Emisyonlarının Çizimi MQL5'te Gösterge Emisyonlarının Çizimi
Bu makalede, piyasa araştırmasına yeni bir yaklaşım olan göstergelerin emisyonunu ele alacağız. Emisyon hesaplaması, farklı göstergelerin kesişimine dayanmaktadır: Her tick'ten sonra farklı renk ve şekillerde daha fazla nokta belirir. Bulutsular, bulutlar, parçalar, çizgiler, kavisler vb. gibi çok sayıda küme oluştururlar. Bu şekiller, piyasa fiyatlarının hareketini etkileyen görünmez kavisleri ve güçleri tespit etmeye yardımcı olur.