Ana içeriğe geç

Gösterge kodu örnekleri

Bu sayfa, manuel veya algoritmik işlem yapma için kullanılan teknik göstergeler oluşturmaya yönelik çeşitli Python ve C# kod örnekleri sunar.

Gösterge örnek depoları

Çeşitli gösterge türleri ve teknik analiz araçları için hazır şablonlar dahil olmak üzere kapsamlı gösterge kodu örnekleri, GitHub'daki ayrı Python ve C# depolarında mevcuttur.

Basit göstergeler

High Minus Low göstergesi, mevcut çubuğun yüksek ve düşük fiyatları arasındaki farkı hesaplar ve bunu bir çıktı serisinde görüntüler. Seri, her çubuktaki sonuç değerlerini birbirine bağlayan bir çizgi olarak grafikte çizilir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, ScalePrecision = 5)]
public class HighMinusLow : Indicator
{
    [Output("Main", LineColor = "Orange")]
    public IndicatorDataSeries Result { get; set; }

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

Not

Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

1
2
3
4
5
6
7
from System import Action

class HighMinusLow():
    def calculate(self, index):
        # In Python you have to declare parameters and outputs in your algo C# file like C# algos
        # So Result here is already declared in C# file of this indicator and here we can use it
        api.Result[index] = api.Bars.HighPrices[index] - api.Bars.LowPrices[index]

[Indicator...] bildirimi, aşağıdaki gibi tanımlanan çeşitli parametreler içerir:

  • IsOverlay - çizginin grafikte bindirme göstergesi olarak mı yoksa ayrı bir kullanıcı arayüzü panelinde mi görüntüleneceğini tanımlayan bir boolean.
  • TimeZone - gösterge verilerinin ve sunucu zamanının saat dilimini belirten bir TimeZones sınıf alanı.
  • AccessRights - göstergenize ayrılan erişim haklarını belirleyen bir AccessRights sınıf alanı.
  • ScalePrecision - gösterge çıktısının ölçek hassasiyetini ayarlayan bir int.

Daha önce gösterge kodunu düzenlerken öğrendiğiniz gibi, bir özelliği gösterge çıktısı olarak işaretlemek için Output özniteliği bildirilir. Bu özellik, diğer sınıflar tarafından referans alınabilmesi için public olmalıdır.

Gösterge çıktısı her zaman, bir dizi gibi indekslenebilen bir çift listesi olan IndicatorDataSeries veri türünde olmalıdır. Bu nedenle, Result listesindeki her [index]'teki değer, Calculate yönteminde aşağıdaki gibi atanabilir.

1
2
3
4
public override void Calculate(int index)
{
   Result[index] = Bars.HighPrices[index] - Bars.LowPrices[index];
}
1
2
def calculate(self, index):
    api.Result[index] = api.Bars.HighPrices[index] - api.Bars.LowPrices[index]

Parametreli göstergeler

Çoğu durumda, göstergelerin çıktısı kullanıcı girişine bağlı olarak değişebilir. Göstergeler için özelleştirilebilir parametrelerin ayarlanma şekli, cBot'lar için yapıldığına benzer.

Aşağıdaki Simple Moving Average göstergesi, bir fiyat kaynağını ve bir dönemi özelleştirilebilir parametreler olarak kabul edecek şekilde tasarlanmıştır. Bu tür parametrelerin (bu özel örnekte Source ve Periods) öncesinde Parameter özniteliği bulunmalıdır.

Daha önce bahsedilen [Indicator()] ve [Output()] özniteliklerine benzer şekilde, [Parameter()] özniteliği, kullanıcı girişine uygulanan belirli özellikleri tanımlayabilir.

1
[Parameter("MA Periods", DefaultValue = 14, MinValue = 1, MaxValue = 20)]

Not

Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

Yukarıda, aşağıdaki özellikleri belirtiyoruz:

  • Bu parametreyi cTrader kullanıcı arayüzünde belirtmek için görüntülenen ad ("MA Periods").
  • Parametrenin varsayılan değeri; bir örneği özelleştirirken kullanıcı tarafından değiştirilebilir (DefaultValue = 14)
  • Minimum ve maksimum parametre değerleri (MinValue = 1, MaxValue = 20)

Aşağıdaki kod parçasında, özelleştirilebilir parametrelerin gösterge koduna nasıl entegre edilebileceğini gösteriyoruz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[Indicator(IsOverlay = false, ScalePrecision = 5)]
public class SimpleMovingAverage : Indicator
{
    [Parameter("Price")]
    public DataSeries Source { get; set; }

    [Parameter("MA Type", DefaultValue = MovingAverageType.Exponential)]
    public MovingAverageType MaType { get; set; }

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

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

    [Output("Main", LineColor = "Red")]
    public IndicatorDataSeries Result { get; set; }

    public override void Calculate(int index)
    {
        double sum = 0;

        for (var i = index - Periods + 1; i <= index; i++)
        {
            sum += Source[i];
        }
        Result[index] = sum / Periods;
    }
}

Not

Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

1
2
3
4
5
6
7
8
class SimpleMovingAverage():
    def calculate(self, index):
        sum = 0
        # Periods, Source and Result are declared in the C# file
        for i in range(index - api.Periods + 1, index):
            sum += api.Source[i]

        api.Result[index] = sum / api.Periods

İç içe göstergeler

İç içe göstergeler, değeri başka göstergeler tarafından gerçekleştirilen hesaplamaların sonuçlarına bağlı olan göstergeler olarak tanımlanır. DeMark 9 göstergesi gibi belirli türde uzantılar yazarken faydalıdırlar. Aşağıdaki örnek kodu inceleyin:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[Indicator(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SampleDeMarker : Indicator
{
    [Parameter(DefaultValue = 14)]
    public int Periods { get; set; }

    [Output("DMark", Color = Colors.Turquoise)]
    public IndicatorDataSeries DMark { get; set; }

    private IndicatorDataSeries deMin;
    private IndicatorDataSeries deMax;
    private MovingAverage deMinMA;
    private MovingAverage deMaxMA;

    protected override void Initialize()
    {
        deMin = CreateDataSeries();
        deMax = CreateDataSeries();
        deMinMA = Indicators.MovingAverage(deMin, Periods, MovingAverageType.Simple);
        deMaxMA = Indicators.MovingAverage(deMax, Periods, MovingAverageType.Simple);
    }

    public override void Calculate(int index)
    {
        deMin[index] = Math.Max(Bars.LowPrices[index - 1] - Bars.LowPrices[index], 0);
        deMax[index] = Math.Max(Bars.HighPrices[index] - Bars.HighPrices[index - 1], 0);

        var min = deMinMA.Result[index];
        var max = deMaxMA.Result[index];

        DMark[index] = max / (min + max);
    }
}

Not

Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class SampleDeMarker():
    def initialize(self):
        self.deMin = api.CreateDataSeries()
        self.deMax = api.CreateDataSeries()
        # Periods is declared in the C# file
        self.deMinMA = api.Indicators.MovingAverage(self.deMin, api.Periods, MovingAverageType.Simple)
        self.deMaxMA = api.Indicators.MovingAverage(self.deMax, api.Periods, MovingAverageType.Simple)

    def calculate(self, index):
        self.deMin[index] = max(api.Bars.LowPrices[index - 1] - api.Bars.LowPrices[index], 0)
        self.deMax[index] = max(api.Bars.HighPrices[index] - api.Bars.HighPrices[index - 1], 0)

        minValue = self.deMinMA.Result[index]
        maxValue = self.deMaxMA.Result[index]

        # DMark Output is declared in the C# file
        api.DMark[index] = maxValue / (minValue + maxValue)

Yukarıdaki örnekte, deMinMA ve deMaxMA, DeMarker göstergemizin değerini hesaplamak için kullanılan iki değişkendir.

İç içe göstergeler Initialize() yönteminde tanımlanmalıdır. Örneğin, deMinMA, deMin serisinin Simple Moving Average'ı olarak tanımlanır.

1
deMinMA = Indicators.MovingAverage(deMin, Periods, MovingAverageType.Simple);
1
self.deMinMA = api.Indicators.MovingAverage(self.deMin, api.Periods, MovingAverageType.Simple)

deMin ise, Calculate() yönteminde son iki düşük fiyat değerinin maksimumu olarak tanımlanır.

1
deMin[index] = Math.Max(Bars.LowPrices[index - 1] - Bars.LowPrices[index], 0);
1
self.deMin[index] = max(api.Bars.LowPrices[index - 1] - api.Bars.LowPrices[index], 0)

İç içe göstergelerle çalışmayı basitleştirmek için IntelliSense, kod düzenleyiciye Indicators yazıp ardından bir nokta koyduğunuzda tüm yerleşik göstergelerin listesini otomatik olarak doldurur. Bu listeden belirli bir göstergeyi seçtiğinizde, ilgili tüm giriş parametrelerini de gösterecektir.

Image title

Tembel yükleme

cTrader Algo, referans göstergeleri kullandığınızda tembel yükleme kullanır. Referans gösterge tarafından sağlanan değerler, kodunuz onları aktif olarak kullanmaya başlayana kadar hesaplanmaz.

Bir referans göstergenin Outputs verilerine erişirseniz, cTrader gösterge verilerini geçmiş ve gelecek çubuklarda Calculate() yöntemini çağırarak yüklemeye başlayacaktır. Diğer durumlarda, referans gösterge boşta kalacak ve bu nedenle herhangi bir sistem kaynağı tüketmeyecektir.

Bu aynı zamanda, göstergenizin herhangi bir Output'u yoksa veya genel özelliklerinden herhangi birine erişmeye çalışırsanız, söz konusu özelliğin varsayılan değerini alacağınız anlamına gelir. Bu sorunu çözmek için, özel göstergenizin Calculate() yöntemini mevcut göstergenin Calculate() yönteminden çağırın.

Osilatörler ve seviyeler özniteliği

Osilatörler terimi, belirli bir sabit değişken etrafında salınım yapan tüm göstergeleri kapsar.

Osilatörler oluştururken, önce o sabit değerde yatay veya "seviye" çizgisi çizmek faydalıdır; gösterge daha sonra bu çizgi etrafında salınım yapacaktır. Çoğu durumda, sabit değer sıfıra eşittir.

Aşağıdaki örnekte, bir momentum osilatörü tanımlıyoruz. Genellikle 100 değeri etrafında salınım yapar. Bu değere, gösterge özniteliklerinden önce bildirilen Levels özniteliğini kullanarak bir seviye çizgisi ekliyoruz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Levels(100)]
[Indicator()]
public class MomentumOscillator : Indicator
{
    [Parameter()]
    public DataSeries Source { get; set; }

    [Parameter(DefaultValue = 14, MinValue = 1)]
    public int Periods { get; set; }

    [Output("Main", LineColor = "Green")]
    public IndicatorDataSeries Result { get; set; }

    public override void Calculate(int index)
    {
        Result[index] = 100 * Source[index] / Source[index - Periods];
    }
}

Not

Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

1
2
3
4
class MomentumOscillator():
    def calculate(self, index):
        # Result, Source, and Periods are declared in the C# file
        api.Result[index] = 100 * api.Source[index] / api.Source[index - api.Periods]

Levels özniteliğinin yalnızca gösterge grafiğin üzerine bindirilmemişse kullanılabileceğini unutmayın, yani IsOverlay özelliği true olarak ayarlanmamışsa. Varsayılan olarak, IsOverlay değeri false'tur. Bu öznitelik kodunuzdan çıkarılırsa, Levels düzgün çalışmalıdır.

Birden fazla "seviye" çizgisi oluşturmanız gerekiyorsa, aşağıda gösterildiği gibi parantez içine virgülle ayrılmış bir değer listesi ekleyin.

1
[Levels(0, 50, 100)] 
1
[Levels(50.5, 50.75)] 
1
[Levels(0.001, 0.002)] 

Python Göstergelerinde Seviyeler

Python'da Seviyeleri, C# göstergelerinde olduğu gibi gösterge C# dosyanızda bildirirsiniz.

IsLastBar özelliği

Bazı durumlarda, işlem grafiğindeki yalnızca son çubuk için hesaplanması gereken bir gösterge oluşturmak isteyebilirsiniz. Bunu basitleştirmek gerekirse, IsLastBar özelliği, Calculate() yönteminin indeks parametresinin son çubuğa ait olup olmadığını kontrol etmek için kullanılabilir.

Aşağıdaki gösterge UTC zamanına dayanmaktadır; ancak, son açılış zamanını New York ve Tokyo'da görüntüleyebilir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
public class TimeInDifferentParts : Indicator
{
    public override void Calculate(int index)
    {
        if (IsLastBar)
            DisplayTime(index);
    }

    protected void DisplayTime(int index)
    {
        var nyDateTime = Bars.OpenTimes[index].AddHours(-5);
        var tokyoDateTime = Bars.OpenTimes[index].AddHours(7);

        var nyTime = nyDateTime.ToShortTimeString();
        var tokyoTime = tokyoDateTime.ToShortTimeString();

        Chart.DrawStaticText("Title", "Last Bar OpenTime \n NY " + nyTime + "\n" + "Tokyo " + tokyoTime, VerticalAlignment.Top, HorizontalAlignment.Left, Color.Lime);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class TimeInDifferentParts():
    def calculate(self, index):
        if api.IsLastBar:
            self.display_time(index)

    def display_time(self, index):
        nyDateTime = api.Bars.OpenTimes[index].AddHours(-5)
        tokyoDateTime = api.Bars.OpenTimes[index].AddHours(7)

        nyTime = nyDateTime.ToShortTimeString()
        tokyoTime = tokyoDateTime.ToShortTimeString()

        api.Chart.DrawStaticText("Title", f"Last Bar OpenTime\nNY {nyTime}\nTokyo {tokyoTime}", VerticalAlignment.Top, HorizontalAlignment.Left, Color.Lime)

Göstergeleri birleştirme

cTrader, birden fazla göstergeyi aynı panelde veya aynı grafik içinde birleştirmeye izin verir.

Aşağıdaki gösterge, Aroon, RSI ve Directional Movement System göstergelerini tek bir yerde birleştirir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, ScalePrecision = 5)]
public class Aroon_RSI_DMS : Indicator
{
    private Aroon aroon;
    private RelativeStrengthIndex rsi;
    private DirectionalMovementSystem dms;

    [Parameter()]
    public DataSeries Source { get; set; }

    [Parameter(DefaultValue = 14)]
    public int Periods { get; set; }

    [Output("Aroon Up", LineColor = "LightSkyBlue")]
    public IndicatorDataSeries AroonUp { get; set; }

    [Output("Aroon Down", LineColor = "Red")]
    public IndicatorDataSeries AroonDn { get; set; }

    [Output("Rsi", LineColor = "Green")]
    public IndicatorDataSeries Rsi { get; set; }

    [Output("DI Plus", LineColor = "DarkGreen")]
    public IndicatorDataSeries DmsDIPlus { get; set; }

    [Output("DI Minus", LineColor = "DarkRed")]
    public IndicatorDataSeries DmsDIMinus { get; set; }

    [Output("ADX", LineColor = "Blue")]
    public IndicatorDataSeries DmsADX { get; set; }

    protected override void Initialize()
    {
        // Initialize and create nested indicators
        aroon = Indicators.Aroon(Periods);
        rsi = Indicators.RelativeStrengthIndex(Source, Periods);
        dms = Indicators.DirectionalMovementSystem(Periods);
    }

    public override void Calculate(int index)
    {
        AroonUp[index] = aroon.Up[index];
        AroonDn[index] = aroon.Down[index];

        Rsi[index] = rsi.Result[index];

        DmsADX[index] = dms.ADX[index];
        DmsDIMinus[index] = dms.DIMinus[index];
        DmsDIPlus[index] = dms.DIPlus[index];
    }
}

Not

Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Aroon_RSI_DMS():
    def initialize(self):
        # Initialize and create nested indicators
        # Periods and Source parameters are declared in the C# file
        self.aroon = api.Indicators.Aroon(Periods)
        self.rsi = api.Indicators.RelativeStrengthIndex(Source, Periods)
        self.dms = api.Indicators.DirectionalMovementSystem(Periods)

    def calculate(self, index):
        # AroonUp, AroonDn, Rsi, DmsADX, DmsDIMinus, and DmsDIPlus
        # outputs are declared in the C# file
        api.AroonUp[index] = self.aroon.Up[index]
        api.AroonDn[index] = self.aroon.Down[index]

        api.Rsi[index] = self.rsi.Result[index]

        api.DmsADX[index] = self.dms.ADX[index]
        api.DmsDIMinus[index] = self.dms.DIMinus[index]
        api.DmsDIPlus[index] = self.dms.DIPlus[index]

Çoklu zaman dilimleri

  • Çoklu zaman dilimleri kullanma

    Aşağıdaki örnek, farklı zaman dilimlerinde bir Moving Average göstergesini gösterir.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiTF_MA : Indicator
    {
        [Parameter(DefaultValue = 50)]
        public int Period { get; set; }
    
        [Output("MA", LineColor = "Yellow")]
        public IndicatorDataSeries MA { get; set; }
    
        [Output("MA5", LineColor = "Orange")]
        public IndicatorDataSeries MA5 { get; set; }
    
        [Output("MA10", LineColor = "Red")]
        public IndicatorDataSeries MA10 { get; set; }
    
        private Bars bars5;
        private Bars bars10;
    
        private MovingAverage ma;
        private MovingAverage ma5;
        private MovingAverage ma10;
    
        protected override void Initialize()
        {
            bars5 = MarketData.GetBars(TimeFrame.Minute5);
            bars10 = MarketData.GetBars(TimeFrame.Minute10);
    
            ma = Indicators.MovingAverage(Bars.ClosePrices, Period, MovingAverageType.Triangular);
            ma5 = Indicators.MovingAverage(bars5.ClosePrices, Period, MovingAverageType.Triangular);
            ma10 = Indicators.MovingAverage(bars10.ClosePrices, Period, MovingAverageType.Triangular);
        }
    
        public override void Calculate(int index)
        {
            MA[index] = ma.Result[index];
    
            var index5 = bars5.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            if (index5 != -1)
                MA5[index] = ma5.Result[index5];
    
            var index10 = bars10.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
    
            if (index10 != -1)
                MA10[index] = ma10.Result[index10];
        }
    }
    

    Not

    Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class MultiTF_MA():
        def initialize(self):
            self.bars5 = api.MarketData.GetBars(TimeFrame.Minute5)
            self.bars10 = api.MarketData.GetBars(TimeFrame.Minute10)
    
            # Period is declared as a parameter in the C# file 
            # We use indicator time frame bars for this moving average
            self.ma = Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, MovingAverageType.Triangular)
    
            # We use other two time frame bars that we created previously
            # for these two moving averages
            self.ma5 = Indicators.MovingAverage(self.bars5.ClosePrices, api.Period, MovingAverageType.Triangular)
            self.ma10 = Indicators.MovingAverage(self.bars10.ClosePrices, api.Period, MovingAverageType.Triangular)
    
        def calculate(self, index):
            # MA, MA5, and MA10 are outputs we declared in the C# file
            api.MA[index] = self.ma.Result[index]
    
            index5 = self.bars5.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index])
    
            if index5 > -1:
                api.MA5[index] = self.ma5.Result[index5]
    
            index10 = self.bars10.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index])
    
            if index10 > -1:
                api.MA10[index] = self.ma10.Result[index10]
    
  • Çoklu zaman dilimleri ve semboller kullanma

    Aşağıdaki örnek, çoklu zaman dilimlerinde ve sembollerde Moving Average göstergesini gösterir.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiSymbolMA : Indicator
    {
        private MovingAverage ma1, ma2, ma3;
        private Bars bars2, bars3;
        private Symbol symbol2, symbol3;
    
        [Parameter(DefaultValue = "EURCHF")]
        public string Symbol2 { get; set; }
    
        [Parameter(DefaultValue = "EURCAD")]
        public string Symbol3 { get; set; }
    
        [Parameter(DefaultValue = 14)]
        public int Period { get; set; }
    
        [Parameter(DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }
    
        [Output("MA Symbol 1", LineColor = "Magenta")]
        public IndicatorDataSeries Result1 { get; set; }
    
        [Output("MA Symbol 2", LineColor = "Magenta")]
        public IndicatorDataSeries Result2 { get; set; }
    
        [Output("MA Symbol 3", LineColor = "Magenta")]
        public IndicatorDataSeries Result3 { get; set; }
    
        protected override void Initialize()
        {
            symbol2 = Symbols.GetSymbol(Symbol2);
            symbol3 = Symbols.GetSymbol(Symbol3);
    
            bars2 = MarketData.GetBars(TimeFrame, symbol2.Name);
            bars3 = MarketData.GetBars(TimeFrame, symbol3.Name);
    
            ma1 = Indicators.MovingAverage(Bars.ClosePrices, Period, MaType);
            ma2 = Indicators.MovingAverage(bars2.ClosePrices, Period, MaType);
            ma3 = Indicators.MovingAverage(bars3.ClosePrices, Period, MaType);
        }
    
        public override void Calculate(int index)
        {
            ShowOutput(Symbol, Result1, ma1, Bars, index);
            ShowOutput(symbol2, Result2, ma2, bars2, index);
            ShowOutput(symbol3, Result3, ma3, bars3, index);
        }
    
        private void ShowOutput(Symbol symbol, IndicatorDataSeries result, MovingAverage movingAverage, Bars bars, int index)
        {
            var index2 = bars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            result[index] = movingAverage.Result[index2];
    
            string text = string.Format("{0} {1}", symbol.Name, Math.Round(result[index], symbol.Digits));
            Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow);
        }
    }
    

    Not

    Python göstergeleri, .cs dosyalarında bildirilen özelleştirilebilir parametreler kullanır.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class MultiSymbolMA():
        def initialize(self):
            # Symbol2 and Symbol3 are declared as parameters in the C# file
            self.symbol2 = api.Symbols.GetSymbol(api.Symbol2)
            self.symbol3 = api.Symbols.GetSymbol(api.Symbol3)
    
            self.bars2 = api.MarketData.GetBars(api.TimeFrame, self.symbol2.Name)
            self.bars3 = api.MarketData.GetBars(api.TimeFrame, self.symbol3.Name)
    
            self.ma1 = api.Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, api.MaType)
            self.ma2 = api.Indicators.MovingAverage(self.bars2.ClosePrices, api.Period, api.MaType)
            self.ma3 = api.Indicators.MovingAverage(self.bars3.ClosePrices, api.Period, api.MaType)
    
        def calculate(self, index):
            # Result1, Result2, and Result3 are declared as outputs in the C# file
            self.show_output(api.Symbol, api.Result1, self.ma1, api.Bars, index)
            self.show_output(self.symbol2, api.Result2, self.ma2, self.bars2, index)
            self.show_output(self.symbol3, api.Result3, self.ma3, self.bars3, index)
    
        def show_output(self, symbol, result, movingAverage, bars, index):
            index2 = bars.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index])
    
            result[index] = movingAverage.Result[index2]
    
            text = f"{symbol.Name} {round(result[index], symbol.Digits)}"
    
            api.Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow)
    

Image title