Ana içeriğe geç

Grafik nesneleri ve çizimler

Grafik nesneleri (çizimler), cTrader grafiklerinde çizgiler veya geometrik şekiller çizmeye olanak tanır. Bunları kullanarak, cBot veya gösterge verilerinize göre grafiklerde formasyonlar çizebilir veya belirli olayları gösterebilirsiniz.

Grafik nesneleri konumlandırma için X ve Y koordinatlarını kullanır.

  • X ekseni grafik zamanını veya çubuk endekslerini temsil eder.
  • Y ekseni sembol fiyatıdır.

Tüm grafik nesneleri ChartObject temel sınıfından türetilmiştir, yani hepsi belirli temel özellikleri miras alır.

Grafik nesneleri kod örnekleri

Gösterge pencerelerinin içine çizim yap

Grafik nesneleri oluştururken ana sembol grafiğiyle sınırlı değilsiniz. Aslında, gösterge çıktılarını içeren herhangi bir pencerenin içine grafik nesneleri çizebilirsiniz.

Chart sınıfı IndicatorAreas koleksiyonuna sahiptir. Göstergelerin çıktılarını görüntüleyebileceği tüm çakışmayan veya ayrı pencereleri içerir.

Ayrıca Indicator sınıfınızın IndicatorArea özelliğini kullanarak mevcut gösterge alanınıza erişebilirsiniz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = IndicatorArea.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);
        }

        public override void Calculate(int index)
        {
        }
    }
}

Yukarıdaki göstergenin bir örneğini çalıştırdığınızda, ayrı bir gösterge penceresinde kırmızı bir çizgi görmelisiniz. Ayrı gösterge alanlarında grafikler oluştururken, hem Chart hem de IndicatorArea ChartArea temel sınıfından miras aldığı için tüm çizim yöntemlerini kullanabilirsiniz.

Statik metin

Konumlandırma için X ve Y koordinatlarını kullanmak yerine, statik metin statik yatay ve dikey hizalamaları kullanır. Statik bir metin göstermek veya çizmek için DrawStaticText() yöntemini kullanın.

1
var staticText = Chart.DrawStaticText("static", "This is the text that will be shown", VerticalAlignment.Center, HorizontalAlignment.Center, Color.Red);

Bu grafik nesnesini bir göstergeye ekler ve bir örnek çalıştırırsanız, ana grafikte aşağıdaki metni göreceksiniz.

Image title

Dikey çizgi

Dikey çizgi çizmek için DrawVerticalLine() yöntemini kullanın.

1
2
3
var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);
// Or
var verticalLine = Chart.DrawVerticalLine("line", Bars.OpenTimes[Chart.LastVisibleBarIndex], Color.Red);

Yatay çizgi

Yatay çizgi çizmek için DrawHorizontalLine() yöntemini kullanın.

1
2
3
/* We use the maximum of the high prices
of the last ten bars as the Y coordinate. */ 
var horizontalLine = Chart.DrawHorizontalLine("line", Bars.HighPrices.Maximum(10), Color.Red);

Trend çizgisi

Bir trend çizgisi, grafikte belirli bir noktadan başlar ve başka bir noktada biter. Trend çizgileri, farklı şekiller veya karmaşık formasyonlar oluşturmak için kullanışlıdır.

Bir trend çizgisi çizmek için DrawTrendLine() yöntemini kullanın.

1
2
3
4
5
6
7
/* We draw a line from the low price
 of the first visible bar to the high price
 of the last visible bar on the chart. */
var trendLine = Chart.DrawTrendLine("line", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

// Alternatively, consider the following.
var trendLine = Chart.DrawTrendLine("line", Bars.OpenTimes[Chart.FirstVisibleBarIndex], Bars.LowPrices[Chart.FirstVisibleBarIndex], Bars.OpenTimes[Chart.LastVisibleBarIndex], Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

Dikdörtgen

Dikdörtgen çizmek için DrawRectangle() yöntemini kullanın.

1
2
3
4
5
6
7
var rectangle = Chart.DrawRectangle("rectangle", Chart.FirstVisibleBarIndex + 1, Bars.LowPrices[Chart.FirstVisibleBarIndex + 1], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

/* We fill the rectangle with a transparent color.
By using its current color, we only change the alpha
channel. */
rectangle.IsFilled = true;
rectangle.Color = Color.FromArgb(80, rectangle.Color);

Üçgen

Üçgen çizmek için DrawTriangle() yöntemini kullanın.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var middleX = Chart.FirstVisibleBarIndex + (Chart.LastVisibleBarIndex - Chart.FirstVisibleBarIndex) / 2;
var middleY = Bars.LowPrices[Chart.FirstVisibleBarIndex] + (Bars.HighPrices[Chart.LastVisibleBarIndex] - Bars.LowPrices[Chart.FirstVisibleBarIndex]) / 2;

var triangle = Chart.DrawTriangle("triangle", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], middleX, middleY, Chart.LastVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], Color.Red);

// We fill the triangle with a transparent color
// by using it's current color, we change only the alpha channel

/* We fill the triangle with a transparent color.
By using its current color, we only change the alpha
channel. */
triangle.IsFilled = true;
triangle.Color = Color.FromArgb(80, triangle.Color);

Diğer grafik nesneleri

Kısa olması amacıyla, yukarıdaki kod parçacıklarında diğer bazı grafik nesnelerinden bahsetmedik. Bu nesneler aşağıdakileri içerir ancak bunlarla sınırlı değildir:

  • Oval
  • Simge
  • Andrews Pitchfork
  • Eşit Mesafeli Kanal
  • Fibonacci Genişlemesi
  • Fibonacci Yelpazesi
  • Fibonacci Geri Çekilme Seviyesi

Bu nesnelerin tümü, benzer parametreleri kabul eden benzer adlandırılmış Draw...() yöntemleri kullanılarak çizilebilir.

Risk-getiri

ChartRiskReward arayüzü, grafiklerde risk-getiri nesnelerini programlı olarak oluşturmanızı ve yönetmenizi sağlayan türler sağlar.

Aşağıdaki kod, bir risk-getiri nesnesi çizen bir göstergeyi nasıl oluşturacağınızı 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
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class SimpleRiskReward : Indicator
    {
        protected override void Initialize()
        {
            var type = new ChartRiskRewardFixedRiskType(
                ChartRiskRewardAmountType.BalancePercentage, 
                1                                            
            );
            var tradeType = TradeType.Buy;
            var orderType = OrderType.Market;

            var entryPrice = Chart.Bars.LastBar.Close;
            var time1 = Chart.LastVisibleBarIndex - 20; 
            var time2 = Chart.LastVisibleBarIndex;      

            var rr = Chart.DrawRiskReward(
                "SimpleRR",     
                time1,           
                time2,            
                entryPrice,       
                orderType,        
                tradeType,        
                type              
            );

            rr.IsInteractive = true;

            rr.RiskColor = Color.Yellow;
            rr.RiskLineStyle = LineStyle.DotsRare;
            rr.RiskThickness = 3;

            rr.RewardColor = Color.Blue;
            rr.RewardLineStyle = LineStyle.LinesDots;
            rr.RewardThickness = 2;

            PrintRRInfo(rr);
        }

        private void PrintRRInfo(ChartRiskReward rr)
        {
            Print($"Name: {rr.Name} | Type: {rr.Type.GetType().Name} | Order Type: {rr.OrderType} | Trade Type: {rr.TradeType} | Time 1: {rr.Time1:o} | Time 2: {rr.Time2:o} | Entry: {rr.EntryPrice} | SL: {rr.StopLossPrice} | TP: {rr.TakeProfitPrice} | RR: {rr.RiskRewardRatio} | Volume: {rr.VolumeInUnits}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Temel nesne ayarları

Grafik nesnelerini adlandırma

Bir grafik nesnesi çizmeye çalıştığınızda, çizim yöntemi için adını bir argüman olarak sağlamanız gerekir.

Tüm grafik nesnesi adları benzersiz olmalıdır. Bu gereksinim karşılanmazsa, yürütme sürelerine bağlı olarak grafik nesnelerinin aynı ada sahip grafik nesnelerini geçersiz kılması riskiyle karşı karşıya kalırsınız. Her nesne için benzersiz adlar oluşturmak üzere mevcut çubuk dizin değerini veya mevcut zamanı kullanabilirsiniz.

Grafik nesnelerine erişme

Tüm grafik nesneleri Objects koleksiyonunda yer alır. Bu koleksiyon, kullanıcı tarafından çizilen nesneleri içerir. Sonuç olarak, nesneleri grafiklerden kaldırmak veya özelliklerini değiştirmek için Objects koleksiyonuna erişilebilir.

Aşağıdaki örnek, Objects koleksiyonunun üyelerine erişir:

 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
58
59
60
using cAlgo.API;
using System.Linq;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            foreach (var chartObject in Chart.Objects)
            {
                /* If the object is a trend line 
                we change its Y1/2 properties */
                if (chartObject is ChartTrendLine trendLine)
                {
                    trendLine.Y1 = Chart.BottomY;
                    trendLine.Y2 = Chart.TopY;
                }
            }

            /* Here, we filter all objects of the 'ChartRectangle'
            type. */
            var rectangles = from chartObject in Chart.Objects
                             where chartObject is ChartRectangle
                             select chartObject as ChartRectangle;

            /* We select only the chart objects with a name that
            begins with "MyObjects". */
            var myObjects = from chartObject in Chart.Objects
                            where chartObject.Name.StartsWith("MyObjects", System.StringComparison.OrdinalIgnoreCase)
                            select chartObject;

            /* We select only interactive objects. If an object
            is interactive, it will not be removed when the 
            indicator is removed or reloaded. */
            var interactiveObjects = from chartObject in Chart.Objects
                                     where chartObject.IsInteractive
                                     select chartObject;

            /* We remove all objects with a name 
            that begins with "ToRemove". */
            var chartObjectsCopy = Chart.Objects.ToArray();

            foreach (var chartObject in chartObjectsCopy)
            {
                if (chartObject.Name.StartsWith("ToRemove", System.StringComparison.OrdinalIgnoreCase))
                {
                    /* Chart 'RemoveObject' gets the object name
                    as a parameter. */
                    Chart.RemoveObject(chartObject.Name);
                }

            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

Olaylar

Grafik nesnelerinin, hangi nesnelerin çizildiğini, güncellendiğini veya kaldırıldığını bilmek için kullanabileceğiniz çeşitli olayları vardır:

  • ObjectsAdded - bir veya daha fazla grafik nesnesi bir grafiğe eklendiğinde tetiklenir.
  • ObjectsRemoved - bir veya daha fazla grafik nesnesi bir grafikten kaldırıldığında tetiklenir.
  • ObjectsUpdated - bir veya daha fazla grafik nesnesi güncellendiğinde tetiklenir (özelliklerinden biri kullanıcı veya aktif gösterge ya da cBot tarafından değiştirildiğinde).
  • ObjectsSelectionChanged - bir veya daha fazla grafik nesnesi kullanıcı tarafından seçildiğinde tetiklenir.
  • ObjectHoverChanged - fare imleci bir grafik nesnesinin üzerine geldiğinde tetiklenir.

Aşağıdaki örnek, beş olay türünün tümünü 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
28
29
30
31
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            Chart.ObjectsAdded += Chart_ObjectsAdded;
            Chart.ObjectsRemoved += Chart_ObjectsRemoved;
            Chart.ObjectsUpdated += Chart_ObjectsUpdated;
            Chart.ObjectsSelectionChanged += Chart_ObjectsSelectionChanged;
            Chart.ObjectHoverChanged += Chart_ObjectHoverChanged;
        }

        private void Chart_ObjectHoverChanged(ChartObjectHoverChangedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsSelectionChanged(ChartObjectsSelectionChangedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsUpdated(ChartObjectsUpdatedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsAdded(ChartObjectsAddedEventArgs obj) => throw new System.NotImplementedException();

        public override void Calculate(int index)
        {
        }
    }
}

Etkileşimli ve etkileşimli olmayan nesneler

Etkileşimli nesnelerle çalışırken, kullanıcılar nesne konumu, rengi, yorumu vb. gibi özelliklerini değiştirebilir. Kullanıcı tarafından çizilen tüm nesneler varsayılan olarak etkileşimlidir.

Not

ChartStaticText özelliği, ilgili nesnesinin etkileşimli olup olmadığına bakılmaksızın değiştirilemez.

Bir nesneyi etkileşimli hale getirmek için, aşağıda gösterildiği gibi IsInteractive özelliğini true olarak ayarlayın:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsInteractive = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

Tüm grafik nesneleri IsInteractive özelliğine sahiptir. Varsayılan değeri false'tur.

Bir grafik nesnesi etkileşimliyse, bir gösterge veya cBot örneği kaldırıldığında veya durdurulduğunda kaldırılmaz. Aksine, etkileşimli olmayan nesneler bir gösterge veya cBot çalışmayı durdurduğunda otomatik olarak kaldırılır.

Dağınıklığı önlemek için, ilgili örnekleri kaldırıldıktan sonra etkileşimli nesneleri gösterge Destroy veya cBot OnStop yöntemlerini kullanarak temizlediğinizden emin olun.

Bir grafik nesnesi etkileşimli değilse, grafik nesnelerinin listelerinde ve koleksiyonlarında da görünmez olacaktır.

Kilitli ve kilitsiz nesneler

Bir grafik nesnesini kilitlemek, kullanıcının onu değiştirmesini veya güncellemesini engeller. Bunu Trader (Grafik özellikleri) kutusu aracılığıyla veya IsLocked özelliğini true olarak ayarlayarak yapabilirsiniz. Varsayılan değeri false'tur.

Bir nesneyi etkileşimli hale getirmek için kilitlemeyi kullanabilir, ancak aynı zamanda kullanıcının onu güncellemesini engelleyebilirsiniz. Aşağıdaki örnek, dikey bir çizgi nesnesini kilitler:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsLocked = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

Göster ve gizle

Bir nesneyi grafiğe çizebilir ve ardından gizleyebilirsiniz. Nesne grafikte hala mevcut olsa da, tamamen görünmez olacaktır.

Bunu yapmak için, IsHidden özelliğini true olarak ayarlayın.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsHidden = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

Kaynak kullanımı, bu özelliği kullanmak için birincil husustur. Grafikte sık sık (ancak her zaman değil) görünmesi gereken bir nesne varsa, her ihtiyaç duyulduğunda kaldırıp yeniden çizmek yerine gizlemek daha iyidir.

Nesne seçimi ve görünüm dizini (ZIndex)

Doğal olarak, bir grafikte birden fazla nesnenin birbiriyle kesiştiği, belirli bir nesneyi seçmeyi zor veya tamamen imkansız hale getiren durumlar olabilir. Fare imlecinizi kesişen grafik nesneleri grubunun üzerine getirdiğinizde yalnızca en son çizilen nesne seçilebilir olacaktır.

Bu davranışı değiştirmek için ZIndex özelliğini kullanabilirsiniz. Grafik nesnelerinin karmaşık formasyonlarını görüntülemeye çalışırken faydalı olabilir.

 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
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var firstVerticalLine = Chart.DrawVerticalLine("line1", Chart.LastVisibleBarIndex, Color.Red);

            firstVerticalLine.IsInteractive = true;

            var secondVerticalLine = Chart.DrawVerticalLine("line2", Chart.LastVisibleBarIndex, Color.Yellow);

            secondVerticalLine.IsInteractive = true;

            firstVerticalLine.ZIndex = secondVerticalLine.ZIndex + 1;
        }

        public override void Calculate(int index)
        {
        }
    }
}

Bir grafiğe eklendiğinde, yukarıdaki gösterge sarı yerine kırmızı dikey bir çizgi gösterecektir. İlk çizginin ZIndex özelliğinin değeri ikinci çizginin karşılık gelen değerinden yüksek olduğu için, ikinci (sarı) çizgiye göre önceliklidir.

Başka bir deyişle, ZIndex özelliği, çakıştıklarında hangi grafik nesnelerinin önce görüntüleneceğini belirler. Çizilen tüm grafik nesnelerine ZIndex özelliği için otomatik olarak belirli bir değer atanır.

Bir nesnenin kaldırılıp kaldırılmadığını öğrenin

Tüm grafik nesneleri, ChartObject temel sınıfından IsAlive özelliğini miras alır. Bu özelliğin değeri, bir nesne grafikte mevcut olduğu sürece (görünür veya görünmez olmasına bakılmaksızın) true'dur. Bir nesne grafikten kaldırılır kaldırılmaz değer false olarak ayarlanır.

Bir grafik nesnesine referans kaydederseniz ve bu nesne kullanıcı tarafından kaldırılırsa, bir nesnenin canlı mı yoksa ölü mü olduğunu kontrol etmek için IsAlive özelliğini kontrol edebilirsiniz.

 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
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        private ChartVerticalLine _verticalLine;

        protected override void Initialize()
        {
            _verticalLine = Chart.DrawVerticalLine("line1", Chart.LastVisibleBarIndex, Color.Red);
            _verticalLine.IsInteractive = true;

            Chart.ObjectsRemoved += Chart_ObjectsRemoved;

            Print(_verticalLine.IsAlive);
        }

        private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj)
        {
            Print(_verticalLine.IsAlive);

            /* If the object is removed, we should rid of its
            reference. Otherwise, it will remain in memory. */
            if (_verticalLine.IsAlive is false)
            {
                _verticalLine = null;

                Print("Object reference removed");
            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

Bu göstergenin bir örneğini çalıştırırsanız, kırmızı çizgiye sağ tıklayın ve kaldırın. Günlük daha sonra "Object reference removed" mesajını çıkarmalıdır.

(Ölü) bir grafik nesnesine referans tutarsanız, bir bellek sızıntısı meydana gelir. Çöp toplama sırasında, nesneniz hala canlı kabul edilecek, bu da toplama sürecinden sağ çıkacağı anlamına gelir.

Bu sorunu önlemek için, ObjectsRemoved olayını IsAlive özelliğiyle birlikte kullanın.

Çubuk dizini veya zaman

Grafik nesnelerini kodlarken, X ekseni için grafik zamanını veya çubuk dizinini kullanabilirsiniz.

Bizim görüşümüze göre, grafik zamanı daha iyi bir seçenektir. Çubuk dizinlerini kullanırken, gelecek değerler için plan yapamazsınız (çünkü gerekli dizinler henüz mevcut değildir) ve çubuklar arasındaki boşlukları hesaba katamazsınız. Ancak, çubuk dizinleri, özellikle nispeten basit grafik nesneleri durumunda kullanımı daha kolay olabilir.

Tüm Chart.Draw yöntemleri, çubuk dizinleri ve grafik zamanı için farklı aşırı yüklemelere sahiptir.