Langkau tajuk talian

Cara mencipta bot dagangan dalam Python

Artikel dan video ini menawarkan arahan langkah demi langkah untuk mencipta robot dagangan dalam Python.

Nota

cTrader adalah satu-satunya platform dagangan utama dengan sokongan Python natif, membolehkan anda menulis kod dalam Python dan membina bot, indikator teknikal dan alat secara langsung dalam cTrader Windows atau Mac. Tiada penyesuai atau penyelesaian kompleks diperlukan.

Cipta robot dagangan

Dalam tab cBots aplikasi Algo, klik butang Baharu untuk mula mencipta bot dagangan baharu.

Beri nama kepada cBot dan pilih Python sebagai bahasa pengaturcaraan.

Nota

cTrader menyediakan beberapa algoritma yang telah disediakan dalam Python yang merangkumi pelbagai strategi dan tindakan dagangan automatik. Templat algoritma ini sudah mengandungi logik dagangan dan parameter yang boleh disesuaikan dan sedia untuk dijalankan sebaik sahaja anda menyimpan dan membinanya.

Pilih Menggunakan templat sebagai kaedah penciptaan, pilih Grid Sample, kemudian klik Cipta.

Grid cBot melaksanakan strategi dagangan grid di mana pelbagai pesanan beli atau jual untuk simbol diletakkan pada selang harga atau langkah yang tetap, menghasilkan grid posisi.

Mari kita bina cBot kita untuk mengesahkan kodnya.

Tekan Ctrl+B atau klik Bina.

Tekan Cmd+B atau klik ikon Bina.

Tambah indikator

Mari kita gabungkan indikator ke dalam bot dagangan kita untuk meningkatkan ketepatannya.

Relative Strength Index (RSI) adalah indikator popular yang menandakan keadaan terlebih beli atau terlebih jual dalam pasaran. Indikator ini boleh membantu cBot kita mengelakkan pembukaan posisi baharu apabila pasaran terlalu melampau dalam satu arah.

Integrasikan RSI ke dalam logik robot. Mulakan indikator dengan tempoh lalai 14 dan tetapkan tahap terlebih beli dan terlebih jual masing-masing kepada 70 dan 30. Gunakan harga penutupan simbol untuk mencipta RSI.

1
2
3
4
self.rsi_period = getattr(api, "RsiPeriod", 14)
self.rsi_overbought = getattr(api, "RsiOverbought", 70)
self.rsi_oversold = getattr(api, "RsiOversold", 30)
self.rsi = api.Indicators.RelativeStrengthIndex(api.Bars.ClosePrices, self.rsi_period)

Tambah logik untuk memeriksa sama ada keadaan RSI membenarkan dagangan sebelum membuka posisi. Jika penapis menghalang dagangan, log mesej yang menunjukkan nilai RSI semasa.

1
2
3
4
5
6
if len(self.get_grid_positions()) == 0:
    # self.open_position()
    if self.passes_rsi_filter():
        self.open_position()
    else:
        api.Print("RSI filter blocked initial entry (RSI={:.2f})".format(self.get_rsi_value()))

Tulis kod yang memastikan bahawa posisi grid dibuka hanya jika harga telah bergerak cukup dan nilai RSI berada dalam julat neutral. Gunakan nilai RSI bar terakhir yang ditutup untuk kestabilan dan cetak mesej apabila dihalang oleh penapis RSI.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
if distance >= api.StepPips:
    # self.open_position()
    if self.passes_rsi_filter():
        self.open_position()
    else:
        api.Print("RSI filter: no new entry (RSI={:.2f}, range {}-{})"
                    .format(self.get_rsi_value(), self.rsi_oversold, self.rsi_overbought))

def get_rsi_value(self):
    # Use the last CLOSED bar for stability
    return self.rsi.Result.Last(1)

def passes_rsi_filter(self):
    r = self.get_rsi_value()
    return (r > self.rsi_oversold) and (r < self.rsi_overbought)

Sesuaikan logik pengiraan untuk jarak dalam pip antara harga pasaran semasa dan harga entri posisi.

1
2
3
4
5
6
7
def get_distance_in_pips(self, position):
    # return (position.EntryPrice - api.Symbol.Ask if position.TradeType == TradeType.Buy else api.Symbol.Bid - position.EntryPrice) / api.Symbol.PipSize
    if position.TradeType == TradeType.Buy:
        diff = position.EntryPrice - api.Symbol.Ask
    else:
        diff = api.Symbol.Bid - position.EntryPrice
    return diff / api.Symbol.PipSize

Anda boleh menyalin kod Python penuh dengan indikator RSI yang diintegrasikan di bawah:

 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class SupercBot():
    def on_start(self):
        self.volumeInUnits = api.Symbol.QuantityToVolumeInUnits(api.VolumeInLots)
        self.enoughMoney = True

        self.rsi_period = getattr(api, "RsiPeriod", 14)
        self.rsi_overbought = getattr(api, "RsiOverbought", 70)
        self.rsi_oversold = getattr(api, "RsiOversold", 30)
        self.rsi = api.Indicators.RelativeStrengthIndex(api.Bars.ClosePrices, self.rsi_period)

        if len(self.get_grid_positions()) == 0:
            if self.passes_rsi_filter():
                self.open_position()
            else:
                api.Print("RSI filter blocked initial entry (RSI={:.2f})".format(self.get_rsi_value()))

    def on_tick(self):
        grid_positions = self.get_grid_positions()
        net_profit_sum = sum([p.NetProfit for p in grid_positions])
        if net_profit_sum >= api.TargetProfit:
            api.Print("Target profit is reached. Closing all grid positions")
            self.close_grid_positions()
            api.Print("All grid positions are closed. Stopping cBot")
            api.Stop()

        if len(grid_positions) > 0 and self.enoughMoney == True:
            position_with_highest_pips = sorted(grid_positions, key=lambda pos: pos.Pips, reverse=True)[0]
            distance = self.get_distance_in_pips(position_with_highest_pips)          
            if distance >= api.StepPips:
                if self.passes_rsi_filter():
                    self.open_position()
                else:
                    api.Print("RSI filter: no new entry (RSI={:.2f}, range {}-{})"
                              .format(self.get_rsi_value(), self.rsi_oversold, self.rsi_overbought))

    def get_rsi_value(self):
        # Use the last CLOSED bar for stability
        return self.rsi.Result.Last(1)

    def passes_rsi_filter(self):
        r = self.get_rsi_value()
        return (r > self.rsi_oversold) and (r < self.rsi_overbought)

    def get_grid_positions(self):
        return [pos for pos in api.Positions if pos.SymbolName == api.SymbolName and pos.TradeType == api.TradeType]

    def open_position(self):
        result = api.ExecuteMarketOrder(api.TradeType, api.SymbolName, self.volumeInUnits, "Grid")
        if result.Error == ErrorCode.NoMoney:
            self.enoughMoney = False
            api.Print("Not enough money to open additional positions")

    def close_grid_positions(self):
        for position in self.get_grid_positions():
            position.Close()

        if len(self.get_grid_positions()) > 0:
            self.close_grid_positions()

    def get_distance_in_pips(self, position):
        if position.TradeType == TradeType.Buy:
            diff = position.EntryPrice - api.Symbol.Ask
        else:
            diff = api.Symbol.Bid - position.EntryPrice
        return diff / api.Symbol.PipSize

Mulakan tika

Mari kembali ke cBot kita dan binanya. Sekarang, klik ikon Mulakan cBot untuk mana-mana tika, dan bot dagangan akan mula berjalan.

Sebagai alternatif, anda boleh klik Tambah tika, tentukan parameter tika pilihan anda, tambah tika baharu dan mulakannya.

Dengan menambah dan menyesuaikan tika baharu, anda boleh menjalankan cBot secara serentak pada simbol, tempoh atau parameter yang berbeza.

Jalankan bot di tempat lain

Dengan penyegerakan awan diaktifkan, cBot muncul secara automatik dalam semua aplikasi cTrader di mana cTID anda aktif. Kita boleh memulakan robot dagangan yang sama dalam Awan dalam mana-mana aplikasi cTrader, termasuk cTrader Mobile dan Web.

Dalam cTrader Algo, mulakan cBot.

Artikel ini telah menunjukkan cara mencipta robot dagangan Python dan memulakannya, membolehkan anda mengautomasikan strategi anda dan menjalankan algo pada mana-mana peranti.

Image title