Lewati ke isi

Objek grafik dan gambar

Objek grafik (gambar) memungkinkan untuk menggambar garis atau bentuk geometris pada grafik cTrader. Dengan menggunakannya, Anda dapat menggambar pola atau menunjukkan peristiwa tertentu pada grafik berdasarkan data cBot atau indikator Anda.

Objek grafik menggunakan koordinat X dan Y untuk penempatan.

  • Sumbu X mewakili waktu grafik atau indeks bar.
  • Sumbu Y adalah harga simbol.

Semua objek grafik diturunkan dari kelas dasar ChartObject, yang berarti bahwa semuanya mewarisi fitur dasar tertentu.

Contoh kode objek grafik

Menggambar di dalam jendela indikator

Saat membuat objek grafik, Anda tidak terbatas pada grafik simbol utama. Sebenarnya, Anda dapat menggambar objek grafik di dalam jendela apa pun yang berisi output indikator.

Kelas Chart memiliki koleksi IndicatorAreas. Ini berisi semua jendela non-overlay atau terpisah di mana indikator dapat menampilkan outputnya.

Anda juga dapat mengakses area indikator Anda saat ini dengan menggunakan properti IndicatorArea dari kelas Indicator Anda.

 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)
        {
        }
    }
}

Ketika Anda menjalankan instance indikator di atas, Anda akan melihat garis merah di jendela indikator terpisah. Saat membuat grafik di area indikator terpisah, Anda dapat menggunakan semua metode gambar karena baik Chart maupun IndicatorArea mewarisi dari kelas dasar ChartArea.

Teks statis

Alih-alih menggunakan koordinat X dan Y untuk penempatan, teks statis menggunakan perataan horizontal dan vertikal statis. Untuk menampilkan atau menggambar teks statis, gunakan metode DrawStaticText().

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

Jika Anda melampirkan objek grafik ini ke indikator dan menjalankan instance, Anda akan melihat teks berikut di grafik utama.

Image title

Garis vertikal

Gunakan metode DrawVerticalLine() untuk menggambar garis vertikal.

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

Garis horizontal

Gunakan metode DrawHorizontalLine() untuk menggambar garis horizontal.

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);

Garis tren

Garis tren dimulai dari titik tertentu di grafik dan berakhir di titik lain. Garis tren berguna untuk membuat berbagai bentuk atau pola kompleks.

Untuk menggambar garis tren, gunakan metode DrawTrendLine().

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);

Persegi

Gunakan metode DrawRectangle() untuk menggambar persegi.

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);

Segitiga

Gunakan metode DrawTriangle() untuk menggambar segitiga.

 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);

Objek grafik lainnya

Demi singkatnya, kami tidak menyebutkan beberapa objek grafik lainnya dalam cuplikan kode di atas. Objek-objek ini termasuk namun tidak terbatas pada:

  • Elips
  • Ikon
  • Andrews pitchfork
  • Kanal Equidistant
  • Ekspansi Fibonacci
  • Kipas Fibonacci
  • Retraksi Fibonacci

Semua objek ini dapat digambar menggunakan metode Draw...() dengan nama serupa yang menerima parameter serupa.

Risiko-imbalan

Antarmuka ChartRiskReward menyediakan tipe yang memungkinkan Anda untuk membuat dan mengelola objek risiko-imbalan secara terprogram pada grafik.

Kode di bawah ini menunjukkan cara membuat indikator yang menggambar objek risiko-imbalan:

 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)
        {
        }
    }
}

Pengaturan objek utama

Penamaan objek grafik

Setiap kali Anda mencoba menggambar objek grafik, Anda harus menyediakan namanya sebagai argumen untuk metode gambar.

Semua nama objek grafik harus unik. Jika persyaratan ini tidak terpenuhi, Anda berisiko objek grafik menimpa objek grafik dengan nama yang sama tergantung pada waktu eksekusinya. Anda dapat menggunakan nilai indeks bar saat ini atau waktu saat ini untuk menghasilkan nama unik untuk setiap objek.

Mengakses objek grafik

Semua objek grafik terdapat dalam koleksi Objects. Koleksi ini mencakup objek yang digambar oleh pengguna. Akibatnya, koleksi Objects dapat diakses untuk menghapus objek dari grafik atau memodifikasi propertinya.

Contoh di bawah ini mengakses anggota koleksi Objects:

 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)
        {
        }
    }
}

Peristiwa

Objek grafik memiliki beberapa event yang dapat Anda gunakan untuk mengetahui objek apa yang digambar, diperbarui, atau dihapus:

  • ObjectsAdded - dipicu ketika satu atau lebih objek grafik ditambahkan ke grafik.
  • ObjectsRemoved - dipicu ketika satu atau lebih objek grafik dihapus dari grafik.
  • ObjectsUpdated - dipicu ketika satu atau lebih objek grafik diperbarui (salah satu propertinya diubah oleh pengguna atau indikator atau cBot yang aktif).
  • ObjectsSelectionChanged - dipicu ketika satu atau lebih objek grafik dipilih oleh pengguna.
  • ObjectHoverChanged - dipicu ketika kursor mouse melayang di atas objek grafik.

Contoh berikut menggunakan kelima jenis event:

 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)
        {
        }
    }
}

Objek interaktif dan non-interaktif

Saat bekerja dengan objek interaktif, pengguna dapat mengubah propertinya seperti posisi objek, warna, komentar, dll. Semua objek yang digambar pengguna bersifat interaktif secara default.

Catatan

Properti ChartStaticText tidak dapat diubah terlepas dari apakah objek terkaitnya interaktif atau tidak.

Untuk membuat objek menjadi interaktif, atur properti IsInteractive menjadi true seperti yang ditunjukkan di bawah ini:

 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)
        {
        }
    }
}

Semua objek grafik memiliki properti IsInteractive. Nilai defaultnya adalah false.

Jika objek grafik bersifat interaktif, objek tersebut tidak akan dihapus ketika instance indikator atau cBot dihapus atau dihentikan. Sebaliknya, objek non-interaktif dihapus secara otomatis ketika indikator atau cBot berhenti bekerja.

Untuk menghindari kekacauan, pastikan untuk membersihkan objek interaktif setelah instance terkaitnya dihapus dengan menggunakan metode Destroy indikator atau metode OnStop cBot.

Jika objek grafik tidak interaktif, objek tersebut juga akan tidak terlihat dalam daftar dan koleksi objek grafik.

Objek terkunci dan tidak terkunci

Mengunci objek grafik mencegah pengguna memodifikasi atau memperbaruinya. Anda dapat melakukannya melalui kotak Trader (Properti grafik) atau dengan mengatur properti IsLocked menjadi true. Nilai defaultnya adalah false.

Anda dapat menggunakan penguncian untuk membuat objek interaktif tetapi pada saat yang sama mencegah pengguna memperbaruinya. Contoh berikut mengunci objek garis vertikal:

 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)
        {
        }
    }
}

Tampilkan dan sembunyikan

Anda dapat menggambar objek pada grafik dan, selanjutnya, menyembunyikannya. Meskipun objek tersebut masih ada di grafik, objek tersebut akan benar-benar tidak terlihat.

Untuk melakukannya, atur properti IsHidden menjadi true.

 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)
        {
        }
    }
}

Penggunaan sumber daya adalah pertimbangan utama untuk menggunakan fitur ini. Jika ada objek yang sering muncul di grafik (tetapi tidak sepanjang waktu), lebih baik menyembunyikannya daripada menghapus dan menggambar ulang setiap kali dibutuhkan.

Pemilihan objek dan indeks tampilan (ZIndex)

Secara alami, mungkin ada kasus di mana beberapa objek berpotongan satu sama lain pada grafik, membuat pemilihan satu objek tertentu menjadi sulit atau bahkan tidak mungkin. Hanya objek yang digambar terakhir yang dapat dipilih saat Anda mengarahkan kursor mouse ke sekelompok objek grafik yang berpotongan.

Untuk mengubah perilaku ini, Anda dapat menggunakan properti ZIndex. Ini dapat membantu saat mencoba menampilkan pola kompleks objek grafik.

 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)
        {
        }
    }
}

Setelah dilampirkan ke grafik, indikator di atas akan menampilkan garis vertikal merah alih-alih kuning. Karena nilai properti ZIndex dari garis pertama lebih tinggi daripada nilai yang sesuai dari garis kedua, garis pertama mengambil prioritas atas garis kedua (kuning).

Dengan kata lain, properti ZIndex menentukan objek grafik mana yang ditampilkan terlebih dahulu ketika mereka tumpang tindih. Semua objek grafik yang digambar secara otomatis diberi nilai tertentu untuk properti ZIndex.

Mengetahui apakah objek dihapus

Semua objek grafik mewarisi properti IsAlive dari kelas dasar ChartObject. Nilai properti ini adalah true selama objek ada di grafik (terlepas dari apakah objek tersebut terlihat atau tidak terlihat). Nilai diatur menjadi false segera setelah objek dihapus dari grafik.

Jika Anda menyimpan referensi ke objek grafik dan objek ini dihapus oleh pengguna, Anda dapat memeriksa properti IsAlive untuk mengetahui apakah objek masih hidup atau mati.

 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)
        {
        }
    }
}

Jika Anda menjalankan instance indikator ini, klik kanan pada garis merah dan hapus. Log kemudian harus menampilkan pesan "Object reference removed".

Jika Anda menyimpan referensi ke objek grafik (yang mati), kebocoran memori akan terjadi. Selama pengumpulan sampah, objek Anda masih akan dianggap hidup, yang berarti bahwa objek tersebut akan bertahan dalam proses pengumpulan.

Untuk menghindari masalah ini, gunakan event ObjectsRemoved bersama dengan properti IsAlive.

Indeks bar atau waktu

Saat mengkodekan objek grafik, Anda dapat menggunakan waktu grafik atau indeks bar untuk sumbu X.

Menurut pendapat kami, waktu grafik adalah pilihan yang lebih baik. Saat menggunakan indeks bar, Anda tidak dapat merencanakan nilai masa depan (karena indeks yang diperlukan belum ada) dan tidak dapat memperhitungkan ruang antara bar. Namun, indeks bar mungkin lebih mudah digunakan, terutama dalam kasus objek grafik yang relatif sederhana.

Semua metode Chart.Draw memiliki overload yang berbeda untuk indeks bar dan waktu grafik.