Ir para o conteúdo

Acesso à rede

Este guia define como pode criar algoritmos que podem aceder à Internet. Abaixo está um resumo de um minuto desta funcionalidade da API.

Acesso à rede em um minuto!

  • As suas soluções de algoritmos podem obter informações de websites de notícias de negociação ou APIs web orientadas para Forex. Utilize esta funcionalidade para garantir que os seus cBots, plugins e indicadores reagem a eventos e informações prementes da vida real.
  • Ao utilizar métodos nos espaços de nomes System.Text.Json e System.Text.Json.Serialization, pode rapidamente serializar ou desserializar objetos de e para ficheiros JSON, permitindo que os cBots consumam facilmente endpoints e processem informações valiosas.
  • O protocolo WebSocket permite receber dados de um serviço em tempo real em vez de ter de fazer um pedido HTTP de cada vez. Utilize websocket para integrar suavemente os seus algoritmos com recursos web. A classe WebSocketClient contém todos os métodos e parâmetros necessários para utilizar conexões websocket.
  • Ao utilizar websocket, pode enviar e receber strings e dados brutos em bytes. Trabalhe com diferentes estruturas de dados e serialize-as em bytes para utilizar serviços valiosos de terceiros.
  • AccessRights.None é suficiente para funções de rede.

HTTP

A nova interface Http contém vários métodos que, quando implementados, devem permitir que cBots e outros tipos de algoritmos acedam à Internet. Para uma ilustração, veja o seguinte:

  • HttpResponse Http.Get(string uri). Executa um pedido GET para o URI especificado na string uri passada e retorna um objeto HttpsResponse contendo os resultados deste pedido.

A classe HttpsRequest permite executar pedidos mais complexos, incluindo pedidos POST. Para executar estes pedidos, defina a propriedade HttpsRequest.Method para um dos valores do enum HttpMethod, como HttpMethod.Put ou HttpMethod.Patch.

Por sua vez, a propriedade HttpsRequest.Uri contém o URI para o qual um pedido é enviado, enquanto a propriedade HttpsRequest.Body pode ser utilizada para definir o corpo do pedido. Veja abaixo um exemplo de como pode utilizar um objeto HttpsRequest.

  • HttpResponse Http.Send(HttpRequest request). Executa um pedido para o URI especificado como o valor da propriedade request.Uri do objeto HttpsRequest passado para este método. Depois, retorna um objeto HttpsResponse contendo os resultados deste pedido. O tipo de pedido é definido como o valor da propriedade equest.Method.

Acesso à rede em testes de verificação e otimização

Todos os métodos na interface Http funcionam como pretendido nos testes de verificação e otimização. Note que, ao aceder a um recurso web nos testes de verificação ou otimização, será solicitada a versão atualizada deste recurso em vez de uma histórica.

Criar cBots de exemplo

Realizar um pedido GET

Vamos criar um cBot simples que realiza as seguintes ações:

  • Envia um pedido GET e acede a um ficheiro JSON através da API em https://forexApiExample.com/v1/exchangerate (note que esta API é completamente fictícia).
  • Se a resposta GET for bem-sucedida, o cBot desserializa o corpo da resposta num objeto de uma classe SymbolPrice personalizada (criámos esta classe para fins de demonstração).
  • Coloca uma ordem de limite de venda para um símbolo a um preço ligeiramente superior ao preço especificado na API.

Note que o cBot é totalmente fictício. Embora o código seja compilado, não realizará nenhuma ação significativa.

Como serializar ou desserializar strings de ficheiros JSON

O código do nosso cBot inclui duas declarações using importantes, nomeadamente System.Text.Json e System.Text.Json.Serialization. Estes espaços de nomes contêm vários métodos que permitem serializar e desserializar facilmente strings de ficheiros JSON, como JsonSerializer.Deserialize<T>().

Aqui está o código do nosso cBot de exemplo:

 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
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;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NetworkAccessTest : Robot
    {

        protected override void OnStart()
        {

            var responseToGet = Http.Get("https://forexApiExample.com/v1/exchangerate");

            if (responseToGet.IsSuccessful)
            {
                var tradedSymbol = JsonSerializer.Deserialize<SymbolPrice>(responseToGet.Body);
                var result = PlaceLimitOrder(TradeType.Sell, tradedSymbol.SymbolName, 10000, tradedSymbol.ConversionRate + 0.15);

            }
        }
    }

    public class SymbolPrice
    {
        public string SymbolName { get; set; }
        public double ConversionRate { get; set; }
    }
}

Se este cBot fosse aceder a uma API real, tê-lo-ia feito com sucesso.

Realizar um pedido POST

Também podemos criar um cBot mais avançado que alcança os seguintes objetivos:

  • Envia um pedido POST para a mesma API fictícia em https://anotherForexApiExample.com/commodities/v1/getaccesstoken. Isto é feito para obter um token de acesso para esta API.
  • Armazena o token do corpo da resposta na variável token.
  • Realiza um pedido GET para a mesma API com o valor da variável token passado como um parâmetro de consulta no URI (https://anotherForexApiExample.com/commodities/v1/getprices).
  • Utilizando a serialização JSON (discutida acima), coloca uma ordem de stop de compra a um preço ligeiramente inferior ao preço recebido da API.

Mais uma vez, note que este cBot não realizará nenhuma ação significativa quando compilado. Existe apenas para fins de exemplo.

 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
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;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NetworkAccessTestTwo : Robot
    {

        protected override void OnStart()
        {
            var uriForAccessToken = new Uri("https://anotherForexApiExample.com/commodities/v1/getaccesstoken");

            var postRequest = new HttpRequest(uriForAccessToken);

            postRequest.Method = HttpMethod.Post;

            var responseToPost = Http.Send(postRequest);

            var token = responseToPost.Body;

            var response = Http.Get($"https://anotherForexApiExample.com/commodities/v1/getprices?token={token}");

            if (response.IsSuccessful)
            {
                var tradedSymbol = JsonSerializer.Deserialize<SymbolPrice>(response.Body);

                var result = PlaceStopOrder(TradeType.Buy, tradedSymbol.SymbolName, 10000, tradedSymbol.ConversionRate - 0.15);

            }
        }
    }

    public class SymbolPrice
    {
        public string SymbolName { get; set; }
        public double ConversionRate { get; set; }
    }
}

Cliente WebSocket

A API Algo permite que qualquer pessoa utilize vários serviços e recursos da web usando uma conexão websocket. Em comparação com o protocolo HTTP, que é utilizado na funcionalidade de acesso à rede, o protocolo WebSocket é mais rápido e permite receber dados em tempo real.

Utilizar o cliente WebSocket

Utilizar o cliente WebSocket é simples:

  1. Escolha um serviço que exponha um endpoint para uma conexão websocket
  2. Inicialize um objeto da classe WebSocketClientOptions e especifique os seus parâmetros para configurar o seu cliente.
  3. Inicialize um objeto da classe WebSocketClient e passe as opções previamente criadas para o construtor.
  4. Utilize o método Connect() para se conectar ao recurso escolhido e envie dados através do método Send().
  5. Utilize os manipuladores de eventos TextReceived() e BinaryReceived() para definir o que o seu algo deve fazer quando o cliente WebSocket recebe novos dados.

Abaixo, criaremos um cBot simples que se conecta a um serviço imaginário de notícias económicas via websocket. Quando uma nova notícia é publicada sobre o símbolo ao qual o cBot está atualmente anexado, o algo mostrará uma caixa de mensagem contendo o texto da notícia.

Nota

Este cBot é apenas para fins de exemplo. Embora seja compilado com sucesso, não realiza nenhuma ação quando anexado a um gráfico.

 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
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 ExampleWebSocketBot : Robot
    {

        private static WebSocketClientOptions _webSocketClientOptions = new WebSocketClientOptions 
        {
            KeepAliveInterval = new TimeSpan(0, 1, 30),
            UseDefaultCredentials = true,
        };
        private WebSocketClient _webSocketClient = new WebSocketClient(_webSocketClientOptions);
        private readonly Uri _targetUri = new Uri("ws://amazingnews.com:8000");

        protected override void OnStart()
        {
            _webSocketClient.Connect(_targetUri);
            _webSocketClient.Send("Hello");
            _webSocketClient.TextReceived += NewsReceived;
        }

        protected override void OnStop()
        {
            _webSocketClient.Close(WebSocketClientCloseStatus.NormalClosure);
        }

        private void NewsReceived(WebSocketClientTextReceivedEventArgs args) 
        {
            if (args.Text.Contains(SymbolName)) 
            {
                MessageBox.Show(args.Text, "News!", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
        }
    }
}

Como pode ver, o nosso código é bastante compacto, pois podemos lidar com o evento WebSocketClient.TextReceived para mostrar a caixa de mensagem. Note que o nosso cBot não solicita ativamente informações aos serviços. Em vez disso, reage dinamicamente às novas informações que lhe são fornecidas.

Aviso

Quando o seu cliente websocket se desconecta por qualquer motivo (como um erro do lado do servidor levando a que o intervalo de keep-alive seja excedido), você precisará chamar o método WebSocketClient.Connect() novamente. Para lidar com tais casos programaticamente, utilize o evento WebSocketClient.Disconnected.

Benefícios do WebSocket

Como o websocket permite reagir a novos dados da web em tempo real, é perfeito para integração com serviços de terceiros que podem notificar autonomamente os seus algos sobre algo. Aqui estão alguns exemplos dos recursos da web com os quais pode utilizar o cliente WebSocket.

  • Um calendário de notícias económicas. Quando uma nova notícia é divulgada, o seu algo pode mostrar uma caixa de mensagem com informações-chave.
  • Um serviço de IA generativa. Quando um serviço de IA começa a fornecer uma resposta a um prompt, você pode mostrar o resultado palavra por palavra em vez de ter que esperar pela resposta completa.
  • Um fluxo de preços para todos os símbolos correlacionados com aquele ao qual um algo está anexado. Quando os preços são atualizados, são imediata e precisamente mostrados aos utilizadores do algo.
  • Uma rede social focada em negociação. Quando novas mensagens são publicadas sobre um símbolo específico, um algo pode mostrar o seu conteúdo aos utilizadores.

Em geral, as conexões websocket oferecem os seguintes benefícios em comparação com o HTTPS regular:

  • As conexões WebSocket são mais eficientes. Qualquer pedido HTTP tem que conter dados adicionais, como cabeçalhos. Com websocket, a sua conexão é estabelecida apenas uma vez, após o que não há necessidade de enviar dados redundantes.
  • As conexões WebSocket oferecem melhor concorrência. Não há necessidade de interromper as operações do algo até aguardar uma resposta após o envio de um pedido HTTP. Com websocket, você pode enviar e receber dados a qualquer momento e tratá-los de forma assíncrona.

O cliente WebSocket permite que todos os tipos de algos interajam dinamicamente com recursos da web; esta interação é mais rápida e eficiente em comparação com o uso de HTTP. Utilize o cliente WebSocket para construir algos poderosos integrados com serviços de terceiros.

Acesso à rede e a propriedade AccessRights

Em resumo, o enum AccessRights define se os algoritmos têm acesso a dados externos ao cTrader, como o sistema de ficheiros da sua máquina local. Pode saber mais neste tutorial.

Definir AccessRights como AccessRights.FullAccess permite que os algos realizem operações avançadas (como obter informações do registo do Windows). Os utilizadores finais, no entanto, podem considerar arriscado dar acesso total aos cBots ou indicadores, pois isso pode levar a uma violação de dados.

Como resultado, AccessRights.None é geralmente a opção mais sensata se quiser partilhar os seus produtos algo com outros. No entanto, mesmo que escolha esta opção, os seus produtos cTrader são livres para aceder à web. A adição da funcionalidade de acesso à rede à API Algo do cTrader significa que os cBots já não requerem que a propriedade AccessRights seja definida como AccessRights.FullAccess para trabalhar com recursos na Internet.

Isto expande grandemente as oportunidades que os desenvolvedores de algo têm ao codificar produtos cTrader que pretendem distribuir a outros traders.

Resumo

Em conclusão, o acesso à rede é uma funcionalidade poderosa que permite expandir grandemente o número de operações que os seus algoritmos podem realizar, sem introduzir riscos adicionais.