Dizilerde, Tamponlarda ve Zaman Serilerinde İndisleme Yönü

Tüm dizilerin varsayılan indisleme yönü soldan sağa şeklindedir. İlk elemanın indisi her zaman sıfıra eşittir. Bu nedenle, dizinin (veya tamponun) 0 indisli ilk elemanı varsayılan olarak en solda, son eleman ise en sağda yer alır.

Gösterge tamponu double tipli bir dinamik dizidir, büyüklüğü terminal tarafından ayarlanır ve her zaman göstergenin hesaplandığı çubuk sayısına denk gelir. Basit bir dinamik dizi, SetIndexBuffer() fonksiyonu kullanılarak gösterge tamponu olarak atanır. Gösterge tamponlarının boyutlarının ArrayResize() fonksiyonu ile yeniden ayarlanması gerekmez - bu işlem terminal idari alt-sistemi tarafından otomatik olarak gerçekleştirilir.

Zaman-serileri ters indisleme yönüne sahip dizilerdir, yani son eleman en solda, ilk eleman ise en sağda yer alır. Zaman-serileri, tarihsel fiyat verilerini ve zaman bilgisini depolamak için kullanılır. Bu şekilde baktığımızda en yeni verinin, zaman-serisinin en sağ konumunda yer aldığını, en eski verinin ise en sol konumda yer aldığını söyleyebiliriz.

Yani, 0 indisli zaman-serisi elemanı, sembolün son fiyatı hakkında bilgi içerir. Eğer bir zaman serisi günlük zaman aralığı verilerini içeriyorsa, mevcut (tamamlanmamış) günün verisi sıfır konumunda yer alır ve 1 indisine sahip konumda bir önceki günün verisi mevcuttur.

İndisleme yönünün değiştirilmesi

ArraySetAsSeries() fonksiyonu, dinamik dizi elemanlarının erişim yöntemini değiştirir; bu sırada bilgisayarın veriyi belleğe depolama yöntemi değişmez. Fonksiyon, dizi elemanlarının adresleme şeklini basitçe değiştirir, bu şekilde ArrayCopy() fonksiyonu ile başka bir diziye kopyalama yaparken, alıcı dizinin içeriği, kaynak diziye bağımlı olmaz.

İndisleme yönü statik olarak dağıtılmış dizilerde değiştirilemez. Dizi, fonksiyona parametre olarak geçirilmiş olsa bile, indisleme yönünün değiştirilmesinin hiç bir etkisi olmayacaktır.

Gösterge tamponlarının indisleme yönü de, tıpkı normal dizilerdeki gibi geriye doğru ayarlanabilir (zaman-serilerindeki gibi). Yani, göstergenin sıfır pozisyonuna yapılan referans, karşılık gelen tamponun son değerine, diğer bir deyişle, son çubuk üzerindeki gösterge değerine denk gelecektir. Buna rağmen, gösterge çubuklarının fiziksel yerleri değiştirilmeyecektir.

Göstergelerde Fiyat Verisinin Alınması

Her özel gösterge, hesaplamada kullanılacak fiyat verisinin geçirileceği OnCalculate() fonksiyonunu içermelidir. Geçirilen bu dizilerin indisleme yönü, ArrayGetAsSeries() fonksiyonu ile öğrenilebilir.

Fonksiyona geçirilen diziler, fiyat verilerini yansıtır; bu diziler zaman-serileri işaretine sahiptir ve ArrayIsSeries() fonksiyonu ile kontrol edildiklerinde, 'true' dönüşü alınır. Her durumda, indisleme yönünü öğrenmek için sadece ArrayGetAsSeries() fonksiyonu kullanılmalıdır.

Varsayılan değerlerden bağımsız olmak amacıyla, çalıştığınız diziler için ArraySetAsSeries() fonksiyonu koşulsuz olarak çağrılmalı ve istenen erişim yönü ayarlanmalıdır.

Fiyat Verisinin ve Gösterge Değerlerinin Alınması

Uzman Danışmanlarda, göstergelerde ve scriptlerde kullanılan ön-tanımlı indisleme yönü soldan-sağa doğrudur. Gerekli olduğu durumda, her MQL5 programı ve her sembol/periyot için zaman-serilerinin değerlerini isteyebilirsiniz.

Bu amaç için Copy...() fonksiyonunu kullanmalısınız:

  • CopyBuffer – bir gösterge tamponunun verilerini double tipli bir diziye kopyalar;
  • CopyRates – fiyat geçmişini MqlRates yapı tipli bir diziye kopyalar;
  • CopyTime – Zaman değerlerini datetime tipi bir diziye kopyalar;
  • CopyOpen – Open (açılış) fiyatlarını double tipli bir diziye kopyalar;
  • CopyHigh – High (yüksek) fiyatlarını double tipli bir diziye kopyalar;
  • CopyLow – Low (düşük) fiyatlarını double tipli bir diziye kopyalar;
  • CopyClose – Close (kapanış) fiyatlarını double tipli bir diziye kopyalar;
  • CopyTickVolume – tik hacmi değerlerini long tipli bir diziye kopyalar;
  • CopyRealVolume – alım-satım hacmi değerlerini long tipli bir diziye kopyalar;
  • CopySpread – makas geçmişini int tipli bir diziye kopyalar;

 

Tüm bu fonksiyonlar benzer şekilde çalışırlar. CopyBuffer() örneğindeki veri elde etme mekanizmasını düşünelim. İstenen verinin erişim şeklinin zaman serilerindeki gibi olduğu ve mevcut (tamamlanmamış) çubuğun verisinin 0 indisli konumda depolandığı gösterilmiştir. Bu verilere erişim için, gereken miktarda veriyi alıcı diziye kopyalamamız gerekir, örneğin buffer dizisi.

copyBuffer

Kopyalama yapılırken kaynak dizideki başlangıç konumunu (verinin hangi konumdan başlanarak kopyalanacağını) belirtmemiz gerekir. Başarı durumunda, belirtilen sayıdaki eleman, kaynak diziden (gösterge tamponundan) alıcı diziye kopyalanacaktır. Alıcı dizide ayarlanan indisleme yönünden bağımsız olarak, kopyalama işlemi her zaman yukarıdaki resimde gösterildiği gibi gerçekleştirilir.

Fiyat verisinin yüksek sayıda tekrarlardan oluşan bir döngü ile işlenmesi bekleniyorsa, IsStopped() fonksiyonunu kullanarak programın zorla sonlandırılıp sonlandırılmadığını kontrol etmeniz önerilir:

int copied=CopyBuffer(ma_handle,// gösterge tanıtıcı değeri
                      0,        // Gösterge tamponunun indisi
                      0,        // Kopyalama için başlangıç pozisyonu
                      number,   // Kopyalanacak değerlerin sayısı 
                      Buffer    // Kopyalanan değerlerin yazılacağı dizi
                      );
if(copied<0) return;
int k=0;
while(k<copied && !IsStopped())
  {
   //--- k indisi için değer al
   double value=Buffer[k];
   // ... 
   // değerle çalış
   k++;
  }

Örnek:

input int per=10; // üs periyodu
int ma_handle;    // gösterge tanıtıcı değeri
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ma_handle=iMA(_Symbol,0,per,0,MODE_EMA,PRICE_CLOSE);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double ema[10];
   int copied=CopyBuffer(ma_handle,// gösterge tanıtıcı değeri
                         0,        // gösterge tamponunun indisi
                         0,        // kopyalama başlangıç konumu
                         10,       // kopyalanacak değerlerin sayısı
                         ema       // değerlerin yazılacağı dizi
                         );
   if(copied<0) return;
// .... daha sonraki kodlar
  }

Ayrıca Bakınız

Veri Erişiminin Düzenlenmesi