Ir para o conteúdo

Operações de negociação do cBot

Neste guia, explicamos em detalhe as principais operações de negociação que pode executar usando um cBot desenvolvido através da API Algo.

Estas são algumas das operações suportadas para cBots:

  • Enviar ordens de mercado.
  • Colocar ordens pendentes.
  • Modificar ordens pendentes e posições abertas.
  • Fechar posições e cancelar ordens.
  • Subscrever eventos de negociação (posições, ordens e atividade relacionada).

Enviar ordens de mercado

Uma ordem de mercado é enviada para o servidor de negociação quando o método ExecuteMarketOrder() é chamado. Depois de criar um novo cBot, pode adicionar este método com várias propriedades definidas da ordem de mercado (símbolo, volume, take profit, stop loss, etc.). O exemplo abaixo coloca uma ordem de mercado quando o cBot é iniciado.

 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)

Dica

No exemplo, vários parâmetros da ordem foram intencionalmente deixados indefinidos "". Verifique as Referências para as assinaturas e ordem de todos os parâmetros de ExecuteMarketOrder().

Ao construir o cBot e adicionar uma instância, verá que uma ordem de mercado com os parâmetros especificados foi executada no início. Os separadores Posições e Registo no painel Observação da Negociação mostram as entradas correspondentes de posição e registo.

Positions

Log

Colocar ordens pendentes

O cTrader suporta três tipos de ordens pendentes, nomeadamente ordens de stop, ordens de limite e ordens de stop-limit. Para colocar ordens pendentes no início, pode substituir a ordem de mercado pelos seguintes fragmentos de código no exemplo anterior do 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)

Dica

Para inspecionar rapidamente os parâmetros de um método, comece a digitar o nome do método e um parêntese de abertura. Verá um pop-up do IntelliSense com informações adicionais.

Image title

Dica

Se clicar num método/parâmetro no cTrader Algo e pressionar F1, o painel de ajuda à direita da janela de código mostrará os resultados de pesquisa correspondentes. Se o cursor de texto permanecer fora da janela de código e pressionar F1, a janela Centro de Ajuda aparecerá para o auxiliar.

Verá os seguintes registos no painel Observação da Negociação após a construção e execução bem-sucedida do cBot.

Orders

Log

Modificar ordens pendentes e posições abertas

Quando as ordens pendentes são colocadas, ficam disponíveis na sua coleção PendingOrders do cBot. Através desta coleção, pode aceder e modificá-las. As ordens pendentes existentes podem ser modificadas ajustando o seu nível de stop loss da seguinte forma.

 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)

O separador Registo do painel Observação da Negociação mostra que as três ordens pendentes foram modificadas com sucesso imediatamente após serem colocadas.

Image title

Depois de os diferentes tipos de ordens serem executados com sucesso, as posições serão abertas para a sua conta. Todas as posições abertas estão disponíveis na coleção Positions do seu cBot. De forma semelhante à modificação das ordens pendentes no exemplo anterior, pode modificar a posição aberta. Como as ordens de mercado são a forma mais rápida de abrir posições, vamos adicionar o método OnBar() com uma ação de modificação de posição ao primeiro cBot deste guia.

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 refletido no registo, a posição aberta foi modificada na primeira barra aberta.

Image title

Fechar posições e cancelar ordens

Pode encontrar um exemplo de cBot abaixo que fecha todas as posições abertas e cancela todas as ordens pendentes na sexta-feira às 11:00 (UTC) chamando o 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

Subscrever eventos de negociação

O cTrader permite que os desenvolvedores de algoritmos subscrevam eventos de negociação e monitorizem a atividade de negociação, independentemente de terem sido iniciados por um cBot ou manualmente. Isto é conseguido ouvindo os eventos disponíveis nas duas coleções demonstradas anteriormente, Positions e PendingOrders.

Existem três eventos disponíveis para posições:

  • Open
  • Modified
  • Closed

Eles são acionados quando abre, modifica e fecha as posições na sua conta, respetivamente.

No fragmento de código abaixo, os três eventos são declarados no método OnStart() e os métodos a serem chamados são atribuídos. Estes criarão automaticamente as assinaturas de código para nós usarmos. Depois, as declarações Print() são adicionadas a cada um dos métodos de evento.

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

Quer seja você ou o cBot a executar os eventos Open, Modified e Closed, o algoritmo irá reagir a eles de cada vez com mensagens impressas, como mostrado no registo abaixo.

Image title

Da mesma forma, pode subscrever eventos relacionados com ordens pendentes. Existem quatro eventos disponíveis para ordens pendentes:

  • Created
  • Modified
  • Filled
  • Cancelled

Os quatro eventos são declarados no método OnStart(), e os manipuladores de eventos são adicionados da seguinte forma.

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

Se subscrito aos eventos relacionados com ordens pendentes, o cBot irá reagir tanto às atividades de negociação manuais como programadas.

Image title

Resumo

Para concluir, o cTrader equipa os desenvolvedores de algoritmos com um impressionante arsenal de operações de negociação que podem ser executadas pelos cBots. Ao aplicá-las habilmente, pode perseguir estratégias de negociação personalizadas e sofisticadas.

Image title