Saltar a contenido

Cómo usar el acceso a la red

El acceso a Internet es un caso de uso común para plugins, cBots e indicadores. Anteriormente, los algos tenían que solicitar permisos especiales para realizar cualquier operación relacionada con la red, lo que podía generar algunas preocupaciones en los usuarios, especialmente si estos algos se distribuían sin ningún código fuente. Afortunadamente, cTrader ahora permite que todos los algos accedan a recursos web sin necesidad de tener derechos de acceso elevados.

En este artículo y su video correspondiente, demostraremos cómo recuperar noticias de una API gratuita que utiliza JSON para serialización y deserialización.

Consumir un endpoint de API

En nuestro ejemplo, utilizaremos nuestro cBot para leer información de noticias de una fuente externa e imprimirla en el registro. Para este propósito, utilizaremos una API gratuita ofrecida por NewsData.

Para ver cómo se ve la API en un navegador, simplemente podemos acceder a este enlace.

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

Como podemos ver, el endpoint proporciona una secuencia de pares clave-valor que podemos consumir fácilmente utilizando un cBot. Comenzaremos añadiendo los espacios de nombres que contienen varias clases y métodos para deserializar y leer datos en formato 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;

Luego podemos declarar un simple HttpClient() que accederá a Internet.

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

Después, podremos leer datos en el 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;
}

La solicitud devolverá una respuesta sin procesar en formato JSON. Podemos ver cómo se ve utilizando un MessageBox.

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

Deserializar datos JSON

Para deserializar nuestros datos JSON, utilizaremos la clase JsonSerialiser. Sin embargo, antes de poder hacer esto, tendremos que definir las clases necesarias para la deserialización.

  • NewsItem- esta clase representa un solo artículo de noticias.
  • News - esta clase contiene una colección 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; }
}

Si desea evitar escribir este código repetitivo, también puede utilizar un convertidor en línea de JSON a C#.

Utilizando el convertidor, hemos definido nuestras clases 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
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; }
}

Ahora podemos escribir nuestro código de deserialización.

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

Además, podemos añadir el siguiente código para imprimir los títulos de las noticias en el registro.

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);
}

Si compilamos y ejecutamos nuestro cBot, veremos que aparece una excepción en el registro. Sin embargo, si cambiamos los derechos de acceso del cBot a AccessRights.FullAccess, veremos que nuestro cBot funciona como se esperaba.

Acceder a Internet sin derechos de acceso elevados

Para evitar tener una situación en la que nuestro cBot necesite solicitar derechos de acceso elevados, podemos modificar nuestro método OnStart() de la siguiente manera.

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

Si establecemos los derechos de acceso en AccessRights.None y recompilamos nuestro cBot, deberíamos ver los títulos de las noticias imprimiéndose en el registro sin ningún problema. ¡Con un poco más de esfuerzo, nuestro cBot puede transformarse en un elegante lector de noticias disponible directamente dentro de cualquier gráfico de cTrader!