
Yeni Raylara Adım Atın: MQL5'te Özel Göstergeler
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





- Ücretsiz alım-satım uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz