Langkau tajuk talian

Cipta indikator teknikal dalam cTrader

Artikel ini menggariskan langkah-langkah untuk mencipta indikator teknikal tersuai, termasuk alat untuk dagangan algoritma atau tindakan manual dalam cTrader.

Dalam tab Indikator aplikasi Algo, klik butang Baharu untuk membuka wizard penciptaan algoritma.

Masukkan nama untuk indikator anda, kemudian pilih bahasa pengaturcaraan antara C# dan Python.

Pilih kaedah penciptaan daripada:

  • Dari awal – indikator baharu akan mengandungi templat asas sahaja.

  • Menggunakan templat – anda akan dapat memilih algoritma yang telah disediakan daripada senarai templat Python# atau C#, yang merangkumi pelbagai jenis indikator, alat analisis teknikal dan banyak lagi.

Nota

Algoritma yang telah disediakan sudah mengandungi logik untuk pengiraan dan parameter yang boleh disesuaikan. Indikator sedemikian sedia untuk dipaparkan pada carta sebaik sahaja anda menyimpan dan membinanya.

Selepas anda klik Cipta, penyunting kod akan dibuka dan anda boleh mula menyunting kod indikator.

Sunting kod

Bergantung pada kaedah penciptaan anda, sampel kod indikator harus mengandungi 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 sifat pilihan seperti TimeZone dan AccessRights, mendahului pengisytiharan kelas indikator (SimpleIndicator).

Kaedah-kaedah ini disertakan dalam setiap indikator secara lalai:

  • Kaedah Initialize() dipanggil sekali apabila indikator anda bermula. Ia biasanya digunakan untuk menetapkan pemboleh ubah, indikator tersarang dan siri yang perlu disediakan dari awal.
  • Kaedah Calculate() dipanggil secara automatik pada setiap bar sejarah dan dalam masa nyata pada setiap tik baharu. Di sinilah anda melaksanakan formula indikator dan menentukan bagaimana hasil dikira dan dipaparkan.

Atribut [Output()] menentukan nilai yang dihasilkan oleh indikator anda dan bagaimana ia muncul pada carta. Anda boleh menyesuaikan nama dan gaya setiap output, contohnya dengan menetapkan warna garisnya.

Kaedah Initialize() dan Calculate() membentuk asas setiap indikator tersuai dan tidak boleh diabaikan. Anda boleh menambah kaedah anda sendiri untuk memperluaskan fungsi, sama seperti ketika mengekod cBot. Untuk mengetahui lebih lanjut tentang algoritma, mulakan dengan panduan asas C# dan terokai contoh kod indikator.

Nota

Rujukan merangkumi semua kelas, acara, kaedah, pemboleh ubah, dsb. untuk membina algoritma dalam cTrader, manakala contoh algoritma penuh dan templat tersedia dalam repositori GitHub.

Gunakan pengetahuan baharu anda untuk menyunting kod indikator dan menyesuaikannya dengan keperluan 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 menentukan indikator tersuai dalam Python.

Kaedah-kaedah ini disertakan dalam setiap indikator secara lalai:

  • Kaedah initialize(self) dipanggil sekali apabila indikator anda bermula. Ia biasanya digunakan untuk mengawalkan pemboleh ubah, indikator tersarang dan siri yang perlu disediakan dari awal.
  • Kaedah calculate(self, index) dipanggil secara automatik pada setiap bar sejarah dan dalam masa nyata pada setiap tik baharu. Di sinilah anda melaksanakan formula indikator dan menentukan bagaimana hasil dikira dan dipaparkan.

Kaedah initialize(self) dan calculate(self, index) membentuk asas setiap indikator tersuai dan tidak boleh diabaikan. Anda juga boleh menambah kaedah pembantu anda sendiri dalam kelas untuk memperluaskan fungsi, sama seperti ketika mengekod cBot. Untuk mengetahui lebih lanjut tentang algoritma, mulakan dengan asas Python dan terokai contoh kod indikator.

Gunakan pengetahuan baharu anda untuk menyunting kod indikator dan menyesuaikannya dengan keperluan anda.

Simpan dan bina

Simpan kod anda dengan mengklik butang Save di bahagian atas penyunting kod atau gunakan pintasan Ctrl+S.

Sebelum anda boleh menggunakan indikator anda, anda perlu mengesahkan kodnya dengan membina projek indikator. Klik butang Build di bahagian atas penyunting kod atau tekan Ctrl+B.

Simpan kod anda dengan mengklik ikon Save di bahagian atas penyunting kod atau gunakan pintasan Cmd+S.

Sebelum anda boleh menggunakan indikator anda, anda perlu mengesahkan kodnya dengan membina projek indikator. Klik ikon Build di bahagian atas penyunting kod atau tekan Cmd+B.

Apabila pembinaan berjaya, anda akan melihat mesej pengesahan dalam Hasil pembinaan. Jika pembinaan gagal, ringkasan semua ralat yang ditemui akan muncul.

Jika terdapat perubahan pada kod sejak pembinaan terakhir, tanda bintang akan muncul di sebelah ikon Build. Dalam kes ini, anda harus membina indikator sekali lagi sebelum menambah contoh daripadanya ke mana-mana carta.

Untuk menggunakan atau memaparkan indikator pada carta, tambah contoh daripadanya, atau anda boleh terus mengubah suai kod indikator seperti yang dijelaskan dalam bahagian-bahagian.

Gunakan aritmetik NaN

Indikator melakukan pengiraan untuk menghasilkan visual tertentu, dan adalah penting kod anda mengendalikan kes pinggiran dan keadaan sempadan dengan betul semasa pengiraan ini.

Pertimbangkan cebisan kod berikut daripada indikator yang menghasilkan pengayun harga tanpa trend:

 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];
}

Kod di atas menentukan peraturan pengiraan umum tetapi mengabaikan keadaan sempadan. Contohnya, jika Periods ditetapkan kepada 10 dan index berada dalam julat 0–9, pengiraan akan mengembalikan NaN (Bukan Nombor). Isu ini berlaku kerana indikator tidak dapat mengira nilai untuk carta bar dengan indeks negatif.

Untuk menangani masalah ini, anda boleh menambah syarat seperti yang ditunjukkan di bawah:

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];
    }
}

Kod untuk purata bergerak mudah itu sendiri juga mesti memeriksa bahawa index >= Periods. Jika anda menggunakan indikator tersarang, seperti jenis purata bergerak yang lain, syarat akan berbeza untuk mengambil kira pengiraan tambahan.

Walaupun anda boleh menentukan keadaan sempadan secara jelas, C# menawarkan cara mudah untuk mengelakkan isu ini melalui aritmetik NaN. Khususnya, jenis data double menyokong sepenuhnya pengiraan NaN. Sebagai contoh:

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

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

Walau bagaimanapun, apabila mana-mana operan dalam pengiraan adalah NaN, hasilnya juga akan menjadi NaN. Oleh kerana indikator tersuai cTrader beroperasi pada jenis DataSeries, jika anda cuba mengakses elemen DataSeries dengan indeks negatif, ia akan mengembalikan NaN, dan nilai tidak akan dilukis pada carta dagangan. Tingkah laku ini membolehkan indikator terus beroperasi tanpa menghasilkan pengecualian. Dalam kebanyakan kes, anda boleh mengabaikan keadaan sempadan dengan selamat dan hanya fokus pada logik pengiraan umum.

Tambah pemeriksaan jelas

Walaupun aritmetik NaN memudahkan pengendalian keadaan sempadan, sesetengah kes masih memerlukan pemeriksaan NaN yang jelas. Indikator rekursif adalah contoh biasa. Indikator rekursif mengira nilai semasanya berdasarkan nilai yang dikira sebelumnya.

Pertimbangkan pelaksanaan purata bergerak eksponen 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);
    }
}

Apabila indikator mengira tempoh pertama, nilai awal mesti ditetapkan secara jelas kepada jenis bukan NaN. Jika tidak, semua pengiraan seterusnya akan mengembalikan NaN, menjadikan indikator tidak berguna.

Dalam kod di atas, ini dikendalikan dengan kaedah double.IsNaN(previousValue). Operator == tidak boleh digunakan untuk pemeriksaan ini (previousValue == double.NaN) kerana sebarang perbandingan NaN dengan nilai lain, termasuk dirinya sendiri, sentiasa dinilai sebagai false.

Apabila anda berpuas hati dengan kod indikator, bina ia, kemudian gunakannya dengan menambah contoh pada carta.

Image title