Ana içeriğe geç

cTrader'da paralel emir gerçekleştirme

cTrader'ı öne çıkaran özelliklerden biri, emirlerinizi gerçekleştirmek için hem senkron hem de asenkron programlama kullanabilme yeteneğidir. Daha fazla ilerlemeden önce emir gerçekleştirme sonuçlarını beklemesi gereken stratejileri uygulamak için senkron programlama kullanabilirsiniz; alternatif olarak, asenkron programlama, aynı anda birden fazla emir gönderebilen yüksek hızlı bir strateji oluştururken en iyi şekilde kullanılır.

Bu videoda ve ilgili makalesinde, senkron ve asenkron gerçekleştirme arasındaki farkı açıklayacak ve yeni emirler vermek için bu yaklaşımların her ikisini de nasıl kullanacağınızı göstereceğiz.

Senkron ve asenkron emir gerçekleştirme

Temel akışlar

Senkron emir gerçekleştirme, basit bir diyagram kullanarak açıklanabilir. Yeni emirleri senkron olarak verirken, bir cBot başka talimatları takip etmeden önce bir emrin gerçekleştirilmesini beklemelidir. Başka bir deyişle, cTrader sunucuya bir emir gönderir, yanıtı bekler ve ancak o zaman bir sonraki kod satırını gerçekleştirmeye başlar.

flowchart LR
  A([Emir 1, 100 ms]) --> B([Emir 2, 70 ms]) --> C([Emir 3, 80 ms]) --> D([Sonraki<br>talimatlar])

Yukarıdaki emirleri senkron olarak verirken, cBot'unuz 3. Emir'den sonra belirtilen talimatlara geçmeden önce toplam 250 ms harcamak zorunda kalacak.

Öte yandan, eşzamansız yürütme, cTrader'ın sunucudan yanıt beklemeden birden fazla emri paralel olarak göndermesine olanak tanır. Eşzamansız programlama kullanarak, bir strateji birden fazla emri gerçekleştirmek için gereken toplam süreyi en aza indirebilir.

flowchart LR
  subgraph Orders ["Emirler"]
    direction TB
    A([Emir 1, 100 ms]) --- B([Emir 2, 70 ms]) --- C([Emir 3, 80 ms])
  end
  D([Sonraki<br>talimatlar])
  Orders --> D

Yukarıdaki diyagramda, her üç emir de tam olarak aynı anda gönderilir ve cBot, sonraki talimatlara geçmeden önce gerçekleştirme sonuçlarını beklemez.

Kod örnekleri

Senkron yürütmenin nasıl çalıştığını göstermek için kod da kullanabiliriz.

1
2
3
4
5
6
7
8
9
protected override void OnStart()
{
    for (int i = 0; i < 10; i++)
    {
        ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
        Print("Order Sent");
        Print("Positions Count:" + Positions.Count); 
    }
}

Bu kodla bir cBot çalıştırırsak, günlük, pozisyon sayısının yalnızca her pozisyon gerçekleştirildikten sonra arttığını gösterecektir. Kod, bir sonraki emri gerçekleştirmek için bir istek göndermeden önce her emrin gerçekleştirilmesini bekliyor.

Eşzamansız emir gerçekleştirmeye geçmek için ExecuteMarketOrderAsync yöntemini kullanabiliriz.

1
2
3
4
5
6
7
8
9
protected override void OnStart()
{
    for (int i = 0; i < 10; i++)
    {
        ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 1000);
        Print("Order Sent");
        Print("Positions Count:" + Positions.Count); 
    }
}

Ayrıca Positions.Opened olayını dinlemek için bir olay işleyici ekleyeceğiz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
protected override void OnStart()
{
    Positions.Opened += Positions_Opened;
    for (int i = 0; i < 10; i++)
    {
        ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 1000, PositionOpened);
        Print("Order Sent");
        Print("Positions Count:" + Positions.Count); 
    }
}

Olay işleyicimizde, bir pozisyon açılır açılmaz günlüğe bir mesaj ve o anki açık pozisyon sayısını yazdıracağız.

Bu kodla bir cBot çalıştırır ve günlüğe bakarsak, tüm emirlerin önceki talimatların sonuçları hakkında bir onay almadan gönderildiğini göreceğiz. Pozisyon sayacı tüm süre boyunca 0'da kaldı. Onaylar, tüm emirler sunucuya gönderildikten birkaç milisaniye sonra geldi ve günlüğe yazdırıldı.

Geri arama emirlerini kullanın

Şimdi kaynak kodumuza geri dönebilir ve eşzamansız yürütmenin başka bir değerli özelliğini, yani emir gerçekleştirme biter bitmez çağrılan geri arama yöntemlerini kullanma seçeneğini gösterebiliriz. Positions.Opened olayının işleyicisini kaldıracak ve bir emir gerçekleştirildiğinde bir onay yazdıran bir geri arama yöntemi uygulayacağız.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private void TradeExecuted(TradeResult tradeResult)
{
    if (tradeResult.IsSuccessful)
    {
        Print("Trade succeeded. Position Opened.");
    }
    else
    {
        Print("Trade failed. Position Not Opened.");
    }
}

Daha sonra bu yöntemi ExecuteMarketOrderAsync yöntemine bir argüman olarak geçireceğiz.

1
ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 1000, TradeExecuted);

Daha önceki yaklaşımımızın aksine, geri arama yöntemi bir işlemin başarılı olup olmadığına bakılmaksızın çağrılacak, bu da başarısız işlemlerden haberdar olduğunuz ve buna göre hareket edebileceğiniz anlamına gelir.

Eşzamansız yürütmenin durumunu izleyin

cTrader ayrıca eşzamansız işlemlerin durumunu izlemek için kullanımı kolay bir araç sunar. ExecuteMarketOrderAsync yöntemi, emrin hala gerçekleştirilip gerçekleştirilmediği hakkında bilgi içeren bir TradeOperation nesnesi döndürür.

Yeni bir alan tanımlayarak başlayabiliriz.

1
TradeOperation _tradeOperation;

Daha sonra for döngümüzü kaldıracak ve emir gerçekleştirme sonucunu yeni alana atayacağız.

1
_tradeOperation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 1000, TradeExecuted);

cBot'umuza bir zamanlayıcı da ekleyeceğiz. Zamanlayıcı, her 100 milisaniyede bir işlemin durumunu kontrol edecek.

1
2
Timer.TimerTick += Timer_TimerTick;
Timer.Start(new System.TimeSpan(0, 0, 0, 0, 100));

Bir işlem hala gerçekleştiriliyorsa, zamanlayıcı bunu günlüğe yazdıracak.

1
2
3
4
5
6
7
8
private void Timer_TimerTick()
{
    Print("Tick");
    if (_tradeOperation != null)
    {
        Print("Trade operation is executing: " + _tradeOperation.IsExecuting);
    }
}

cBot oluşturulduktan sonra, demo hesapta nasıl çalıştığını test edebiliriz. Günlükte, zamanlayıcı eşzamansız yürütmenin durumu hakkında düzenli güncellemeler yazdırmalıdır.

Özet

Eşzamansız yürütme, otomatik emir yerleştirmeyi senkron programlamaya kıyasla çok daha hızlı hale getirebilen güçlü bir araçtır. Ancak, bir sonraki adıma geçmeden önce bir işlemin sonucunu bilmeniz gerekiyorsa senkron yürütme hala kullanılabilir. Eşzamansız yürütme ise, birden fazla emri herhangi bir gecikme olmadan paralel olarak göndermeniz gerektiğinde en iyi şekilde kullanılır.