English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Yeni Raylara Adım Atın: MQL5'te Özel Göstergeler

Yeni Raylara Adım Atın: MQL5'te Özel Göstergeler

MetaTrader 5Örnekler | 9 Aralık 2021, 10:03
215 0
TheXpert
TheXpert

Giriş

Sonunda yeni alım satım terminali MetaTrader 5'i deneme fırsatımız oldu. Hiç şüphesiz, dikkat çekicidir ve selefine göre birçok yeni özelliğe sahiptir. Bu platformun diğerleri arasında önemli avantajları şunlardır:

  • Temel olarak değiştirilmiş dil, şimdi nesne yönelimli programlamayı kullanmaya olanak tanırken, yine de yapısal programlamanın zengin avantajlarını kullanmaya izin vermektedir.
  • Artık MetaTrader 4'ten çok daha hızlı olan kod yürütme hızı.
  • Gerekli bilgilerin görüntülenmesi için olasılıkların önemli ölçüde artması.

Yeni terminalin ve dilin tüm yeni olanaklarını ve özelliklerini listelemeyeceğim. Bunlar sayısızdır ve bazı yenilikler ayrı bir makalede tartışılmaya değerdir. Ayrıca burada nesne yönelimli programlama ile yazılmış bir kod yoktur, geliştiriciler için ek avantajlar olarak bir bağlamda basitçe bahsedilemeyecek kadar ciddi bir konudur.

Bu makalede göstergeleri, yapılarını, çizimlerini, türlerini ve programlama ayrıntılarını MQL4 ile karşılaştırmalı olarak ele alacağız.

Bu makalede karmaşık bir şey yoktur, ayrıca burada dikkate alınan herhangi bir şey ekli dosyalar kullanılarak doğrudan terminalde kontrol edilebilir.

Bu makalenin hem yeni başlayanlar hem de deneyimli geliştiriciler için yararlı olacağını umuyorum, belki bazıları burada yeni bir şeyler bulacaktır.

 

Genel Yapı

MQL4'e kıyasla göstergenin genel yapısı değişmemiştir.

Daha önce olduğu gibi, başlatma için, veri işleme için ve göstergenin ayrıntılandırılması için üç fonksiyon vardır.

Daha önce olduğu gibi, birçok gösterge parametresi, özellikler (#property anahtar sözcüğü) tarafından tanımlanabilir. Çoğu, göstergeler için özel olarak tasarlanmıştır. Özellikler ve giriş parametreleri daha önce olduğu gibi global bir bağlamda tanımlanır.

Örnek olarak, RSI göstergesi için özel renklendirme uygulamasını ele alalım. İşte kısaltılmış versiyon, tam versiyon Color_RSI.mq5 dosyasında bulunabilir.

Kodun bölümlerini ele alalım.

//--- group of data properties
#property copyright "TheXpert"
#property link      "theforexpert@gmail.com"
#property version   "1.00"
//--- description of the indicator should not exceed 511 symbols in total
//--- including newline symbols
#property description "      "
#property description "Demonstration of the indicator creation"
#property description "by the example of RSI coloring"

Yukarıda belirtilen özellikler, gösterge bilgi panelinde (özelliklerin "Common" sekmesi) görüntülenir. Bu, aşağıdaki gibidir:

//--- indicator properties
#property indicator_separate_window // the indicator will be displayed in a separate subwindow
#property indicator_buffers 2       // number of used buffers
#property indicator_plots   1       // number of displayed buffers
//--- plot 1
#property indicator_color1 clrDarkSalmon, clrDeepSkyBlue // use 2 colors
#property indicator_type1  DRAW_COLOR_LINE               // and the special color display type

Bu özellikler gösterge özellikleridir. Diğer özelliklerin açıklaması yardımda bulunabilir.

//---- buffers
double Values[];                 // buffer of values
double ValuesPainting[];         // buffer of color indices
//--- indicator input parameters
input string             _1           = "RSI parameters";
input int                RSIPeriod    = 5;
input int                SmoothPeriod = 5;
input ENUM_APPLIED_PRICE AppliedPrice = PRICE_CLOSE;
input string             _2           = "Color settings";
input color              Down         = clrDarkSalmon;
input color              Up           = clrDeepSkyBlue;
//--- variable for storing the indicator handle
int RSIHandle;

Gösterge giriş parametreleri ve global değişkenler buradadır (istemci terminalinin global değişkenleri ile karıştırmayın). Gösterge giriş parametreleri, giriş tanımlayıcısı ile belirtilir.

Artık giriş parametresi için numaralandırma ayarlamak mümkündür, bazen yanlış parametre seçiminden kaçınmak yararlıdır.

Örneğin, AppliedPrice parametresi, olası geçerli değerlerle birlikte bir açılır listede görüntülenecektir.

Böylece, tanımlı kullanıcı da dahil olmak üzere tüm numaralandırmalar aynı açılır listede görüntülenecektir. Örneğin, aşağıdaki parametre

//...
enum DayOfWeek
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
};

input DayOfWeek Day;

//...

aşağıdaki gibi görüntülenecektir:

int OnInit()
  {
//--- bind indicator buffers
//--- Values serves as a display buffer
   SetIndexBuffer(0,Values,INDICATOR_DATA);
//--- ValuesPainting serves as the buffer for storing colors
   SetIndexBuffer(1,ValuesPainting,INDICATOR_COLOR_INDEX);
//--- Set the start of drawing Values buffer
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,RSIPeriod);
//--- Set the indicator name
   IndicatorSetString(INDICATOR_SHORTNAME,"Color RSI("+string(RSIPeriod)+")");
//--- Set an empty value for plots
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//--- Set buffer colors
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Down);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Up);
//--- Receive indicator handles
   RSIHandle=iRSI(NULL,0,RSIPeriod,AppliedPrice);
//--- Set the sequence of buffer indexation
   ArraySetAsSeries(Values,true);
   ArraySetAsSeries(ValuesPainting,true);
//--- successful execution
   return(0);
  }

OnInit gösterge başlatma fonksiyonudur. Burada gösterge tamponlarını ve özelliklerini yapılandırıyoruz ve özelliklerde tanımlanamayan veya dinamik olarak ayarlanması gereken gösterge değişkenlerini tanımlıyoruz. Ayrıca, göstergeler için gerekli olan tanıtıcı atamaları da dahil olmak üzere bir başlangıç veri başlatması vardır.

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[])
  {
//--- number of bars for calculation
   int toCount=(int)MathMin(rates_total,rates_total-prev_calculated+1);
//--- try to copy iRSI indicator data
   if(CopyBuffer(RSIHandle,0,0,toCount,Values)==-1)
     {
      Print("Data copy error, №",GetLastError());
      //--- return command for recalculation of the indicator values
      return(0);
     }
//--- coloring. Yer, now it has become that easy
   for(int i=toCount-2;i>=0;--i)
     {
      //--- coloring the first line
      if(Values[i+1]!=EMPTY_VALUE && Values[i]>Values[i+1])
         ValuesPainting[i]=1;
      else
         ValuesPainting[i]=0;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

OnCalculate veri hesaplama fonksiyonudur. Bu fonksiyon iki tür olabilir. Standart formu buradadır. Ayrıntılar aşağıdadır.

Fonksiyon:

//--- this function usage in not obligatory
/*
void OnDeinit()
{

}
*/

OnDeinit gösterge sıfırlama fonksiyonudur. Çoğu zaman, örneğin dosya tanıtıcıları gibi kaynakları serbest bırakmak gerekir. Diğer durumlarda bu fonksiyon gerekli değildir.

 

İki Gösterge Kavramı

Birincisi standart, MQL4'te alıştığımızla aynı, ancak biraz değiştirilmiş bir biçimdedir. OnCalculate fonksiyonu, Başlat fonksiyonu yerine kullanılır.

Standart form için bu, aşağıdaki gibi görünür:

int OnCalculate(const int rates_total,      // Arrays size
                const int prev_calculated,  // Bars processed on the previous call
                const datetime& time[],     // Data for the current chart and timeframe...
                const double& open[],
                const double& high[],       
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
{
   return rates_total;
}

Veri kopyalamaya yönelik kod miktarını azaltmak için, grafik verileri doğrudan fonksiyonun parametrelerine diziler olarak iletilir. Ayrıca, mevcut çubukların sayısı fonksiyonun birinci parametresi olarak, son çağrıdan sonra işlenen çubuk sayısı veya 0 (sıfır) ikinci parametre olarak iletilir.

0 (sıfır) değeri, birinci gösterge çağrısında ve ayrıca yeni veya eksik veriler yüklenirken iletilebilir. Bu parametre, birçok geliştirici için elverişsiz olan IndicatorCounted() için bir ikamedir (alternatif veya eşdeğeri - bu, size kalmış).

İkinci kavram, MQL4'ün fonksiyonları gibi i<…>OnArray fonksiyonunun değiştirilmesi ve genişletilmesidir. Terminal örneklerinde böyle bir türün göstergesi vardır - Özel Hareketli Ortalama. Bu tür göstergeler, özel göstergeler de dahil olmak üzere kullanıcının seçimine bağlı olarak veri işlemeye yöneliktir.

Bu tür göstergeler için veri işleme fonksiyonu aşağıdaki gibi görünür:

int OnCalculate (const int rates_total,      // the size of the price[] array
                 const int prev_calculated,  // bars calculated in the previous call
                 const int begin,            // where notional data start from
                 const double& price[]       // data array for calculation
                 )
  {
   return rates_total;
  }

Fonksiyonun son parametresi, işleme için kullanıcı tarafından seçilen verilerdir. Çok sayıda tampona sahip bir gösterge uygulamak istiyorsanız birinci gösterge tamponu veri işleme için iletilecektir.

Birinci Göstergenin Verileri göstergenin, grafiğin seçilen penceresine ilk eklenen göstergeye uygulanacağı anlamına gelir.

Önceki Göstergenin Verileri bu göstergenin grafiğin seçilen penceresine en son eklenen göstergeye uygulanacağı anlamına gelir.

Bu göstergeler tüm yığınları birleştirmek için kullanılabilir. Örneğin , Özel Hareketli Ortalama göstergesini kullanarak birinci göstergeyi gerekli verilere, ikinciyi birinciye ve üçüncüyü ikinciye geçirerek üçlü düzleme elde etmek mümkündür.

Bu özel kavramı uygulayan birçok standart gösterge vardır. Bu nedenle, applied_price_or_handle fonksiyon parametresi istemini gördüğünüzde:

bu, göstergenin, kullanıcı verileri üzerinde hesaplanabilecek şekilde uygulandığını gösterir - bu verilerin tanıtıcısı applied_price_or_handle parametresi olarak iletilmelidir.

Aynı şekilde, veri işlemeyi doğrudan gösterge kodunda düzenlemek mümkündür:

  {
   //...
   RSIHandle = iRSI(NULL, 0, RSIPeriod, AppliedPrice);
   SmoothHandle = iMA(NULL, 0, SmoothPeriod, 0, MODE_EMA, RSIHandle);
   //...
  }

Bu kavramın başka bir yeni uygulaması daha var - evrensel hizmet göstergeleri yazma becerisi. Bu tür bir göstergenin bir örneği Direction_Brush.mq5 dosyasına eklenmiştir.

Sonuçlar üst grafikte sunulmuştur. Bu durumda yön renklendirmesi bağımsız bir varlık olarak ayrılır ve diğer göstergede uygulanır.

Yalnızca göstergenin sıfır tamponu için geçerli oldukları için evrensellikleri sınırlıdır. Yine de, bu tür göstergelerin yararlı olabileceğini düşünüyorum.

Diğer taraftan, özel bir gösterge yazdığınızda, bunu dikkate almalısınız, çünkü sıfır tamponunda ana bilgi işleme, çok fonksiyonlu bir makinenin tek bir göstergede uygulanmasından kaçınmaya izin verecektir. Diğer eylemlerin çoğu harici hizmet göstergelerinde yapılabilir ve yürütülebilir. Tek yapmanız gereken gerekli fonksiyona sahip servis göstergelerini özelleştirmenize eklemektir.

Uygulama aralığı ilk bakışta göründüğü kadar dar değildir:

  • ton görselleştirmesi dahil olmak üzere gösterge özelliklerinin (üst kısımlar, yönler, seviyeler, segmentler vb.) renklendirilmesi;
  • farklı koşullarda farklı sinyaller;
  • istatistiklerin toplanması ve görüntülenmesi - örneğin, veri dağıtımı;
  • bir tampon için hesaplanabilen evrensel göstergelerin yapımı - örneğin, hareketli ortalamalar, zikzak.

Yukarıda bahsedilen özellikler, kavram uygulamasının kapsamlı listesi değildir. Daha sonra başka birçok etkili uygulamanın bulunacağını düşünüyorum.

 

Verilere Erişim

MQL5'te veri erişim ilkeleri değişti. Şimdi iş doğrudan dizilerde gerçekleşir ve sonuç olarak hesaplama hızı önemli ölçüde artmıştır. Artık bir dizi oluşturmak ve ve her değer için iCustom fonksiyonunu çağırmak gerekli değildir. Bunun yerine, bir fonksiyonu çağırarak gerekli veri sayısını elde etmek ve daha sonra belirtilen yerel bir dizide kopyalanan istenen verileri doğrudan kullanmak mümkündür.

Veri kopyalama, CopyBuffer sistem fonksiyonu kullanılarak gerçekleştirilir. Fonksiyon açıklamasını yardımda bulabilirsiniz.

Gösterge ve statik (önceden tanımlanmış bir boyuta sahip) diziler için kopyalanacak maksimum veri sayısı, dizinin boyutuna göre belirlenir. Dinamik dizinin boyutu kopyalanan veri sayısı boyutunu aşıyorsa değiştirilebilir.

Ayrıca, geçmiş verilere erişmek için özel fonksiyonlar vardır:

Fonksiyon Açıklama
CopyBuffer Belirtilen bir göstergenin belirtilen bir tamponundan gereken miktarda veri alır.
CopyRates Belirtilen sembol-periyot için MqlRates yapısının geçmiş verilerini rates_array dizisine belirtilen miktarda kopyalar.
CopyTime Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş çubuk açılış zamanı verilerini time_array dizisine belirtilen miktarda kopyalar.
CopyOpen Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş çubuk açılış fiyatı verilerini open_array dizisine belirtilen miktarda kopyalar.
CopyHigh Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş en yüksek çubuk fiyatı verilerini high_array dizisine belirtilen miktarda kopyalar.
CopyLow Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş minimum çubuk fiyatı verilerini low_array dizisine belirtilen miktarda kopyalar.
CopyClose Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş çubuk kapanış fiyatı verilerini close_array dizisine belirtilen miktarda kopyalar.
CopyTickVolume Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş tik hacmi verilerini belirtilen miktarda volume_array dizisine kopyalar.
CopyRealVolume Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş alım-satım hacmi verilerini belirtilen miktarda volume_array dizisine kopyalar.
CopySpread Bu fonksiyon, seçilen sembol-periyot çifti için, geçmiş spread değerleri verilerini spread_array dizisine belirtilen miktarda kopyalar.

Ayrıntılar yardımda bulunabilir.

Bu veriler, göstergenin yalnızca bir biçiminde iletilir, diğeri için kendilerininkini edinmeleri gerekir.

Geçmiş veri dizisinin türünün double olmaması gerçeği nedeniyle, depolama için sadece dinamik gösterge dışı tamponların kullanılması tavsiye edilir.

Ayrıca belgelenmemiş bir ayrıntı daha vardır - kopyalanan veri sayısı 0'a (sıfır) eşitse, CopyBuffer fonksiyonu №4003 kodlu bir hata oluşturur, bu nedenle kopyalanacak veri sayısı 1 (bir) öğeden az olmamalıdır.

 

Gösterge Tamponları

Tampon sayısı sınırlı değildir.

Şimdi küme göstergesinin oluşturulması üzerinde çalışırken bilgileri nasıl doğru bir şekilde yerleştireceğinizi, ara hesaplamaları nasıl verimli bir şekilde yapacağınızı düşünmenize gerek yoktur.

Ancak tampon depolamasının bellek gerektirdiğini unutmamalıyız. Bu nedenle, yaklaşık 1.000.000 çubukluk bir terminal geçmişi derinliği belirtirseniz ve "kalın" küme göstergesini dakika grafiğine eklerseniz, terminal Gb bellek tükettiğinde şaşırmayın.

Tamponun özü de bazı değişikliklere uğramıştır. Kullanılan tamponların miktarı in özelliğinde belirtilir.

#property indicator_buffers 2       // buffers used

Bu değer, toplam tampon sayısına karşılık gelmelidir.

Görüntülenen tampon sayısı, özellik tarafından tanımlanır:

#property indicator_plots 1         // buffers displeyed

Bazı detaylar şuradadır. Çizim stillerinin çoğu, çizim için yalnızca bir INDICATOR_DATA tamponuna ihtiyaç duyar. Ancak, çizim için birkaç gösterge tamponu gerektiren bazı stiller vardır.

Aşağıdaki çizim stillerini kastediyoruz:

  • DRAW_HISTOGRAM2 - iki gösterge tamponu gerektirir (HistogramSample.mq5)

  • DRAW_FILLING - iki gösterge tamponu gerektirir (CrossMa.mq5)

  • DRAW_CANDLES - dört gösterge tamponu gerektirir (CandleSample.mq5)

  • DRAW_BARS - dört gösterge tamponu gerektirir (BarsSample.mq5)

DRAW_FILLING stili haricinde (bu renklendirilemez) yukarıdaki tüm türler, renkli analoglara sahiptir.

Tüm gösterge tamponları artık 3 türe ayrılmıştır:

  • INDICATOR_DATA - verileri grafikte görüntülenen tamponlar. Bu tamponlar, çizim yapmak ve iCustom ile çalışmak için tasarlanmıştır. Önce kayıt olmaları gerekir. Rastgele sıralanması durumunda (yanlış), kod başarıyla derlenecek ve bir grafiğe uygulandığında çizilecek, ancak büyük olasılıkla yanlış çizilecektir.

  • INDICATOR_COLOR_INDEX - bir renk depolaması için tamponlar. Bunlar, özel renk türlerinden birine (#property indicator_typeN) sahip olan INDICATOR_DATA türündeki renk tampon dizinlerini depolamak için gereklidirler. Bu tür bir tampon (renk tamponunu adlandırıyoruz), bunu kullanan ana tampondan hemen sonra kaydedilmelidir.

  • INDICATOR_CALCULATIONS - bu tür tamponlar, yardımcı hesaplamaların sonuçlarını depolamak için tasarlanmıştır. Bunlar grafikte gösterilmezler.

int OnInit()
{
   // ...
   SetIndexBuffer(0, V2, INDICATOR_DATA);
   SetIndexBuffer(1, V2C,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, V4, INDICATOR_DATA);
   SetIndexBuffer(3, V4C,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(4, V1, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5, V3, INDICATOR_CALCULATIONS);

   // ...
   return 0;
}

iCustom aracılığıyla göstergelere atıfta bulunurken de bazı özellikler vardır.

  • Çizim için tamponlar (grafikte görüntülenenler) okumak için kullanılabilir. Tampon numarası (indeks), tamponun kaydedildiği numara ile eşleşmelidir.
  • Bir renk depolaması için tamponlar okumak için kullanılabilir, ancak her zaman değil. Örneğin, yukarıdaki kodda V2C tamponu okuyabilir ve gerekli değerleri elde edebilir, ancak V4C tamponu kullanılamaz.
  • Ara hesaplamalar için tamponlar, MQL4'te olduğu gibi mevcut değildir. Harici veri tamponuna garantili erişime sahip olmak istiyorsanız bunu INDICATOR_DATA olarak bildirin.

Erişilemeyen tampona istek olması durumunda, 4806 ("İstenen veri bulunamadı") hatası oluşturulur.

Renk tamponlarını ayrıntılı olarak ele alalım.

MQL4'te her renk için ayrı bir tampon oluşturmak gerekiyordu, ancak şimdi renk stillerini kullanarak tek bir tampon için 63'e kadar renk belirtebilirsiniz. Bazı durumlarda, kullanılan tampon sayısını optimize etmeye ve böylece bellek kullanımından tasarruf etmeye olanak tanır. Ayrıca, gösterge yazmak için özellikle, ton görselleştirme kullanımında yeni olanaklar açar.

Ek olarak, bu yenilik bazı durumlarda MQL4 ile karşılaştırıldığında birkaç renk uygulamasının mantığını büyük ölçüde basitleştirir. En bariz örnek - trendlerin renklere göre ayrılmasıdır. MQL4'te çok ekonomik (doğru durumlardan) uygulama durumu için üç (3) tampon ve basit olmayan programlama gerektirmiştir.

Şimdi bu, her zamankinden daha kolaydır. İşte kod örnekleri, tam uygulama Color_RSI.mq5 dosyasında bulunabilir.

#property indicator_color1 clrDarkSalmon, clrDeepSkyBlue // use 2 colors
#property indicator_type1  DRAW_COLOR_LINE               // and the special color display type
//---- buffers
double Values[];                 // buffer of values
double ValuesPainting[];         // buffer of color indices
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- bind indicator buffers
//--- Values serves as a display buffer
   SetIndexBuffer(0,Values,INDICATOR_DATA);
//--- ValuesPainting serves as the buffer for storing colors
   SetIndexBuffer(1,ValuesPainting,INDICATOR_COLOR_INDEX);
//...
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(/*...*/)
  {
//--- number of bars for calculation
   int toCount=(int)MathMin(rates_total,rates_total-prev_calculated+1);
//--- try to copy iRSI indicator data
   if(CopyBuffer(RSIHandle,0,0,toCount,Values)==-1)
     {
      Print("Data copy error, №",GetLastError());
      //--- return command for recalculation of the indicator values
      return(0);
     }
//--- coloring. Yer, now it has become that easy
   for(int i=toCount-2;i>=0;--i)
     {
      //--- coloring the first line
      if(Values[i+1]!=EMPTY_VALUE && Values[i]>Values[i+1])
         ValuesPainting[i]=1;
      else
         ValuesPainting[i]=0;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Birkaç kod daha ve aşağıdakileri alırız:

Çizim için renk türlerini kullanırken bazı ayrıntılara dikkat etmelisiniz.

Renk tamponları için, dinamik bir renk tanımı şeması kullanılırken, maksimum renk sayısı, indicator_colorN özelliğinde tanımlanan renk sayısı ile sınırlıdır. Örneğin

#property indicator_color1 clrDarkSalmon, clrDeepSkyBlue // use 2 colors

tamponun renk şeması, dinamik olarak daha fazla sayıda renk ayarlasanız bile (PlotIndexSetInteger kullanarak) maksimum iki renk içerecektir.

Bu nedenle, gerekli sayıda renk tek satırda, özellik tanımlama satırında yazılmalıdır. Ardından renk dinamik olarak değiştirilebilir. Bulduğum en kısa renk "Kırmızıdır". Ancak, her zaman aşağıdakileri yapabilirsiniz:

Bunun yerine

#property indicator_color1  clrRed, clrRed, clrRed, clrRed, clrRed, clrRed, clrRed, clrRed, //…

şunları yazabilirsiniz:

#define C clrRed
#property indicator_color1  C, C, C, C, C, C, C, C, C, C, C, C, C, C, //…

Bir tampon için maksimum renk sayısı 63'tür. Renk sayısı maksimumdan büyük olduğunda (indicator_colorN özelliği ile tanımlanır) tampon görüntülenmeyecektir.

Maksimum renk sayısını kullanarak bir ton görselleştirme örneği aşağıdadır:

Genel olarak, çizim fırsatları önemli ölçüde arttı ve bu harikadır.

 

Diziler

Dizi verilerine indekslerle doğrudan başvuru sırasında, veri sıralama türü AsSeries özelliğinin kastedilmesi gerekir. Bu, bazı dizi türleri için tanımlanamaz.

Bu bayrak, çok boyutlu ve statik diziler için ayarlanamaz. OnCalculate fonksiyonuna iletilen dizi türleri için böyle bir bayrak ayarlamak mümkündür.

CopyBuffer fonksiyonunu kullanarak veri kopyalama, AsSeries özelliğine bağlı değildir, ancak uygulaması farklı tamponlar için farklıdır.

Gösterge tamponları için mevcut geçmişin tüm derinliğini kopyalamak gerekir. Unutulmamalıdır.

Dinamik ve statik (önceden tanımlanmış bir boyuta sahip) diziler için veri kopyalama şimdiden geçmişe doğru gerçekleştirilir.

CopyBuffer fonksiyonu, gerekli boyut için dinamik (göstergeler hariç) tamponların tampon boyutunu değiştirir.

Veri kopyalama için statik dizilerin kullanılması önerilmez.

Genel olarak, verileri nasıl kopyaladığınızı ve bunları nasıl ele aldığınızı her zaman kontrol etmenizi öneriyorum. En basit ve güvenli yol şudur:

  • geçmiş verilerinin depolanması için kullanılan tüm tamponlar için AsSeries özelliğini ayarlamak.
  • farklı tamponlar için tampon yapılarını hesaba katmak.
  • her zaman _LastError değişkeninin değerini kontrol etmek (son hata kodu).

Ayrıca, CopyBuffer fonksiyonu ve AsSeries özelliğiyle bağlantılı tüm fonksiyonlar için yardımı incelemenizi şiddetle tavsiye ederim.

 

IndicatorCounted

Artık IndicatorCounted fonksiyonunun gerekliliği ile ilgili tartışmalar. unutulacaktır, çünkü bu değer bizim tarafımızdan doğrudan önceki fonksiyon çağrısının dönüş değeri olarak tanımlanıyor.

int OnCalculate(const int rates_total,      // array size
                const int prev_calculated,  // bars processed after last call
                //...)
  {
   return rates_total;
  }

Daha sık olarak, geçerli fonksiyon çağrısının çubuk sayısını içeren rates_total değerini döndürmek yeterlidir.

Ancak, fiyat verileri son OnCalculate() çağrısından bu yana değiştiyse (örneğin, geçmiş verileri yüklendi veya geçmiş verileri boşlukları doldurulduysa), bu durumda prev_calculated giriş parametresinin değeri

istemci terminali tarafından 0 (sıfır) olarak ayarlanacaktır.

Ayrıca, OnCalculate fonksiyonu sıfır verirse, gösterge değerleri, istemci terminalinin DataWindow öğesinde gösterilmez. Bu nedenle, göstergeyi görmek ve geçmiş yükleme işlemi sırasında veya bir bağlantıdan başarısızlığı sonrasında tam yeniden hesaplamasını yapmak istiyorsanız 0 yerine 1 döndürün.

Eklenen bir diğer kullanışlı özellik ise, gösterge için kaç tane çubuk hesaplandığının belirlenmesidir. Daha büyük veriler üzerinde hesaplamalar yapan Uzman Danışmanlar (EA) için daha kullanışlıdır. Fonksiyon BarsCalculated fonksiyonudur, ayrıntıları yardımda bulunabilir.

Bu fonksiyonun başka bir yararlı uygulaması vardır. Gösterge yüklenmediyse, yüklenmesi biraz zaman alabilir - gösterge tanıtıcısının oluşturulması ile hesaplamalar için kullanılması arasındaki süre.

Bu süre, başlatma ve ilk ön hesaplama için gereklidir. Hesaplama hızına ve gösterge detaylarına bağlıdır.

Bu süre zarfında CopyBuffer fonksiyonu çağrısı 4806 - "İstenen veri bulunamadı hatasını üretir.

BarsCalculated fonksiyonu, kopyalama için gösterge verilerinin kullanılabilirliğini belirlemek için kullanılabilir:

//--- number of bars for calculation
   int toCount=rates_total-(int)MathMax(prev_calculated-1,0);
//--- try to copy iWPR indicator data
   int copied=CopyBuffer(WPRHandle,0,0,toCount,Values);
   int err=GetLastError();
//--- check coying result
   if(copied==-1)
     {
      //--- if error number is 4806, the data simply have not been uploaded yet
      if(err==4806)
        {
         //--- wait till the data is uploaded
         for(int i=0;i<1000;++i)
            if(BarsCalculated(WPRHandle)>0)
               break;
         //--- try to copy iWPR indicator data again
         copied=CopyBuffer(WPRHandle,0,0,rates_total,Values);
         err=GetLastError();
        }
     }
//--- check coying result
   if(copied==-1)
     {
      Print("Error when trying to get WPR values, last error is ",err," bars ",rates_total);
      return(0);
     }
//...

 

Özet

Sonuç olarak, bu makalede sadece bazı detayların ele alındığını söylemek isterim. Ama umarım temel yönler burada sunulmuştur.

Bu makale konuyla ilgili her zaman ayrıntılar hakkında bilgi arayabileceğiniz ve bulabileceğiniz yararlı bir referans olursa harika olur.

Bu makalede herhangi bir hata bulduysanız veya önemli bir şey keşfettiyseniz, lütfen beni bilgilendirin, en kısa sürede düzeltmeye ve makaleyi geliştirmeye çalışacağım.

Son değişiklikleri özetlemeyi planlıyorum, bunun yanı sıra, bazı yararlı bilgilerin yorumlarda görüneceğini umuyorum.

Bunları dikkatlice okumanın nedeni budur.

 

Ek

  • Color.mqh - içerme dosyası, bu dosyayı MQL5/Include klasörüne kopyalayın. Bu dosya Toned_WPR göstergesi için gereklidir.
  • Color.mq5 - kitaplık, bu dosyayı MQL5/Libraries klasörüne kopyalayın. Bu dosya Toned_WPR göstergesi için gereklidir.

Dosyaların tamamı göstergelerdir.

 

Teşekkür

Yine, el yazması okuma, faydalı tartışmalar ve yararlı tavsiyeler için Sayın Victor Rustamov'a (granit77) teşekkür etmek istiyorum.


MetaQuotes Ltd tarafından İngilizceden çevrilmiştir.
Orijinal makale: https://www.mql5.com/en/articles/5

Ekli dosyalar |
crossma.mq5 (2.47 KB)
candlesample.mq5 (2.31 KB)
barssample.mq5 (2.3 KB)
color.mq5 (4.28 KB)
color.mqh (0.99 KB)
toned_wpr.mq5 (4.65 KB)
color_rsi.mq5 (5.57 KB)
MQL5: Kendi Göstergenizi Oluşturma MQL5: Kendi Göstergenizi Oluşturma
Bir gösterge nedir? Ekranda uygun bir şekilde görüntülenmesini istediğimiz bir dizi hesaplanmış değerdir. Değer setleri programlarda bir dizi olarak gösterilir. Böylelikle, bir göstergenin oluşturulması, bazı dizileri (fiyat dizileri) idare eden ve diğer dizilere (gösterge değerleri) devretmenin sonuçlarını kaydeden bir algoritmanın yazılması anlamına gelir. Yazar, Doğru Güç Endeksinin oluşturulmasını açıklarken MQL5’te göstergelerin nasıl yazılacağını gösterir.
İşte Karışınızda Yeni MetaTrader 5 ve MQL5 İşte Karışınızda Yeni MetaTrader 5 ve MQL5
Bu MetaTrader 5 ile ilgili sadece kısa bir inceleme. Sistemin tüm yeni özelliklerini bu kadar kısa sürede açıklayamam, test süreci 09.09.2009’da başladı. Bu sembolik bir tarihtir ve şanslı sayı olacağına eminim. MetaTrader 5 terminalinin ve MQL5’in beta sürümünü beş gün önce aldım. Tüm özelliklerini deneme şansım olmadı ama şimdiden etkilendim.
Bir Göstergenin Diğerine Uygulanması Bir Göstergenin Diğerine Uygulanması
OnCalculate() fonksiyon çağrısının kısa biçimini kullanan bir gösterge yazarken, bir göstergenin yalnızca fiyat verileriyle değil, aynı zamanda başka bir göstergenin verileriyle de hesaplanabileceği gerçeğini kaçırabilirsiniz. Diğer göstergelerin verilerine doğru uygulanması için bir göstergeyi geliştirmek ister misiniz? Bu makalede, bu tür bir değişiklik için gereken tüm adımları gözden geçireceğiz.
Ticaret için kombinatorik ve olasılık teorisi (Bölüm III): İlk matematiksel model Ticaret için kombinatorik ve olasılık teorisi (Bölüm III): İlk matematiksel model
Daha önce tartışılan konunun mantıksal bir devamı, ticaret görevleri için çok işlevli matematiksel modellerin geliştirilmesi olacaktır. Bu makalede, fraktalları tanımlayan ilk matematiksel modelin geliştirilmesiyle ilgili tüm süreci sıfırdan anlatacağım. Bu model önemli bir yapı taşı haline gelmeli, çok işlevli ve evrensel olmalıdır. Bu fikrin daha da geliştirilmesi için teorik temelimizi oluşturacaktır.