Saltar a contenido

Operaciones de trading del cBot

En esta guía, explicamos en detalle las operaciones de trading clave que puede ejecutar utilizando un cBot desarrollado a través de la API de Algo.

Estas son algunas de las operaciones admitidas para cBots:

  • Enviar órdenes de mercado.
  • Colocar órdenes pendientes.
  • Modificar órdenes pendientes y posiciones abiertas.
  • Cerrar posiciones y cancelar órdenes.
  • Suscribirse a eventos de trading (posiciones, órdenes y actividad relacionada).

Enviar órdenes de mercado

Se envía una orden de mercado al servidor de trading cuando se llama al método ExecuteMarketOrder(). Después de crear un nuevo cBot, puede agregar este método con varias propiedades definidas de la orden de mercado (símbolo, volumen, take profit, stop loss, etc.). El ejemplo siguiente coloca una orden de mercado cuando se inicia el cBot.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
        }       
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import clr

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *

class TradeOperations():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000, "", 10, 10, "", False)

Consejo

En el ejemplo, varios parámetros de la orden se dejaron intencionalmente sin definir "". Consulte Referencias para las firmas y el orden de todos los parámetros de ExecuteMarketOrder().

Al construir el cBot y agregar una instancia, verá que se ejecutó una orden de mercado con los parámetros especificados al inicio. Las pestañas Posiciones y Registro en el panel Visualización de operaciones muestran las entradas correspondientes de posición y registro.

Positions

Log

Colocar órdenes pendientes

cTrader admite tres tipos de órdenes pendientes, a saber, órdenes de stop, órdenes limitadas y órdenes de stop limitadas. Para colocar órdenes pendientes al inicio, puede reemplazar la orden de mercado con los siguientes fragmentos de código en el ejemplo anterior de cBot.

1
2
3
PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);
1
2
3
api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask - (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
api.PlaceStopLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), 2, "", 10, 10, None, "", False)

Consejo

Para inspeccionar rápidamente los parámetros de un método, comience a escribir el nombre del método y un paréntesis de apertura. Verá una ventana emergente de IntelliSense con información adicional.

Image title

Consejo

Si hace clic en un método/parámetro en cTrader Algo y presiona F1, el panel de ayuda a la derecha de la ventana de código mostrará los resultados de búsqueda coincidentes. Si el cursor de texto permanece fuera de la ventana de código y presiona F1, aparecerá la ventana del Centro de ayuda para asistirle.

Verá los siguientes registros en el panel Visualización de operaciones después de construir y ejecutar con éxito el cBot.

Orders

Log

Modificar órdenes pendientes y posiciones abiertas

Cuando se colocan las órdenes pendientes, quedan disponibles en la colección PendingOrders de su cBot. A través de esta colección, puede acceder a ellas y modificarlas. Las órdenes pendientes existentes se pueden modificar ajustando su nivel de stop loss de la siguiente manera.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
protected override void OnStart()
{
    PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);

    foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
    {
        order.ModifyStopLossPips(20);
    }
}     
1
2
3
4
5
6
7
8
def on_start(self):
    api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
    api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask - (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
    api.PlaceStopLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), 2, "", 10, 10, None, "", False)

    for order in api.PendingOrders:
        if order.SymbolName == api.SymbolName:
            order.ModifyStopLossPips(20)

La pestaña Registro del panel Visualización de operaciones muestra que las tres órdenes pendientes se modificaron con éxito inmediatamente después de ser colocadas.

Image title

Después de que los diferentes tipos de órdenes se ejecuten con éxito, se abrirán posiciones para su cuenta. Todas las posiciones abiertas están disponibles en la colección Positions de su cBot. De manera similar a modificar las órdenes pendientes en el ejemplo anterior, puede modificar la posición abierta. Dado que las órdenes de mercado son la forma más rápida de abrir posiciones, agreguemos el método OnBar() con una acción de modificación de posición al primer cBot de esta guía.

1
2
3
4
5
6
7
protected override void OnBar()
{
    foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
    {
        position.ModifyTakeProfitPips(20);
    }
}
1
2
3
4
def on_bar(self):
    for position in api.Positions:
        if position.SymbolName == api.SymbolName:
            position.ModifyTakeProfitPips(20)

Como se refleja en el registro, la posición abierta se modificó en la primera barra abierta.

Image title

Cerrar posiciones y cancelar órdenes

Puede encontrar un ejemplo de cBot a continuación que cierra todas las posiciones abiertas y cancela todas las órdenes pendientes el viernes a las 11:00 (UTC) llamando al método OnTick().

 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
namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
            PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
        }  

        protected override void OnTick()
        {
            if(Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 11)
            {
                foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
                {
                    position.Close();    
                }

                foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
                {
                    order.Cancel();
                }
            }
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from robot_wrapper import *

class TradeOperations():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000, "", 10, 10, "", False)
        api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)

    def on_tick(self):
        # Friday == 5 (Sunday=0)
        if api.Server.Time.DayOfWeek == 5 and api.Server.Time.Hour >= 11:
            for position in api.Positions:
                if position.SymbolName == api.SymbolName:
                    position.Close()
            for order in api.PendingOrders:
                if order.SymbolName == api.SymbolName:
                    order.Cancel()

Image title

Suscribirse a eventos de trading

cTrader permite a los desarrolladores de algoritmos suscribirse a eventos de trading y monitorear la actividad de trading, sin importar si estos han sido iniciados por un cBot o manualmente. Se logra escuchando eventos disponibles en las dos colecciones demostradas anteriormente, Positions y PendingOrders.

Hay tres eventos disponibles para posiciones:

  • Open
  • Modified
  • Closed

Se activan cuando abre, modifica y cierra las posiciones en su cuenta, respectivamente.

En el siguiente fragmento de código, los tres eventos se declaran en el método OnStart() y se asignan los métodos a llamar. Estos crearán automáticamente las firmas de código para que las usemos. Posteriormente, se agregan declaraciones Print() a cada uno de los métodos de eventos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
protected override void OnStart()
{
    Positions.Opened += Positions_Opened;
    Positions.Modified += Positions_Modified;
    Positions.Closed += Positions_Closed;                    
}  

private void Positions_Opened(PositionOpenedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was opened");
}

private void Positions_Modified(PositionModifiedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was modified");
}

private void Positions_Closed(PositionClosedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was closed");
}   
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def on_start(self):
    api.Positions.Opened += self.positions_opened
    api.Positions.Modified += self.positions_modified
    api.Positions.Closed += self.positions_closed

def positions_opened(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was opened")

def positions_modified(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was modified")

def positions_closed(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was closed")

Ya sea que usted o el cBot realicen los eventos Open, Modified y Closed, el algoritmo los alcanzará cada vez con mensajes impresos como se muestra en el registro a continuación.

Image title

De manera similar, puede suscribirse a eventos relacionados con órdenes pendientes. Hay cuatro eventos disponibles para órdenes pendientes:

  • Created
  • Modified
  • Filled
  • Cancelled

Los cuatro eventos se declaran en el método OnStart(), y los manejadores de eventos se agregan de la siguiente manera.

 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
protected override void OnStart()
{
    PendingOrders.Created += PendingOrders_Created;
    PendingOrders.Modified += PendingOrders_Modified;
    PendingOrders.Filled += PendingOrders_Filled;
    PendingOrders.Cancelled += PendingOrders_Cancelled;
}

private void PendingOrders_Created(PendingOrderCreatedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was created");
}

private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was modified");
}

private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was filled");
}

private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was cancelled");
}       
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def on_start(self):
    api.PendingOrders.Created += self.pending_orders_created
    api.PendingOrders.Modified += self.pending_orders_modified
    api.PendingOrders.Filled += self.pending_orders_filled
    api.PendingOrders.Cancelled += self.pending_orders_cancelled

def pending_orders_created(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was created")

def pending_orders_modified(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was modified")

def pending_orders_filled(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was filled")

def pending_orders_cancelled(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was cancelled")

Si se suscribe a los eventos relacionados con órdenes pendientes, el cBot reaccionará tanto a las actividades de trading manuales como programadas.

Image title

Resumen

Para concluir, cTrader equipa a los desarrolladores de algoritmos con un impresionante arsenal de operaciones de trading que pueden ser ejecutadas por cBots. Al aplicarlas hábilmente, puede perseguir estrategias de trading personalizadas y sofisticadas.

Image title