Kullanıcı Göstergeleri Yazma | Program Ticareti | NTL+ | IFCM Türkiye
IFC Markets Online CFD Broker

Kullanıcı Göstergeler Yazma Temelleri

Tanıtım

Bu makalenin amacı, bir örnekte özel göstergelerin oluşturma ilkelerini ve NTL+ dilinde ilk adımlar yapan programcıların rastlayabilecekleri sorunları açıklamaktır.


Kullanıcı göstergesi algoritmasının hazırlanmasında, gösterge buffer'ine kaydedilen değerlerin nasıl hesaplanacağını ve onların ekranda nasıl görüntüleneceğini belirlemek gerekir. Bu değerlerin doğru oluşumu göstergenin uygulamasının nihai hedefimizdir.


Bir örnek olarak, kapanış fiyatı açılış fiyatından fazla olan barların sayısı ile kapanış fiyatı açılış fiyatından az olan barların sayısı arasındaki farkı gösteren bir endikatör oluşturalım; bu farklılıklar son n aralıklarında toplanır. Göstergemizi ayrı bir pencerede ve bir histogramı şeklinde görüntüleyelim.


Skript kodunun yazılması

Algoritmamız, göstergenin çalışmasını grafikte kontrol edecek kadar basit ve yeterince kolay. Her i-inci bar için önceki n bar analiz edip istatistikleri oluşturalım: artan barın tespit edildiğinde ortaya çıkan değere bir (1) ekleyeceğiz, düşen barın tespit edildiğinde ise biri çıkaracağız.

img

Böyle göstergenin kodunu inceleyelim.


Öncelikle bizim göstergemizde kullanılacak tüm değişkenleri bildirmek gerek.

#set_indicator_separate
double ExtMapBuffer1[];
int ExtCountedBars=0;
extern int period = 10;

#set_indicator_separate preprocessor yönergesi gösteriyor ki biz grafiği ayrı bir pencerede görüntüleyeceğiz ve ana fiyat grafiği üzerinde üst üste olmayacaktır. Bir sonraki satırda global array ExtMapBuffer1 işaretlenir, orada gösterge buffer'inin değerleri saklanacaktır. Dikkat edin ki bu array'ın boyutunu belirtmiyoruz çünkü derleyici ayrılan belleğin gerekli miktarını kendisi belirleyecek.


ExtMapBuffer1 array'ında aslında görüntülemeye dahil ordinates noktalarının koordinatları saklanır, apsisleri ise array öğeleri endeksi ile belirlenir. Sonra ExtCountedBars değişkenini 0 değeri ile başlatıyoruz. Bu değişkende zaten hesaplanmış barlar saklanacak. Böylece, tüm barlar için hesaplamaları yapmamıza gerek yok ve bu da gösterge değerlerinin hesaplanmasını büyük derecede hızlandırır; gösterge grafiğin hareketi daha hızlı olacaktır. Bir sonraki satırda, göstergenin önceden belirlenmiş istatistikleri hesapladığı aralık sayısını saklamak için global değişken period tespit edilmiştir. Unutmayın ki modifikatör extern'in kullanılması, derlemeye gerek kalmadan göstergenin özellikleri aracılığıyla period parametresini değiştirme fırsatını verir.


Initialize() fonksiyonu inceleyelim, onda göstergemiz için temel ayarlarını belirleyeceğiz.


int Initialize() { Indicator.SetIndexCount(1); Indicator.SetIndexBuffer(0,ExtMapBuffer1); Indicator.SetIndexStyle(0,ltHistogram,lsSolid,5,clrBlue); return(0); }

Indicator nesnesinin SetIndexCount metodu gösterge değerlerinin buffer sayısını belirler. ExtMapBuffer1 değerli buffer bizde sadece bir tane var, o yüzden tek parametre olarak "bir" yazıyoruz. Ayrıca, buffer numarası ve array'ı buffer değerleri ile bağlamamız gerekir. Bu bağlama Indicator.SetIndexBuffer(0,ExtMapBuffer1) satırında ayarlanır. O satırda da, sıfır göstergesinin özelliklerinin ExtMapBuffer1 buffer'indeki değerleri çizmek için kullanıldığı tespit edilmiştir.


Bir sonraki satırda bizim göstergemizin özelliklerini ayarlıyoruz. SetIndexStyle metodunun ilk parametresi buffer sayısını belirtir; bu değer, SetIndexBuffer'de ayarlamış olduğunuz 0'dır. İkinci parametre çizme türünü belirtir: histogram. Üçüncü parametrede çizgi stili belirleriz: lsSolid (aslında, dilediğimiz değeri ayarlayabiliriz, çünkü bu seçenek yalnızca tek kalınlıkta hattı ve histogramı etkiler). Bir sonraki parametrede çizgi kalınlığını 5 olarak ve renk mavi clrBlue şeklinde belirliyoruz (renk ayrıca RGB formatında, örneğin 0x0000FF olarak ayarlanabilir).


Sonra, temel kontrolleri yapar ve kullanıcı fonksiyonu draw()'u çalıştırır Run() fonksiyonu geliyor. draw() fonksiyonu tam hesaplama yapar.


int Run() { ExtCountedBars=Indicator.Calculated; if (ExtCountedBars < 0) { System.Print("Error"); return(-1); } draw(); return(0); }

Global değişken ExtCountedBars'a, son çağrıldığı andan değişmeyen barların sayısını giriyoruz. Bu değerler için herşey hesapladık artık, bu yüzden yeniden hesaplamamız gerekmez. Sonra şu koşulu ayarlıyoruz: ExtCountedBars < 0 ise gösterge çalışmasını durduruyor. Sonra da, değerleri hesaplayan ve onları gösterge buffer'ine koyacak olan draw() fonksiyonu çağrılır.


void draw() { int pos=Chart.Bars-ExtCountedBars-1; int value; while(pos>=0) { value=0; for(int i=pos;i < pos+period && i < Chart.Bars-1;i++) { if(Open[i] < Close[i]) value+=1; else value-=1; } ExtMapBuffer1[pos]=value; pos--; } }

«int pos=Chart.Bars-ExtCountedBars-1;» satırında, daha eski verilerden daha yeni verilere hareket ederek, değerleri hesaplamaya başladığımız pozisyonu tespit ediyoruz. Barların Chart.Bars'a eşit toplam sayısı ile en öğe Chart.Bars-1 endeksine sahip, ve hesaplanan barlar göz önüne alındığında: Chart.Bars-ExtCountedBars-1. Değişken "value" bizim istatistiklerimizi depolama için kullanılır. Ardından, Chart.Bars-ExtCountedBars-1'den 0'a kadar her bar için son "period" pozisyon istatistik topluyoruz (yüklenmemiş veriler için değerleri hesaplamak gerekmez).


Tüm kodu birlikte toplayalım:


#set_indicator_separate double ExtMapBuffer1[]; int ExtCountedBars=0; extern int period = 10; int Initialize() { Indicator.SetIndexCount(1); Indicator.SetIndexBuffer(0,ExtMapBuffer1); Indicator.SetIndexStyle(0,ltHistogram,lsDot,5,clrBlue); return(0); } int Run() { ExtCountedBars=Indicator.Calculated; if (ExtCountedBars < 0) { System.Print("Error"); return(-1); } draw(); System.Print("ExtCountedBars="+ExtCountedBars); return(0); } void draw() { int pos=Chart.Bars-ExtCountedBars-1; int value; while(pos>=0) { value=0; for(int i=pos;i < pos+period && i < Chart.Bars-1;i++) { if(Open[i] < Close[i]) value+=1; else value-=1; } ExtMapBuffer1[pos]=value; pos--; } }

Şimdi göstergemizin küçük bir iyileştirme yapalım: negatif sütunlar bir renk ve pozitif sütunlar farklı renge boyayalım. Bununla beraber her bar da iki renkli olacak. Bunun için bize 4 buffer gerekecek.


#set_indicator_separate double ExtMapBuffer1[]; double ExtMapBuffer2[]; double ExtMapBuffer3[]; double ExtMapBuffer4[]; int ExtCountedBars=0; extern int period = 10; int Initialize() { Indicator.SetIndexCount(4); Indicator.SetIndexBuffer(0,ExtMapBuffer1); Indicator.SetIndexStyle(0,ltHistogram,lsDot,5,clrBlue); Indicator.SetIndexBuffer(1,ExtMapBuffer2); Indicator.SetIndexStyle(1,ltHistogram,lsDot,5,clrGreen); Indicator.SetIndexBuffer(2,ExtMapBuffer3); Indicator.SetIndexStyle(2,ltHistogram,lsDot,5,clrRed); Indicator.SetIndexBuffer(3,ExtMapBuffer4); Indicator.SetIndexStyle(3,ltHistogram,lsDot,5,clrLime); return(0); } int Run() { ExtCountedBars=Indicator.Calculated; if (ExtCountedBars < 0) { System.Print("Error"); return(-1); } draw(); return(0); } void draw() { int pos=Chart.Bars-ExtCountedBars-1; int value; while(pos>=0) { value=0; for(int i=pos;i < pos+period && i < Chart.Bars-1;i++) { if(Open[i] < Close[i]) value+=1; else value-=1; } if(value>0) { ExtMapBuffer1[pos]=value; ExtMapBuffer2[pos]=0; ExtMapBuffer3[pos]=1; ExtMapBuffer4[pos]=0; } if(value==0) { ExtMapBuffer1[pos]=0; ExtMapBuffer2[pos]=0; ExtMapBuffer3[pos]=0; ExtMapBuffer4[pos]=0; } if(value < 0) { ExtMapBuffer1[pos]=0; ExtMapBuffer2[pos]=value; ExtMapBuffer3[pos]=0; ExtMapBuffer4[pos]=-1; } } pos--; } }

Renkli barları olan göstergenin yeni sürümü:

img

Gösterge kodu yazarken günlükte (journal) şu mesajı karşılayabilirsiniz: «run fuction call failed» (çalıştırmak için başarısız çağrı). Bu hata, değerler varolmayan endekslerine sahip olan öğelere kaydedilirken sık oluşur, bu yüzden bu mesajın oluşması halinde buffer array'ının endeksleri için değerleri dikkatle kontrol etmeniz gerekir.


Özet

Bu makalede biz ilk göstergemizi adım adım oluşturmuştuk. Bununla birlikte onun uygulanması, skript kodunun NTL+ dilinde anlamanmasını basitleştirmek şeklinde gerçekleştirilmiştir. Belki de bu gösterge ticaretinizde yararlı olmayacak ama, bizim böyle bir görevi kendimize yüklemeye niyetimiz yoktu. Makalede göstergenin uygulanmasının bir örneği gösterilmiştir, bu da herhangi bir gösterge yazarken sizin için yararlı olacaktır.

Close support
Call to Skype Call to messenger Call to telegram Call to WhatsApp Call Back