Ana içeriğe geç

Algoritmik işlem yapma için C#

C# nedir

C#, çok çeşitli hizmetler ve uygulamalar oluşturmak için kullanılan nesne yönelimli bir programlama dilidir. Net, yapılandırılmış söz dizimi, yeni başlayanlar için bile öğrenmeyi ve okumayı kolaylaştırırken, kompakt ve yeniden kullanılabilir kod yazmaya yapılandırılmış bir yaklaşım sunar.

Bir dakikada C# algoritmaları!

  • C# ile daha önce hiç çalışmamış olsanız bile, ilk botunuzu veya göstergenizi oluşturmak ve dağıtmak yalnızca birkaç dakikanızı alır.
  • C# kullanımı kolay olduğundan, bu dokümantasyondaki herhangi bir kod parçasını ihtiyaçlarınıza göre hızlıca yeniden yazabilirsiniz.
  • C# kullanırken, önceden tanımlanmış sınıflar ve yöntemler içeren çok sayıda kütüphaneye erişebilirsiniz. Bu yöntemler, yaygın görevleri verimli bir şekilde hallederek karmaşık işlem sorunlarını çözmenize olanak tanır.
  • C#'ta, yürütme sırasında sunucu iş parçacıklarını engellemeyen kod yazabilirsiniz. Başka bir deyişle, belirli görevleri diğer görevlerle eş zamanlı olarak başlatabilirsiniz.

.NET nedir?

C# programlarının çalışması için kaynak kodlarının Ara Dil'e (IL) derlenmesi gerekir. Bu IL kodu, Ortak Dil Altyapısı (CLI) spesifikasyonunu takip eder ve daha sonra çalışma zamanında yerel makine talimatlarına derlenir. .NET çerçevesi, kapsamlı sınıf kütüphaneleri ve Ortak Dil Çalışma Zamanı (CLR), yani Microsoft'un CLI uygulaması üzerine kurulu sanal bir yürütme ortamı sağlar.

Teknik ayrıntılara girmeden, .NET aşağıdaki işlevleri yerine getirir:

  • Uygulama geliştirme ve yürütmeyi kolaylaştırma: .NET SDK, halihazırda çeşitli yerleşik derleyiciler ve derleme motorları içerir, bu da özel çözümler oluşturma ihtiyacını ortadan kaldırır.
  • Çalışma zamanı kütüphaneleri sağlama: Kodunuza yeni veri türleri veya koleksiyonlar eklerken, .NET'in bu görev için zaten uygun sınıflar ve yöntemler sunduğunu sık sık göreceksiniz.

C#'ın temelleri

Veri türleri ve değişken bildirimleri

Veri türleri, C#'ın değişkenleri ve özellikleri tam olarak nasıl ele alacağını bilmesi için verileri kategorize etme yöntemidir. Değişken/özellik bildirimlerinde, veri türleri her zaman değişken/özellik adından önce gelir.

1
string developer = "I am developing cBots, plugins, and indicators!";

Alternatif olarak, bir veri türü belirtmekten kaçınmak için var anahtar kelimesini kullanabilirsiniz.

1
var developer = "I am developing cBots, plugins, and indicators!";

Nesneler ve sınıflar

Nesneleri somut veya soyut varlıkların soyutlamaları olarak düşünün. Bu varlıklar belirli özelliklere (properties) sahip olabilir ve çeşitli operasyonlar (methods) gerçekleştirebilir. Buna karşılık, sınıflar nesne oluşturma için şablon görevi görür.

C# nesne yönelimli bir dil olduğundan, sınıflar diğer sınıflardan da özellikler ve yöntemler miras alabilir. Aşağıdaki örnekte, Robot sınıfından miras alan yeni bir NewBot sınıfı bildirdiğimizi düşünün. Ayrıca bazı yeni sınıf özellikleri tanımlıyoruz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* We use the colon sign to designate inheritance.
Additionally, we used expressions in square brackets to
specify the parameters that apply to the entire class */
[Robot(AccessRights = AccessRights.None)]
public class NewBot : Robot
{
    /* We declare a custom class property and make it
    read-only. */
    public string CustomProperty { get; }

    /* In this declaration, we define the default value of a
    custom parameter. */
    [Parameter("BotName", DefaultValue = "Traders First!")]

    /* We declare the BotName property which is changeable via
    the "BotName" parameter. */
    public string BotName { get; }

    /* We also declare the BotComment parameter.
    It can be both read and set. */
    [Parameter("BotComment", DefaultValue = "Our super-duper bot!")]
    public string BotComment { get; set; }
}

Veri türleri

C# güçlü tipli bir dil olduğundan, değişkenleri ve sınıf özelliklerini bildirirken veri türlerini belirtmek gerekir. Kısacası, veri türleri farklı davranış kümelerine sahip benzersiz sınıflar oluşturur. Farklı sınıf özellikleri ve ilgili parametreler için çeşitli veri türlerinin belirtildiği aşağıdaki örnekleri düşünün.

1
2
[Parameter("Price")]
public DataSeries Source { get; }

Yukarıdaki kodda, DataSeries veri türü, salt okunur bir değer listesini temsil eder ve bu nedenle genellikle piyasa fiyatlarını temsil etmek için kullanılır.

Çok seçenekli parametreler oluşturma ihtiyacı olduğunda, aşağıda ayrıntıları verilen yerleşik enum veri türünü kullanabilirsiniz. enum'ları çeşitli sabitler içeren özel sınıflar olarak düşünebilirsiniz.

1
2
3
4
5
6
7
8
9
public enum Option
{
    First,
    Second,
    Third
}

[Parameter("Option", DefaultValue = Option.Third)]
public Option SelectedOption { get; set; }

Bir enum içinde yer alan bir sabite erişmek için aşağıdaki söz dizimini kullanın.

1
var newOption = Option.First;

Bir parametre veya özelliğin sayı olması gerekiyorsa, çoğunlukla int (tam sayı) veya double (ondalık) veri türlerini kullanırsınız. double türü, decimal türünden daha az hassasiyete sahip olsa da, aynı zamanda daha az kaynak yoğundur.

1
2
[Parameter("MA Periods", DefaultValue = 14, MinValue = 1, MaxValue = 20)]
public int Periods { get; set; }

Son olarak, bool türü tipik olarak evet veya hayır girdisini temsil eder. Evet ve hayır değerleri sırasıyla true ve false değerlerine karşılık gelir.

1
2
[Parameter("Message", DefaultValue = true)]
public bool DisplayChartMessage { get; set; }

Ad alanları

Ad alanları, belirlenmiş sınıf koleksiyonları olarak işlev görür. Bir sınıfı bir ad alanına atadığınızda, daha sonra Namespace.ClassName gösterimi kullanılarak erişilebilir. NewBot'umuzu CoolTradingBots ad alanına atayacağız.

1
2
3
4
5
6
7
8
namespace CoolTradingBots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewBot : Robot
    {
        // ...
    }
}

Sınıf yöntemleri

Sınıf yöntemleri, sınıf bildirimini takiben tanımlanır. NewBot sınıfımızın tüm nesneleri CustomTradeOperation() yöntemini çağırabilecektir. İki argüman alır: bir Symbol nesnesi ve bir double nesnesi. Yöntemimiz bir sembol alıp belirtilen hacim için bir tür işlem eylemi gerçekleştirmelidir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
namespace CoolTradingBots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewBot : Robot
    {
        // ... Defining the class parameters.

        // We declare the CustomTradeOperation method. 
        protected override void CustomTradeOperation(string symbolName, double volume)

        {
            // This space is for declaring the method logic. 
        }
    }
}

Sınıf kütüphaneleri

Sınıf kütüphanelerine (ve dolayısıyla sınıf yöntemlerine) aşağıdaki örnekte gösterildiği gibi ad alanları aracılığıyla erişilebilir.

1
CoolTradingBots.NewBot.CustomTradeOperation(symbolName, 10000)

Alternatif olarak, belirli ad alanlarını belirtmek ve fazlalıkları önlemek için kodunuzun başına using anahtar kelimesini yazabilirsiniz. Aşağıdaki kod parçasını düşünün.

1
2
3
using CoolTradingBots;

NewBot.CustomTradeOperation(symbolName, 10000)

Koşullu ifadeler

Koşullu ifadeleri kullanmak için, bir anahtar kelimeyi parantez içindeki bir ifade takip etmelidir. Aşağıdaki örnek, CustomTradingOperation() metodumuzu sonlandırmak için if anahtar kelimesini kullanır. Bunu yapmak için, Analytics.Actions ad alanında tanımlanan EvaluateMarket() metodunu kullanırız.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
namespace CoolTradingBots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewBot : Robot
    {
        // ... Defining the class parameters.

        protected override void CustomTradeOperation(string symbolName, double volume)
        {
            // We declare and initialize the 'result' variable.
            var result = Analytics.Action.EvaluateMarket();

            // We use a conditional statement based on the IsSuccessful property.
            if (result.IsSuccessful)
            {
                Print("Operation successful!")
            }
        }
    }
}

Koleksiyonlar

Koleksiyonlar, belirli bir sınıfa ait bir veya daha fazla nesneyi depolayabilen kapsayıcılar olarak tanımlanır.

Koleksiyonlar tamamen indekslenebilirdir, yani üyelerine köşeli parantez içinde belirli bir integer değeri geçirilerek erişilebilir. Calculate() metodunun, indeksi aracılığıyla erişilen bir çubuğun özelliklerini yazdırdığı aşağıdaki örneği inceleyin.

1
2
3
4
5
public override void Calculate(int index)
{
       var bar = Bars[index];
       Print($"{bar.Open} | {bar.High} | {bar.Low} | {bar.Close}");
}

cTrader uzantıları oluşturun

Aşağıdaki kod parçasında, yalnızca yukarıdaki bölümlerde ele alınan bilgileri kullanarak temel bir işlem robotu oluşturuyoruz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System; 

namespace Spotware.cBots
{
    [Robot(AccessRights = AccessRights.None)]
    public class SuperAwesomeBot : Robot
    {

        /* In the below method, we define the operation(s) that our bot should
        perform when it is launched. */
        protected override void OnStart()
        {
            var result = ExecuteMarketOrder(TradeType.Buy, symbolName, 10000);

            /* We use a conditional statement using the IsSuccessful property of the
            TradeResult object. */
            if (result.IsSuccessful)
            {
                var position = result.Position;
                Print ("Position entry price is {0}", position.EntryPrice);
            } 
        }
    }
}

Senkron ve asenkron işlemler

Daha önce belirtildiği gibi, C# asenkron işlemleri tamamen destekler. Aşağıdaki diyagram, senkron yürütmede işlem faaliyetlerinin nasıl gerçekleştirildiğine dair temel bir örnek tanımlar.

graph TD
    A(Teknik sinyal<br>algılama) ==> B(Piyasa emri<br>yürütme)
    B ==> C(Take Profit/<br>Stop Loss<br>seviyesine<br>ulaşılması)
    C ==> D(Pozisyonu kapatma)
    D ==> A

Senkron yürütmenin önemli bir dezavantajı vardır. Yukarıdaki örnekte, bir piyasa emrini yürütme eylemi tüm sunucu iş parçacıklarını tamamen meşgul eder, bu da işlem robotunuzun bu işlem tamamlanmadan önce başka hiçbir şey yapamayacağı anlamına gelir.

Bu, piyasa olaylarına ve oynaklığa hızlı tepki vermek istediğinizde ideal değildir. İdeal olarak, botunuz çeşitli eylemleri depolayabilmeli veya belirli görevleri beklemeye alarak diğer, daha acil faaliyetlerle meşgul olabilmelidir. Asenkron işlemlerin nasıl gerçekleştirildiğini daha iyi yansıtmak için örneğimizi genişleteceğiz.

graph TD
    A([Teknik sinyal<br>algılama]) ==> B(['Buy' emri<br>verme]) & C([Riskten<br>korunma için<br>'Sell' emri verme]) ==> D([Bir emir<br>Take Profit/<br>Stop Loss<br>seviyesine ulaşır])
    D ==> E([Pozisyonu kapatma])
    E ==> A

Yukarıdaki örnekte, işlem robotumuz pozisyonlarını hedging yapmak için her iki yönde de eş zamanlı olarak emirler verdi. Senkron işlemlerin aksine, bir işlemin tamamlanmasını beklemeden başka bir işleme geçmeye gerek yoktur. Bu, geliştiricilerin verimli ve güvenilir işlem robotları oluşturma fırsatlarını önemli ölçüde genişletir.

Asenkron yürütmenin çoklu iş parçacığından farklı olduğunu unutmayın:

  • Asenkron yürütmede, tüm görevler aynı iş parçacığında başlatılır. Depolandıklarında veya beklemeye alındıklarında, bu iş parçacığını serbest bırakırlar ve yürütmeleri daha sonra devam ettiğinde, iş parçacığı havuzundan seçilen farklı bir iş parçacığında gerçekleşir.
  • Çoklu iş parçacığı kullanıldığında, tüm görevler farklı iş parçacıklarında başlar ve yürütmelerine başlangıç iş parçacıklarında devam ederler. İş parçacığı karıştırma yoktur.

cTrader metotlarınızı asla paralel olarak çağırmaz, bu nedenle çoklu iş parçacığı sorunları hakkında endişelenmenize gerek yoktur.

Image title