Saltar a contenido

Cómo crear un bot de trading en Python

Este artículo y vídeo ofrecen instrucciones paso a paso para crear un robot de trading en Python.

Nota

cTrader es la única plataforma de trading importante con soporte nativo de Python, lo que le permite escribir código en Python y crear bots, indicadores técnicos y herramientas directamente en cTrader Windows o Mac. No se requiere adaptador ni solución compleja.

Crear un robot de trading

En la pestaña cBots de la aplicación Algo, haga clic en el botón Nuevo para comenzar a crear un nuevo bot de trading.

Asigne un nombre al cBot y seleccione Python como lenguaje de programación.

Nota

cTrader proporciona varios algoritmos prefabricados en Python que cubren una amplia gama de estrategias y acciones de trading automatizadas. Estas plantillas de algoritmos ya contienen lógica de trading y parámetros personalizables y están listas para ejecutarse una vez que las guarde y compile.

Seleccione Usar plantilla como método de creación, elija Grid Sample y luego haga clic en Crear.

El cBot Grid implementa una estrategia de trading en cuadrícula donde se colocan múltiples órdenes de compra o venta para un símbolo a intervalos de precio regulares o pasos, lo que resulta en una cuadrícula de posiciones.

Vamos a compilar nuestro cBot para validar su código.

Presione Ctrl+B o haga clic en Compilar.

Presione Cmd+B o haga clic en el icono Compilar.

Añadir un indicador

Incorporemos un indicador a nuestro bot de trading para mejorar su precisión.

El Índice de Fuerza Relativa (RSI) es un indicador popular que señala condiciones de sobrecompra o sobreventa en el mercado. Este indicador puede ayudar a nuestro cBot a evitar abrir nuevas posiciones cuando el mercado está estirado en una dirección.

Integre el RSI en la lógica del robot. Inicialice el indicador con un período predeterminado de 14 y establezca los niveles de sobrecompra y sobreventa en 70 y 30 respectivamente. Utilice los precios de cierre del símbolo para crear el 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)

Añada la lógica para comprobar si las condiciones del RSI permiten una operación antes de abrir una posición. Si el filtro bloquea la operación, registre un mensaje que muestre el valor actual del RSI.

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

Escriba el código que asegure que la posición de la cuadrícula se abra solo si el precio se ha movido lo suficiente y el valor del RSI está dentro de un rango neutral. Utilice el valor del RSI de la última barra cerrada para mayor estabilidad e imprima un mensaje cuando sea bloqueado por el 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)

Ajuste la lógica de cálculo de la distancia en pips entre el precio de mercado actual y el precio de entrada de una posición.

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

Puede copiar el código completo de Python con el indicador RSI integrado a continuación:

 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

Iniciar una instancia

Volvamos a nuestro cBot y construyámoslo. Ahora, haga clic en el icono Iniciar cBot para cualquier instancia, y el bot de operaciones comenzará a ejecutarse.

Alternativamente, puede hacer clic en Añadir instancia, especificar los parámetros de instancia que prefiera, añadir la nueva instancia e iniciarla.

Al añadir y personalizar nuevas instancias, puede ejecutar el cBot simultáneamente en diferentes símbolos, períodos o parámetros.

Ejecutar el bot en otro lugar

Con la sincronización en la nube activada, el cBot aparece automáticamente en todas las aplicaciones de cTrader donde su cTID esté activo. Podemos iniciar el mismo robot de operaciones en la Nube en cualquier aplicación de cTrader, incluyendo cTrader Mobile y Web.

En cTrader Algo, inicie el cBot.

Este artículo ha demostrado cómo crear un robot de operaciones en Python e iniciarlo, permitiéndole automatizar sus estrategias y ejecutar algoritmos en cualquier dispositivo.

Image title