Ana içeriğe geç

cTrader API'ye yöntemler nasıl eklenir

Uzantı yöntemleri, cTrader API'ye yeni işlevsellik eklemek isterseniz çok önemli bir araçtır. Nispeten basit bir söz dizimi kullanarak Symbol veya Position gibi önceden tanımlanmış herhangi bir API sınıfına yeni davranışlar ekleyebilirsiniz. Bir uzantı yöntemi tanımladıktan sonra, onu uzattığınız sınıfın herhangi bir nesnesinden çağırabilirsiniz.

Uzantı yöntemleri için kullanım durumu

İlk olarak, neden uzantı yöntemlerini kullanmak isteyebileceğinize dair hızlı bir gösterim yapacağız.

Bir cBot kullanarak, belirli bir pozisyonun lot cinsinden boyutuna erişebilmek istiyoruz, çünkü bu bilgi tercih ettiğimiz işlem stratejisini doğrudan etkiliyor. Bunu yapmak için, Position sınıfından bir değişkeni başlatmayı ve ardından Lots() yöntemine erişmeyi deneyebiliriz.

1
2
Position position = Positions.Last();
Print(position.Lots());

Kodu olduğu gibi yazarsak, Lots() erişimcisinin API'de mevcut olmadığını belirten bir hata alırız. Peki ya başka hiçbir işlevselliği etkilemeden mevcut bir API üyesine yeni bir yöntem eklemenin bir yolu olsaydı?

Bu yöntemin var olduğunu varsayarsak, her barda, mevcut tüm pozisyonların bir listesi üzerinde döngü yapacak ve boyutlarını lot cinsinden günlüğe yazdıracak basit bir cBot oluşturabilirdik. OnBar() yöntemini aşağıdaki gibi tanımlardık.

1
2
3
4
5
6
protected override void OnBar()
{
    foreach (var position in Positions) {
        Print(position.Lots());
    }
}

Uzantı yöntemleri, Lots() işlevselliğini sadece birkaç satır kodla eklememize ve ardından Position sınıfının herhangi bir nesnesinde istediğimiz zaman yeniden kullanmamıza olanak tanır. Aşağıda, nasıl oluşturabileceğinizi açıklıyor ve onları kullanan algoritmaların çeşitli örneklerini sunuyoruz.

Uzantı yöntemleri nasıl çalışır

Uzantı yöntemleriyle çalışırken aşağıdaki kurallara dikkat edin.

  • Uzantı yöntemleri her zaman statiktir.

Statik bir yöntem bildirmek için tek yapmanız gereken static anahtar kelimesini kullanmaktır. Aşağıda, Lots() yöntemini boş bir gövdeyle bildirin.

1
2
3
4
public static class MyExtensions {
    public static double Lots() {}

}
  • Uzantı yöntemleri herhangi bir sayıda argümana sahip olabilir, ancak ilk argüman her zaman yöntemin çağrılması gereken veri türünü/sınıfını this anahtar kelimesiyle öncelenmiş olarak belirtmelidir.

Position sınıfından bir nesneyi Lots() yönteminin ilk ve tek argümanı olarak ekleyeceğiz. Bir Position nesnesi aynı zamanda pozisyonun açıldığı sembol hakkında bilgi içerdiğinden, başka argümanlara ihtiyacımız yok.

1
2
3
public static class MyExtensions {
    public static double Lots(this Position position) {}
}
  • Uzantı yöntemleri, sağlanan argümanlar için uygun herhangi bir mantığı içerebilir.

Bir uzantı yönteminin gövdesini tanımlarken özel söz dizimi kullanmaya gerek yoktur. Onu başka herhangi bir yöntem gibi ele alabiliriz ve bu nedenle gövdesini aşağıdaki gibi tanımlayabiliriz.

1
2
3
4
5
public static class MyExtensions {
    public static double Lots(this Position position) {
        return position.VolumeInUnits / position.Symbol.LotSize;
    }
}
  • Uzantı yöntemleri örnek yöntemler veya statik yöntemler olarak çağrılabilir.

Uzantı yöntemimizi bir cBot'un kodunda çağırmanın iki olası yolu vardır.

Örnek yöntem söz dizimini kullanırken, yöntemi Position türündeki herhangi uygun bir nesneden çağırırız.

1
2
var position = Positions.Last();
Print(position.Lots());

Statik yöntem söz dizimini kullanırken, uzantı yöntemimizi ilgili statik sınıfını tam olarak belirttikten sonra çağırabiliriz.

1
2
var position = Positions.Last();
Print(MyExtensions.Lots(position));

Uzantı yöntemlerini çağırmanın hangi yönteminin en uygun olduğunu belirlemek size kalmış.

Yöntem imzaları

Örnek söz dizimi kullanırken, uzantı yöntemlerinizin yerleşik API yöntemlerinden herhangi biriyle (örneğin Position.Close()) aynı imzalara sahip olduğu durumlardan kaçının. Bu durumlarda, eşleşen imzaya sahip bir uzantı yöntemini çağırmaya çalıştığınız her seferinde yerleşik bir yöntem çağrılacaktır.

IntelliSense

Bir uzantı yöntemini çağırmaya çalıştığımızda, IntelliSense onu yerleşik API üyelerinden ayırmak için özel bir simge kullanır.

Yeni yöntemimizi eylemde göstermek için, başlangıçta her biri farklı bir hacme sahip üç emir veren bir cBot oluşturabiliriz. Her barda, cBot şu anda açık olan tüm pozisyonların hacmini lot cinsinden yazdırır.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
protected override void OnStart()
{
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 100000);
    ExecuteMarketOrder(TradeType.Buy, SymbolName, 50000);
}

protected override void OnBar()
{
    foreach (var position in Positions) {
        Print(position.Lots());
    }
}

cBot'umuzu oluşturup başlattıktan sonra, doğru değerlerin günlüğe yazdırıldığını görmeliyiz.

cBot'larda uzantı yöntemlerini kullanma

Şimdi daha karmaşık bir cBot oluşturmaya çalışacağız. Her barda, algoritmamız şu anda açık olan pozisyonların listesini gözden geçirecek ve zarar durdur seviyelerini başa baş noktasına gelecek şekilde ayarlayacak. Bunu yapmak için, Position sınıfı için bir BreakEven() uzantı yöntemi oluşturmamız gerekecek.

Yeni bir cBot oluşturup yeniden adlandırıyoruz. Sonrasında, ihtiyacımız olmayan tüm kodu siliyoruz ve MyExtensions sınıfını ekliyoruz.

1
2
3
public static class MyExtensions {

}

BreakEven() yöntemimiz için kodumuz nispeten basittir. Bir pozisyonun zarar durdur'u olup olmadığını, brüt kârının sıfırdan büyük olup olmadığını ve şu anda ayarlanmış zarar durdur'un pozisyon giriş fiyatına eşit olup olmadığını kontrol ederiz. Tüm bu koşullar doğruysa, pozisyonun zarar durdur'unu pozisyon giriş fiyatına eşit olacak şekilde değiştiririz.

1
2
3
4
5
6
7
public static class MyExtensions {
    public static void BreakEven(this Position position) {
        if (position.StopLoss is not null && position.GrossProfit > 0 && position.StopLoss != position.EntryPrice) {
            position.ModifyStopLossPrice(position.EntryPrice);
        }
    }
}

cBot'un kendisinde, OnBar() dışında herhangi bir yöntem kullanmamıza gerek yoktur. Her barda cBot'tan basit bir işlem yapmasını isteriz, yani Positions koleksiyonu üzerinde döngü yapmasını ve içindeki her öğe için yeni BreakEven() yöntemini çağırmasını.

1
2
3
4
5
6
protected override void OnBar() 
{
    foreach (var position in Positions) {
        position.BreakEven();
    }
}

cBot'umuzu oluşturup başlattıktan sonra, onu eylemde görebiliriz. Özellikle birçok açık pozisyonu yönetirken yararlı bir işlem asistanı olabilir.

Göstergelerde uzantı yöntemlerini kullanma

Ayrıca uzantı yöntemlerine dayanan yararlı bir gösterge oluşturacağız. Gösterge, bir sembolün fiyatının her barda o barın açılış fiyatına kıyasla değiştiği yüzdeyi çizerek oynaklığı ölçecek.

Bunu yapmak için, yeni bir gösterge oluşturup yeniden adlandıracağız. Kod düzenleyici penceresinde, Bar sınıfını genişletmek için MyExtensions sınıfını oluşturacağız.

1
2
3
public static class MyExtensions {

}

Ayrıca PercentageChange() yöntemini ekleyeceğiz. priceChange değişkeninde, bir barın kapanış fiyatını açılış fiyatından çıkarırız. Yöntem, fiyat değişimimizi açılış fiyatına bölünüp 100 ile çarpılmış olarak döndürür.

1
2
3
4
5
6
7
8
public static class MyExtensions 
{
    public static double PercentageChange(this Bar bar) 
    {
        var priceChange = bar.Open - bar.Close;
        return priceChange / bar.Open * 100;
    }
}

Gösterge kodunun kendisinde, Initialize() yöntemine ve gereksiz parametrelere ihtiyacımız yok. Calculate() yönteminin gövdesinde, her barda yeni PercentageChange() yöntemimizi çağırırız.

1
2
3
4
5
6
7
8
[Output("Main")]
public IndicatorDataSeries Result { get; set; }


public override void Calculate(int index)
{
    Result[index] = Bars[index].PercentageChange();
}

Sonrasında, göstergemizi kaydedip oluştururuz. Bir örneğini oluşturduktan sonra, doğru yüzde değişimlerinin çizildiğini görmeliyiz. Kısa ve uzun vadeli oynaklığı belirlemek için kullanılabilirler, her türlü işlem stratejisine fayda sağlayarak.

Özet

Sonuç olarak, uzantı yöntemleri, cTrader API'sine yeni işlevsellikler ekleyen yeniden kullanılabilir kod oluşturmak istiyorsanız değerli bir araçtır. Algoritmalarınızı daha verimli ve bakımı daha kolay hale getirebilecekleri için uzantı yöntemleriyle denemeler yapmanızı şiddetle tavsiye ederiz.