AlgoLab Nasıl Kullanılır?

turkiyenin-ilk-online-algoritmik-islem-platformu

Yatay görüntülenmeyi henüz destekleyemiyoruz.
Mobil bir cihaz kullanmıyorsanız devam edebilirsiniz.

Devam Et
GİRİŞ YAP KAYIT OL arrow_backŞİFRE YENİLEME
account_circle
lock
Beni Hatırla
vpn_key Şifremi Unuttum
Şifre yenileme mesajınız mail adresinize gönderilecektir.
email
DENİZBANK MÜŞTERİSİYİM
Şifremi Unuttum
Deniz Yatırım

DenizBank hesabınız varsa hızlıca bağlanın!

AÇIKDENİZ İLE GİRİŞ YAP AÇIKDENİZ İLE KAYIT OL
Veya
close

Kodlama Rehberi

Engine Kütüphanesi Nedir?

Engine Kütüphanesi, algoritmalarınızı kolayca kodlayabilmeniz için bazı finansal indikatör ve fonksiyonları barındıran kütüphanedir. Engine kütüphanesi C# yazılım dili altyapısıyla oluşturulmuştur. Engine kütüphanesi içinde bulunan tüm metotları temel C# bilgisiyle kullanabilirsiniz. Kodlama editöründe "Engine." komutu ile kullanabileceğiniz bu kütüphane ile ilgili bilgilere bu makalede yer vereceğiz.

Stratejilerinizi Kodlamaya Başlarken

Engine kütüphanesi kendi içinde kolaylık sağlayan bazı genel tanımlamalara sahiptir. Bu tanımları kodunuzun içinde istediğiniz yerde kullanabilirsiniz.

Sembol

readonly string Sembol

Stratejinizi çalıştırdığınız sembolü getiren değişkendir.

Periyot

readonly string Sembol

Stratejinizi çalıştırdığınız periyodu alabileceğiniz değişkendir.

barlar

List<Engine.Bar> barlar;

barlar değişkeni ile algoritmanızın çalıştığı sembole ve periyoda ait bar verisini liste olarak alabilirsiniz. Bar listesi kendi içinde Open,High,Low,Close,Volume,Date değişkenlerini barındıran bir obje listesidir.

SonPozisyon

float SonPozisyon = 0f;

Algoritmanızın son pozisyonuna ait miktar bilgisini bu değişkende tutulur. Örneğin 1 lot SATIŞ işleminde -1 olarak eşitlenir, pozisyon durumunuzu öğrenmek için bu değişkeni çağırabilirsiniz.

SonYon

string SonYon;

Algoritmanızın son yönünü bu değişkende saklayabilirsiniz. Stratejinizin aynı yönde birden fazla işlem yapmaması için bu değişkeni kullanabilirsiniz. Stratejilerin çoğunda arka arkaya aynı işlemin yapılması istenmediğinden bu değişken genellikle kullanılacaktır. Sonraki bölümlerde bu değişkenin kullanımıyla ilgili örneklere yer vereceğiz.

Parametreler

public Dictionary Parametreler = new Dictionary();

Kendinize ait bir değişken saklamak için “Parametreler” sözlüğünü kullanabilirsiniz. Detaylı örneklerine sonraki bölümlerde yer verilecektir.

Sistem Fonksiyonları

ParametreEkle

public void ParametreEkle(string name, object obj)

Bu fonksiyon ile “Parametreler” sözlüğüne yeni bir değişken ekleyebilirsiniz. Eklediğiniz bu bilgi strateji çalıştığı sırada hafızada tutulacaktır. Böylece strateji içinde bu bilgiyi kullanabilirsiniz. Detaylı örneklerine sonraki bölümlerde yer verilecektir.

BarGetir

public void BarGetir(string symbol, string period)

Stratejinizde birden fazla sembolün verisini kullanmak istiyorsanız bu fonksiyon ile o sembole ait verileri çekebilirsiniz. Bu fonksiyonu kodunuzun başında bir defa çağırmanız yeterlidir. İlk parametreye büyük harflerle sembolün adı, ikinci parametreye ise dakika cinsinden periyot verilmelidir.

EmirGonder

public void EmirGonder(string sembol, string yon, float miktar,string emirTipi = ""piyasa"",float price = 0, string emirSuresi = ""kie"")

Emir göndermek için bu fonksiyon kullanılır. İlk üç parametresi zorunlu olmakla birlikte emir tipi, emir fiyatı ve emir geçerlilik süresi gibi değişkenler isteğe bağlı olarak ayarlanabilir.

Sembol : Emrin gönderileceği sembol string olarak verilmelidir.
Yon : Emrin yönü birkaç farklı şekilde verilebilir; “A”,”ALIŞ”,”ALIS”,”BUY” veya “S”,”SATIŞ”,”SATIS”,”SELL”
Miktar : Emrin kaç lot olacağı float olarak verilmelidir.
EmirTipi :“piyasa” veya “limit” olmalıdır. Limir emir verilmesi durumunda sonraki parametrede fiyat bilgisi girilmelidir.
Fiyat : Limit emirlerde emrin fiyatını belirler.

Pozisyonlari Kapat

public void PozisyonlariKapat(string sembol)

Bu metot stratejinizin o anki pozisyon bilgisini okuyarak ters yönde aynı miktarda emir gönderir. Böylece stratejiye ait açık pozisyonlarınız sıfırlanmış olur.

Engine Fonksiyonları

Engine kütüphanesi fonksiyonları algoritmalarda sık kullanılan işlemleri barındır. Örneğin standart sapma, kare kök alma gibi fonksiyonlara sahiptir. Ayrıca "FiyatGetir" gibi fonksiyonlarla bar listesinden kapanış, açılış, yüksek, düşük gibi listeleri elde edebileceğiniz fonksiyonlarda bulunur. Engine fonksiyonlarının detaylarına diğer makalelerde yer verilmiştir.

Engine İndikatörleri

Engine kütüphanesi 50 üzerinde indikatörle geniş bir yelpazeye sahiptir. Bu indikatörleri "Engine." komutuyla listeletebilir ve parametrelerini görebilirsiniz. İndikatörlerin ne işe yaradıkları, kullanımları ile ilgili makaleleri Teknik Kütüphane'de bulabilirsiniz.

İlk Stratejim

Bir sembolde belirli bir fiyat seviyesi kesildiğinde işlem yapacak bir strateji yazalım.

//Kod içinde yorum veya notlarınızı bu şekilde yazabilirsiniz. //İlk olarak mum grafiğinden kapanış listesini alalım. var C = Engine.FiyatGetir(barlar, "kapanis"); //İşlemin gerçekleşmesini istediğimiz seviyeyi belirleyelim. float seviye = 2.06f; //İşlemimizin miktarını belirleyelim. int lot = 1000; //Bu koşulda eğer kapanışların son değeri belirlediğimiz seviyeden büyükse diyoruz. //Ayrıca SonYon değerimiz alış değilse koşulu eklemeliyiz çünkü seviye geçildikten sonra algoritma arka arkaya bu koşulu kontrol //ederek işlemler açabilir. Tekrarlayan işlemler olmaması için SonYon değerimizi kontrol ediyoruz. if(Engine.SonDeger(C) >= seviye && SonYon != "A"){ //ALIŞ koşulu gerçekleşti, SonYon değerimizi eşitliyoruz. SonYon = "A"; //Emir gönder fonksiyonu ile emri belirlediğimiz “lot” miktarında gönderiyoruz. EmirGonder(Sembol, "ALIS", lot); }

İndikatör Kullanmak

İki hareketli ortalamanın kesişimine göre çalışan bir strateji yazalım. Buna göre 1. Hareketli ortalama değeri 2. Hareketli ortalamadan büyükse “ALIŞ”, tersi durumda “SATIŞ” yapalım.

//Birinci hareketli ortalamamızı alıyoruz. var ma1 = Engine.MA(barlar,"Basit",50); //Hareketli ortalamamızın 1 önceki değerini alıyoruz. //1 önceki değeri almamızın sebebi canlı işlem sırasında mum grafiğindeki son değer sürekli olarak değişecektir. //Bu durum koşulların birden fazla kere çalışmasına sebep olabilir. var madeger1 = Engine.OncekiDeger(ma1,1); //İkinci hareketli ortalamamızı alıyoruz. var ma2 = Engine.MA(barlar,"Basit",200); //Hareketli ortalamamızın 1 önceki değerini alıyoruz. var madeger2 = Engine.OncekiDeger(ma2,1); //1. Hareketli ortalamanın değeri ikinci hareketli ortalamadan büyükse ve “ALIŞ” yönünde değilsek koşulu : if(madeger1 > madeger2 && SonYon != "ALIS") { SonYon = "ALIS"; //Piyasa fiyatlı 1 lot emir gönder EmirGonder(Sembol,"ALIS",1,"piyasa"); } //1. Hareketli ortalamanın değeri ikinci hareketli ortalamadan küçükse ve “SATIŞ” yönünde değilsek koşulu : if(madeger1 < madeger2 && SonYon != "SATIS") { SonYon = "SATIS"; //Piyasa fiyatlı 1 lot emir gönder EmirGonder(Sembol,"SATIS",1,"piyasa"); }

İndikatör Kullanmak 2

Bazı indikatörlerde birden fazla çizgi bulunur. Örneğin Bollinger Bantları Üst, Orta ve Alt bantlar olmak üzere 3 çizgiye sahiptir. Bollinger Bantları kullanan bir strateji oluşturalım.

//Kapanışlar listesini alalım. var C = Engine.FiyatGetir(barlar, "kapanış"); //Bollinger indikatörünü alalım. var bollinger = Engine.BollingerBands(barlar, 14, 2); //Bollinger çizgilerinden hangisini almak istediğimizi aşağıdaki gibi belirteceğiz. //Alt çizgi List<float>altBollinger = bollinger[2]; //Orta çizgi List <float>ortaBollinger = bollinger[1]; //Üst çizgi 0 verilmesinin sebebi ilk sıranın her zaman 0'dan başlamısıdır. List<float>ustBollinger = bollinger[0]; //Üst çizginin kapanmış son mumdaki değerini alalım. float ustSonDeger = Engine.OncekiDeger(ustBollinger, 1); //Alt çizginin kapanmış son mumdaki değerini alalım. float altSonDeger = Engine.OncekiDeger(altBollinger, 1); //Bir önceki kapanış değerimizi alalım. float sonKapanis = Engine.OncekiDeger(C, 1); //Kapanış değeri üst çizginin üstünde kalırsa ALIŞ yapalım if(sonKapanis > ustSonDeger && SonYon != "ALIS") { SonYon = "ALIS"; EmirGonder(Sembol,"ALIS",1,"piyasa"); } //Kapanış değeri alt çizginin altında kalırsa SATIŞ yapalım else if(sonKapanis < altSonDeger && SonYon != "SATIS") { SonYon = "SATIS"; EmirGonder(Sembol,"SATIS",1,"piyasa"); }

Double Lot Strateji

İşleme girerken bir önceki pozisyonu kapatacak ve diğer yönde pozisyona geçecek bir strateji yazalım. Bu stratejide açığa satış durumu söz konusu olduğu için sadece VİOP sembollerinde çalıştırılması tavsiye edilir. Emir gönderilirken “SonPozisyon” değişkeni otomatik olarak emir miktarı kadar artar veya azalır. Örneğin 3 lot ALIŞ işlemi sonrası SonPozisyon = 3 olacaktır. Daha sonra 4 lot SATIŞ işlemi gönderildiğinde SonPozisyon = (3 -4) = -1 olacaktır.

Aşağıda geçmiş örnekte verdiğimiz stratejiyi ters işleme girecek şekilde değiştireceğiz.

//İşlem yapacağımız lotu belirleyelim. int lot = 500; var ma1 = Engine.MA(barlar,"Basit",50); var madeger1 = Engine.OncekiDeger(ma1,1); var ma2 = Engine.MA(barlar,"Basit",200); var madeger2 = Engine.OncekiDeger(ma2,1); if(madeger1 > madeger2 && SonYon != "ALIS") { SonYon = "ALIS"; //SonPozisyon değişkeninin mutlak değerini alıp üzerine lot miktarımızı ekliyoruz. EmirGonder(Sembol,"ALIS",Engine.MutlakDeger(SonPozisyon) + lot,"piyasa"); } if(madeger1 < madeger2 && SonYon != "SATIS") { SonYon = "SATIS"; //SonPozisyon değişkeninin mutlak değerini alıp üzerine lot miktarımızı ekliyoruz. EmirGonder(Sembol,"SATIS",Engine.MutlakDeger(SonPozisyon) + lot,"piyasa"); }

Zamana Bağlı Strateji

Stratejilerde zamana bağlı koşullar yazılabilir. Örneğin saat 17 sonrasında işlemleri kapatacak bir koşul yazabiliriz. Zamana bağlı strateji kullanırken iki farklı tarihten yola çıkabiliriz. Birincisi sistem saatini kullanarak o anki saati elde etmek. İkincisi ise mum grafiğindeki son mum çubuğunun tarihini alarak en yakın saati elde etmek.

Örnek verecek olursak 5 dakikalık periyotta çalışan bir strateji için;

//Saat şu anda 12.03, “sonSaat” değerimiz 12.03 olur DateTime sonSaat = DateTime.Now; //5 dakikalık periyottaki son bar tarihi 12.00 olacağı için “sonMumSaat” 12.00 olacaktır. DateTime sonMumSaat = barlar[barlar.Count - 1].Date; RSI indikatörünün 30 ve 70 seviyelerini geçmesi durumunda işlem yapan ve saat 17’de pozisyonları kapatan bir strateji yazalım. int lot = 500; var rsi = Engine.RSI(barlar,14); var rsideger1 = Engine.OncekiDeger(rsi,1); //Stratejinin çalıştığı mum grafiğindeki son mum tarihini alalım. DateTime sonMumTarihi = barlar[barlar.Count - 1].Date; //Son mum barının saati 17'den küçükse ALIŞ veya SATIŞ yapılabilsin. if(sonMumTarihi.Hour < 17) { if(rsideger1 > 70 && SonYon != "ALIS") { SonYon = "ALIS"; EmirGonder(Sembol,"ALIS",lot,"piyasa"); } if(rsideger1 < 30 && SonYon != "SATIS") { SonYon = "SATIS"; EmirGonder(Sembol,"SATIS",Engine.MutlakDeger(SonPozisyon) + lot,"piyasa"); } } //Son mum barının saati 17 ise işlemler kapansın. if(sonMumTarihi.Hour == 17 && SonYon != "FLAT"){ //Pozisyonları kapat ve son yönü flat yap. SonYon = "FLAT"; PozisyonlariKapat(Sembol); }

Çoklu Sembol&Periyot Stratejisi

Stratejiler çalıştırılırken bir sembol ve periyot seçilir. Fakat bazı stratejilerde birden fazla sembol ve periyot kullanma ihtiyacı olabilir. Bu durumda stratejinin çalıştırıldığı sembol ve periyot haricinde bir veri almak için aşağıdaki gibi kodlama yapılmalıdır. Bu örnekte stratejiyi GARAN 15 dakikalık periyotta çalıştırdığımızı düşünelim. Buna ek olarak stratejide GARAN 120 dakikalık periyota ait verileri de kullanacağız.

//Kodun en başında kullanmak istediğimiz sembol ve periyotu belirtiyoruz. BarGetir("GARAN","120"); //GARAN 120 dakika mum grafik listesini aşağıdaki gibi elde edebiliriz. var barlar120 = TumBarlar["GARAN"]["120"]; //120 dakikalık periyotta SAR indikatörü kullanalım. var SAR120 = Engine.SAR(barlar120, 0.02f,0.2f); //Stratejinin çalıştığı sembol ve periyotta kapanış listesi ve hareketli ortalama alalım var C = Engine.FiyatGetir(barlar, "Kapanis"); var MA = Engine.MA(barlar, "Basit", 22); //120 dakikalık SAR ve diğer periyottaki kapanış değerini karşılaştıran koşulumuz if(Engine.OncekiDeger(C,1) > Engine.OncekiDeger(SAR120,1) && Engine.OncekiDeger(C,1) > Engine.OncekiDeger(MA,1) && SonYon != "A"){ SonYon = "A"; EmirGonder(Sembol, "ALIS", 1); } else if(Engine.OncekiDeger(C,1) < Engine.OncekiDeger(SAR120,1) && Engine.OncekiDeger(C,1) < Engine.OncekiDeger(MA,1) && SonYon != "S"){ SonYon = "S"; EmirGonder(Sembol, "SATIS", 1); }

Özel Parametre Kullanmak

Stratejiler içinde tanımlanan değişkenler her fiyat değişiminde yeniden hesaplanır. Bazı durumlarda değişkenleri hafızada tutma ihtiyacı ortaya çıkabilir. Örneğin yapılan son işlemin fiyatını bir değişkende saklayıp daha sonra bu değişkene göre farklı bir işlem yapılmasını istersek stratejide özel bir parametre tanımlamamız gerekecektir.

var C = Engine.FiyatGetir(barlar, "kapanis"); var MA5 = Engine.MA(barlar, "Simple", 5); var MA22 = Engine.MA(barlar, "Simple", 22); var RSI14 = Engine.RSI(barlar, 14); //Emir fiyatımızı hafızada tutacak değişkeni ekleyelim. ParametreEkle("hangiKosulGerceklesti", ""); //Kar al yüzdemizi belirleyelim float karAlYuzde = 0.01f; //Stop yüzdemizi belirleyelim float stopYuzde = 0.01f; //Hareketli ortalama ALIŞ koşulu if(Engine.OncekiDeger(MA5,1) > Engine.OncekiDeger(MA22,1) && SonYon != "A") { SonYon = "A"; EmirGonder(Sembol,"ALIS", 1); //Emrin gönderildiği koşulu hafızaya alalım. Parametreler["hangiKosulGerceklesti"] = "MA"; } //Hareketli ortalama ALIŞ koşulu if(Engine.OncekiDeger(RSI14,1) > 70 && SonYon != "A") { SonYon = "A"; EmirGonder(Sembol,"ALIS", 1); //Emrin gönderildiği koşulu hafızaya alalım. Parametreler["hangiKosulGerceklesti"] = "RSI"; } string kosul = Parametreler["hangiKosulGerceklesti"].ToString(); //Eğer RSI koşulu ile işleme girildiyse //RSI 30 altında SATIŞ yap if(kosul == "RSI" && Engine.OncekiDeger(RSI14,1) < 30 && SonYon != "S") { SonYon = "S"; EmirGonder(Sembol,"SATIS", 1); } //Eğer MA koşulu ile işleme girildiyse //MA 5 periyot 22 den küçük olduğunda SATIŞ yap if(kosul == "MA" && Engine.OncekiDeger(MA5,1) < Engine.OncekiDeger(MA22,1) && SonYon != "S") { SonYon = "S"; EmirGonder(Sembol,"SATIS", 1); }

Take Profit & Stop Loss Örneği

Belirli bir yüzde ile kar al veya zarar durdur yapan bir strateji oluşturalım. Bu stratejide hareketli ortalama koşuluna göre işleme gireceğiz. İşleme girdiğimiz fiyatı bir değişkende saklamamız gerekiyor çünkü daha sonra bu fiyata göre kar al veya zarar durdur işlemi yapacağız.

//Kapanışları ve 2 farklı hareketli ortalamayı alalım var C = Engine.FiyatGetir(barlar, "kapanis"); var MA5 = Engine.MA(barlar, "Simple", 5); var MA22 = Engine.MA(barlar, "Simple", 22); //Emir fiyatımızı hafızada tutacak değişkeni ekleyelim. ParametreEkle("fiyat", 0f); //Kar al yüzdemizi belirleyelim float karAlYuzde = 0.01f; //Stop yüzdemizi belirleyelim float stopYuzde = 0.01f; //Hareketli ortalama ALIŞ koşulu if(Engine.OncekiDeger(MA5,1) > Engine.OncekiDeger(MA22,1) && SonYon != "A") { SonYon = "A"; EmirGonder(Sembol,"ALIS", 1); //Emrin gönderildiği fiyatı hafızaya alalım. Parametreler["fiyat"] = Engine.SonDeger(C); } //ALIŞ yönlü işlem yapıldıysa. if(SonYon == "A") { //Hafızada tutulan son emrin fiyatını alalım. float sonEmirFiyati = Convert.ToSingle(Parametreler["fiyat"]); //Kar al kontrolü if(sonEmirFiyati * (1+karAlYuzde) < Engine.SonDeger(C)) { //Pozisyonları kapat ve yönü Flat yap PozisyonlariKapat(Sembol); SonYon = "F"; } //Stop loss kontolü if(sonEmirFiyati * (1-karAlYuzde) > Engine.SonDeger(C)) { //Pozisyonları kapat ve yönü Flat yap PozisyonlariKapat(Sembol); SonYon = "F"; } }

Kendi İndikatörünü Yaratmak

Engine kütüphanesinde bulunmayan veya size özel indikatörleri de kodlayarak oluşturabilirsiniz. Örneğin son 10 mum çubuğundaki en yüksek ve düşük değerin ortalamasını alan ve bunu bir indikatör gibi kullanan bir strateji yazalım.

//Yüksek, düşük ve kapanış listelerini alalım. var H = Engine.FiyatGetir(barlar, "yüksek"); var L = Engine.FiyatGetir(barlar, "düşük"); var C = Engine.FiyatGetir(barlar, "kapanış"); //İndikatörümüzün periyotunu belirleyelim int period = 10; //İndikatörümüzü yeni bir liste olarak oluşturalım. List<float> indikatorum = new List<float>(); //10. bardan itibaren son bara kadar indikatörümüzü hesaplayacağız. for(int i = period; i < barlar.Count; i ++) { //Son 10 barı listeye alalım. var subList = C.GetRange(i-period, period); //Son 10 barın en düşüğünü bulalım float enDusuk = Engine.EnDusukDeger(subList); //Son 10 barın en yükseğini bulalım float enYuksek = Engine.EnYuksekDeger(subList); //En yüksek ve düşüğün ortalamasını alalım float ortalama = (enYuksek + enDusuk) / 2f; //İndikatör listemize değeri ekleyelim. indikatorum.Add(ortalama); } //İndikatörümüzü kullanarak ALIŞ ve SATIŞ koşulu oluşturalım. if(Engine.OncekiDeger(indikatorum, 1) > Engine.OncekiDeger(indikatorum, 2) && SonYon != "A") { SonYon = "A"; EmirGonder(Sembol,"ALIS", 1); } else if(Engine.OncekiDeger(indikatorum, 1) < Engine.OncekiDeger(indikatorum, 2) && SonYon != "S") { SonYon = "S"; EmirGonder(Sembol,"SATIS", 1); }

Backtest İçin Log Yazdırmak

Kodlama yaparken sorun çözmek için kullanılabilecek en önemli yöntem backtest’e log yazdırmaktır. Böylece stratejinizde hangi değerlerin kullanıldığını veya hangi koşulların gerçekleştiğini backtest içinde kontrol edebilirsiniz. Aşağıdaki örnekte her yeni mum çubuğunda hareketli ortalamaların son değerlerini log olarak yazdıracaktır. Ayrıca alış ve satış durumunda da tarihle birlikte log yazdıracaktır. Backtest yapıldığında log sekmesi açılacak ve yazdırılanlar burada görülecektir.

var ma1 = Engine.MA(barlar,"Basit",50); var madeger1 = Engine.OncekiDeger(ma1,1); var ma2 = Engine.MA(barlar,"Basit",200); var madeger2 = Engine.OncekiDeger(ma2,1); if(madeger1 > madeger2 && SonYon != "ALIS") { SonYon = "ALIS"; EmirGonder(Sembol,"ALIS",1,"piyasa"); Log += barlar[barlar.Count - 1].Date + " :: ALIŞ KOŞULU TETİKLENDİ." + Environment.NewLine; } if(madeger1 < madeger2 && SonYon != "SATIS") { SonYon = "SATIS"; EmirGonder(Sembol,"SATIS",1,"piyasa"); Log += barlar[barlar.Count - 1].Date + " :: SATIŞ KOŞULU TETİKLENDİ." + Environment.NewLine; } Log += barlar[barlar.Count - 1].Date + " :: "+ madeger1 + " " + madeger2 + Environment.NewLine;