Ir para o conteúdo

Como usar o acesso à rede

O acesso à internet é um caso de uso comum para plugins, cBots e indicadores. Anteriormente, os algos tinham de solicitar permissões especiais para realizar quaisquer operações relacionadas com a rede, o que poderia levantar algumas preocupações por parte dos utilizadores, especialmente se estes algos fossem distribuídos sem qualquer código-fonte. Felizmente, o cTrader agora permite que todos os algos acedam a recursos web sem terem direitos de acesso elevados.

Neste artigo e no vídeo correspondente, demonstraremos como obter notícias de uma API gratuita que usa JSON para serialização e desserialização.

Consumir um endpoint de API

No nosso exemplo, usaremos o nosso cBot para ler informações de notícias de uma fonte externa e imprimi-las no registo. Para este fim, usaremos uma API gratuita oferecida pela NewsData.

Para ver como a API se apresenta num navegador, podemos simplesmente aceder a este link.

https://newsdata.io/api/1/news?apikey=pub_32606381862bbdf07962c72ae7bc6135d6332&&language=en

Como podemos ver, o endpoint fornece uma sequência de pares chave-valor que podemos facilmente consumir usando um cBot. Começaremos por adicionar os namespaces que contêm várias classes e métodos para desserializar e ler dados formatados em JSON.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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;
using System.Net.Http.Json;
using System.Net.Http;

Podemos então declarar um simples HttpClient() que acederá à Internet.

1
private static readonly HttpClient client = new HttpClient();

Depois, poderemos ler dados no método OnStart().

1
2
3
4
protected override void OnStart()
{
    HttpResponseMessage responseToGet = client.GetAsync("https://newsdata.io/api/1/news?apikey=pub_32606381862bbdf07962c72ae7bc6135d6332&q=inflation&language=en").Result;
}

O pedido retornará uma resposta bruta em formato JSON. Podemos ver como se apresenta usando uma MessageBox.

1
2
3
var stream = responseToGet.Content.ReadAsStream();
var reader = new StreamReader(stream);
MessageBox.Show(reader.ReadToEnd());

Desserializar dados JSON

Para desserializar os nossos dados JSON, usaremos a classe JsonSerialiser. No entanto, antes de podermos fazer isso, teremos de definir as classes necessárias para a desserialização.

  • NewsItem - esta classe representa um único artigo de notícias.
  • News - esta classe contém uma coleção de objetos NewsItem.
1
2
3
4
5
6
7
8
9
public class NewsItem
{
    public string title { get; set; }   
}

public class News
{
    public List<NewsItem> results { get; set; }
}

Se quiser evitar escrever este código padrão, também pode usar um conversor online de JSON para C#.

Usando o conversor, definimos as nossas classes 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
public class NewsItem
{
    public string article_id { get; set; }
    public string title { get; set; }
    public string link { get; set; }
    public List<string> keywords { get; set; }
    public List<string> creator { get; set; }
    public object video_url { get; set; }
    public string description { get; set; }
    public string content { get; set; }
    public string pubDate { get; set; }
    public string image_url { get; set; }
    public string source_id { get; set; }
    public int source_priority { get; set; }
    public List<string> country { get; set; }
    public List<string> category { get; set; }
    public string language { get; set; }
}

public class News
{
    public string status { get; set; }
    public int totalResults { get; set; }
    public List<NewsItem> results { get; set; }
    public string nextPage { get; set; }
}

Agora podemos escrever o nosso código de desserialização.

1
News news = JsonSerializer.Deserialize<News>(responseToGet.Content.ReadAsStream());

Além disso, podemos adicionar o seguinte código para imprimir os títulos das notícias no registo.

1
2
3
4
5
6
7
if (responseToGet.IsSuccessful)
{
    News news = JsonSerializer.Deserialize<News>(responseToGet.Body);

    foreach (var item in news.results)
            Print(item.title);
}

Se construirmos e executarmos o nosso cBot, veremos que aparece uma exceção no registo. No entanto, se alterarmos os direitos de acesso do cBot para AccessRights.FullAccess, veremos que o nosso cBot funciona como pretendido.

Aceder à internet sem direitos de acesso elevados

Para evitar ter uma situação em que o nosso cBot precisa de solicitar direitos de acesso elevados, podemos modificar o nosso método OnStart() para o seguinte.

1
2
3
4
protected override void OnStart()
{
    var responseToGet = Http.Get("https://newsdata.io/api/1/news?apikey=pub_32606381862bbdf07962c72ae7bc6135d6332&q=inflation&language=en");
}

Se definirmos os direitos de acesso para AccessRights.None e reconstruirmos o nosso cBot, deveremos ver os títulos das notícias a serem impressos no registo sem quaisquer problemas. Com um pouco mais de esforço, o nosso cBot pode ser transformado num leitor de notícias sofisticado disponível diretamente em qualquer gráfico do cTrader!