Vai al contenuto

Come creare un robot di trading in Python

Questo articolo e video offrono istruzioni dettagliate per creare un robot di trading in Python.

Nota

cTrader è l'unica piattaforma di trading importante con supporto nativo Python, che ti consente di scrivere codice in Python e creare bot, indicatori tecnici e strumenti direttamente in cTrader Windows o Mac. Nessun adattatore o soluzione complessa richiesta.

Crea un robot di trading

Nella scheda cBot dell'app Algo, clicca sul pulsante Nuovo per iniziare a creare un nuovo robot di trading.

Assegna un nome al cBot e seleziona Python come linguaggio di programmazione.

Nota

cTrader fornisce diversi algoritmi predefiniti in Python che coprono un'ampia gamma di strategie e azioni di trading automatizzate. Questi modelli di algoritmo contengono già logica di trading e parametri personalizzabili e sono pronti per essere eseguiti una volta salvati e compilati.

Seleziona Utilizzando modello come metodo di creazione, scegli Grid Sample, quindi clicca su Crea.

Il Grid cBot implementa una strategia di grid trading in cui più ordini di acquisto o vendita per un simbolo vengono piazzati a intervalli di prezzo regolari o step, risultando in una griglia di posizioni.

Compiliamo il nostro cBot per validare il suo codice.

Premi Ctrl+B o clicca su Build.

Premi Cmd+B o clicca sull'icona Build.

Aggiungi un indicatore

Incorporiamo un indicatore nel nostro robot di trading per migliorarne la precisione.

Il Relative Strength Index (RSI) è un indicatore popolare che segnala condizioni di ipercomprato o ipervenduto nel mercato. Questo indicatore può aiutare il nostro cBot a evitare di aprire nuove posizioni quando il mercato è esteso in una direzione.

Integra RSI nella logica del robot. Inizializza l'indicatore con un periodo predefinito di 14 e imposta i livelli di ipercomprato e ipervenduto rispettivamente a 70 e 30. Utilizza i prezzi di chiusura del simbolo per creare l'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)

Aggiungi la logica per verificare se le condizioni RSI consentono un'operazione prima di aprire una posizione. Se il filtro blocca l'operazione, registra un messaggio che mostra il valore RSI corrente.

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

Scrivi il codice che garantisce che la posizione grid venga aperta solo se il prezzo si è mosso abbastanza e il valore RSI è all'interno di un intervallo neutro. Utilizza il valore RSI dell'ultima barra chiusa per stabilità e stampa un messaggio quando bloccato dal filtro 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)

Regola la logica di calcolo per la distanza in pip tra il prezzo di mercato corrente e il prezzo di entrata di una posizione.

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

Puoi copiare il codice Python completo con l'indicatore RSI integrato qui sotto:

 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

Avviare un'istanza

Torniamo al nostro cBot e compiliamolo. Ora, clicca sull'icona Avvia il cBot per qualsiasi istanza, e il robot di trading inizierà a funzionare.

In alternativa, puoi cliccare su Aggiungi istanza, specificare i parametri dell'istanza preferiti, aggiungere la nuova istanza e avviarla.

Aggiungendo e personalizzando nuove istanze, puoi eseguire il cBot simultaneamente su simboli, periodi o parametri diversi.

Esegui il bot altrove

Con la sincronizzazione cloud abilitata, il cBot appare automaticamente in tutte le applicazioni cTrader in cui il tuo cTID è attivo. Possiamo avviare lo stesso robot di trading in cloud in qualsiasi app cTrader, inclusi cTrader Mobile e Web.

In cTrader Algo, avvia il cBot.

Questo articolo ha dimostrato come creare un robot di trading Python e avviarlo, permettendoti di automatizzare le tue strategie ed eseguire algoritmi su qualsiasi dispositivo.

Image title