Lewati ke isi

Buat indikator teknikal di cTrader

Artikel ini menguraikan langkah-langkah untuk membuat indikator teknikal kustom, termasuk alat untuk trading algoritmik atau tindakan manual di cTrader.

Di tab Indikator pada aplikasi Algo, klik tombol Baru untuk membuka wizard pembuatan algoritma.

Masukkan nama untuk indikator Anda, lalu pilih bahasa pemrograman antara C# dan Python.

Pilih metode pembuatan dari:

  • Dari awal – indikator baru hanya akan berisi template dasar.

  • Menggunakan template – Anda akan dapat memilih algoritma yang sudah jadi dari daftar template Python# atau C#, yang mencakup berbagai jenis indikator, alat analisis teknikal, dan lainnya.

Catatan

Algoritma yang sudah jadi sudah berisi logika untuk perhitungan dan parameter yang dapat disesuaikan. Indikator seperti ini siap ditampilkan di grafik setelah Anda menyimpan dan membangunnya.

Setelah Anda mengklik Buat, editor kode terbuka dan Anda dapat mulai mengedit kode indikator.

Edit kode

Tergantung pada metode pembuatan Anda, sampel kode indikator harus berisi satu atau lebih elemen berikut:

 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
[Indicator(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SimpleIndicator : Indicator
{
    [Parameter(DefaultValue = "Hello world!")]
    public string Message { get; set; }

    [Output("Main")]
    public IndicatorDataSeries Result { get; set; }

    protected override void Initialize()
    {
    // Called once when the indicator is launched
    // Initialise variables, nested indicators or series

        Print(Message);
    }

    public override void Calculate(int index)
    {
    // Called automatically on each historical bar
    // Also called in real-time on each tick
    // Place the indicator formula and logic here
    }

    // === Custom Methods ===
    // Add helper methods below to structure your indicator logic

}

Atribut Indicator, bersama dengan properti opsionalnya seperti TimeZone dan AccessRights, mendahului deklarasi kelas indikator (SimpleIndicator).

Metode-metode ini disertakan dalam setiap indikator secara default:

  • Metode Initialize() dipanggil sekali ketika indikator Anda dimulai. Biasanya digunakan untuk menyiapkan variabel, indikator bersarang, dan seri yang perlu siap dari awal.
  • Metode Calculate() dipanggil secara otomatis pada setiap bar historis dan secara real-time pada setiap tick baru. Di sinilah Anda menerapkan rumus indikator dan menentukan bagaimana hasil dihitung dan ditampilkan.

Atribut [Output()] menentukan nilai yang dihasilkan indikator Anda dan bagaimana nilai tersebut muncul di grafik. Anda dapat menyesuaikan nama dan gaya setiap output, misalnya dengan mengatur warna garisnya.

Metode Initialize() dan Calculate() membentuk dasar setiap indikator kustom dan tidak boleh dihilangkan. Anda dapat menambahkan metode Anda sendiri untuk memperluas fungsionalitas, sama seperti saat mengkode cBot. Untuk mempelajari lebih lanjut tentang algoritma, mulailah dengan panduan dasar-dasar C# dan jelajahi contoh kode indikator.

Catatan

Referensi mencakup semua kelas, event, metode, variabel, dll. untuk membangun algoritma di cTrader, sementara contoh algoritma lengkap dan template tersedia di repositori GitHub."

Terapkan pengetahuan baru Anda untuk mengedit kode indikator dan menyesuaikannya dengan kebutuhan Anda.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class SimpleIndicator:
    def initialize(self):
        # Called once when the indicator is launched
        # Initialise variables, nested indicators or series
        api.Print(api.Message)

    def calculate(self, index):
        # Called automatically on each historical bar
        # Also called in real-time on each tick
        # Place the indicator formula and logic here
        api.Result[index] = 100 # Example calculation

    # === Custom Methods ===
    # Add helper methods below to structure your indicator logic

Kelas SimpleIndicator mendefinisikan indikator kustom dalam Python.

Metode-metode ini disertakan dalam setiap indikator secara default:

  • Metode initialize(self) dipanggil sekali ketika indikator Anda dimulai. Biasanya digunakan untuk menginisialisasi variabel, indikator bersarang, dan seri yang perlu siap dari awal.
  • Metode calculate(self, index) dipanggil secara otomatis pada setiap bar historis dan secara real-time pada setiap tick baru. Di sinilah Anda menerapkan rumus indikator dan menentukan bagaimana hasil dihitung dan ditampilkan.

Metode initialize(self) dan calculate(self, index) membentuk dasar setiap indikator kustom dan tidak boleh dihilangkan. Anda juga dapat menambahkan metode pembantu Anda sendiri di dalam kelas untuk memperluas fungsionalitas, sama seperti saat mengkode cBot. Untuk mempelajari lebih lanjut tentang algoritma, mulailah dengan dasar-dasar Python dan jelajahi contoh kode indikator.

Terapkan pengetahuan baru Anda untuk mengedit kode indikator dan menyesuaikannya dengan kebutuhan Anda.

Simpan dan build

Simpan kode Anda dengan mengklik tombol Save di bagian atas editor kode atau gunakan pintasan Ctrl+S.

Sebelum Anda dapat menggunakan indikator Anda, Anda perlu memvalidasi kodenya dengan membangun proyek indikator. Klik tombol Build di bagian atas editor kode atau tekan Ctrl+B.

Simpan kode Anda dengan mengklik ikon Save di bagian atas editor kode atau gunakan pintasan Cmd+S.

Sebelum Anda dapat menggunakan indikator Anda, Anda perlu memvalidasi kodenya dengan membangun proyek indikator. Klik ikon Build di bagian atas editor kode atau tekan Cmd+B.

Ketika proses build berhasil, Anda akan melihat pesan konfirmasi di Hasil build. Jika build gagal, ringkasan semua kesalahan yang ditemui akan muncul sebagai gantinya.

Jika ada perubahan pada kode sejak build terakhir, tanda bintang akan muncul di sebelah ikon Build. Dalam hal ini, Anda harus membangun indikator lagi sebelum menambahkan instansinya ke grafik mana pun.

Untuk menggunakan atau menampilkan indikator pada grafik, tambahkan instansi darinya, atau Anda dapat melanjutkan memodifikasi kode indikator seperti yang dijelaskan di bagian-bagian.

Gunakan aritmatika NaN

Indikator melakukan perhitungan untuk menghasilkan visual tertentu, dan penting bahwa kode Anda menangani kasus-kasus pinggiran dan kondisi batas dengan benar selama perhitungan ini.

Pertimbangkan cuplikan berikut dari indikator yang menghasilkan osilator harga yang didetren:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private MovingAverage movingAverage;

protected override void Initialize()
{
    movingAverage = Indicators.SimpleMovingAverage(Source, Periods);
}

public override void Calculate(int index)
{
    Result[index] = Source[index] - movingAverage.Result[index - Periods / 2 - 1];
}

Kode di atas mendefinisikan aturan perhitungan umum tetapi menghilangkan kondisi batas. Misalnya, jika Periods diatur ke 10 dan index berada dalam rentang 0–9, perhitungan akan mengembalikan NaN (Not a Number). Masalah ini terjadi karena indikator tidak dapat menghitung nilai untuk grafik batang dengan indeks negatif.

Untuk mengatasi masalah tersebut, Anda dapat menambahkan kondisi seperti yang ditunjukkan di bawah ini:

1
2
3
4
5
6
7
public override void Calculate(int index)
{
    if (index >= Periods + Periods / 2 + 1)
    {
        Result[index] = Source[index] - movingAverage.Result[index - Periods / 2 - 1];
    }
}

Kode untuk rata-rata bergerak sederhana itu sendiri juga harus memeriksa bahwa index >= Periods. Jika Anda menggunakan indikator bersarang, seperti jenis rata-rata bergerak lainnya, kondisinya akan berbeda untuk memperhitungkan perhitungan tambahan.

Meskipun Anda dapat mendefinisikan kondisi batas secara eksplisit, C# menawarkan cara yang nyaman untuk menghindari masalah ini melalui aritmatika NaN. Secara khusus, tipe data double sepenuhnya mendukung perhitungan NaN. Contohnya:

1
2
3
4
5
double result = double.NaN + 1.4; 
// result will be NaN

bool isNaN = double.IsNaN(result); 
// isNaN will be true

Namun, ketika operand apa pun dalam perhitungan adalah NaN, hasilnya juga akan menjadi NaN. Karena indikator kustom cTrader beroperasi pada tipe DataSeries, jika Anda mencoba mengakses elemen DataSeries dengan indeks negatif, itu akan mengembalikan NaN, dan nilainya tidak akan digambar pada grafik trading. Perilaku ini memungkinkan indikator untuk terus beroperasi tanpa melempar pengecualian. Dalam kebanyakan kasus, Anda dapat dengan aman mengabaikan kondisi batas dan hanya fokus pada logika perhitungan umum.

Tambahkan pemeriksaan eksplisit

Meskipun aritmatika NaN menyederhanakan penanganan kondisi batas, beberapa kasus masih memerlukan pemeriksaan NaN secara eksplisit. Indikator rekursif adalah contoh umum. Indikator rekursif menghitung nilai saat ini berdasarkan nilai yang telah dihitung sebelumnya.

Pertimbangkan implementasi exponential moving average berikut:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public override void Calculate(int index)
{
    var previousValue = Result[index - 1];

    if (double.IsNaN(previousValue))
    {
        Result[index] = Source[index];
    }
    else
    {
        Result[index] = Source[index] * _exp + previousValue * (1 - _exp);
    }
}

Ketika indikator menghitung periode pertama, nilai awal harus secara eksplisit diatur ke tipe non-NaN. Jika tidak, semua perhitungan selanjutnya akan mengembalikan NaN, membuat indikator menjadi tidak berguna.

Dalam kode di atas, hal ini ditangani dengan metode double.IsNaN(previousValue). Operator == tidak dapat digunakan untuk pemeriksaan ini (previousValue == double.NaN) karena setiap perbandingan NaN dengan nilai lain, termasuk dirinya sendiri, selalu menghasilkan false.

Ketika Anda puas dengan kode indikator, build indikator tersebut, lalu gunakan dengan menambahkan instance ke grafik.

Image title