Przejdź do treści

Jak używać dostępu do sieci

Dostęp do Internetu jest powszechnym przypadkiem użycia dla wtyczek, cBotów i wskaźników. Wcześniej algorytmy musiały żądać specjalnych pozwoleń, aby wykonywać jakiekolwiek operacje związane z siecią, co mogło budzić pewne obawy użytkowników, zwłaszcza jeśli te algorytmy były dystrybuowane bez kodu źródłowego. Na szczęście cTrader pozwala teraz wszystkim algorytmom na dostęp do zasobów internetowych bez posiadania podwyższonych praw dostępu.

W tym artykule i odpowiadającym mu filmie pokażemy, jak pobierać wiadomości z bezpłatnego interfejsu API, który używa JSON do serializacji i deserializacji.

Korzystanie z punktu końcowego API

W naszym przykładzie użyjemy naszego cBota do odczytywania informacji o wiadomościach z zewnętrznego źródła i wypisywania ich do dziennika. W tym celu użyjemy bezpłatnego interfejsu API oferowanego przez NewsData.

Aby zobaczyć, jak wygląda interfejs API w przeglądarce, możemy po prostu uzyskać dostęp do tego linku.

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

Jak widzimy, punkt końcowy dostarcza sekwencję par klucz-wartość, które możemy łatwo wykorzystać za pomocą cBota. Zaczniemy od dodania przestrzeni nazw zawierających kilka klas i metod do deserializacji i odczytywania danych w formacie 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;

Następnie możemy zadeklarować prosty HttpClient(), który będzie uzyskiwał dostęp do Internetu.

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

Następnie będziemy mogli odczytać dane w metodzie 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;
}

Żądanie zwróci surową odpowiedź w formacie JSON. Możemy zobaczyć, jak to wygląda, używając MessageBox.

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

Deserializacja danych JSON

Aby zdeserializować nasze dane JSON, użyjemy klasy JsonSerialiser. Jednak zanim będziemy mogli to zrobić, będziemy musieli zdefiniować klasy wymagane do deserializacji.

  • NewsItem - ta klasa reprezentuje pojedynczy artykuł informacyjny.
  • News - ta klasa zawiera kolekcję obiektów 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; }
}

Jeśli chcesz uniknąć pisania tego kodu szablonowego, możesz również użyć konwertera online z JSON do C#.

Używając konwertera, zdefiniowaliśmy nasze klasy w następujący sposób:

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

Możemy teraz napisać nasz kod deserializacji.

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

Ponadto możemy dodać następujący kod, aby wypisać tytuły wiadomości w dzienniku.

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

Jeśli zbudujemy i uruchomimy naszego cBota, zobaczymy, że w dzienniku pojawia się wyjątek. Jednak jeśli zmienimy prawa dostępu cBota na AccessRights.FullAccess, zobaczymy, że nasz cBot działa zgodnie z przeznaczeniem.

Dostęp do Internetu bez podwyższonych praw dostępu

Aby uniknąć sytuacji, w której nasz cBot musi żądać podwyższonych praw dostępu, możemy zmodyfikować naszą metodę OnStart() do następującej.

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

Jeśli ustawimy prawa dostępu na AccessRights.None i przebudujemy naszego cBota, powinniśmy zobaczyć tytuły wiadomości wypisywane w dzienniku bez żadnych problemów. Przy nieco większym wysiłku nasz cBot może zostać przekształcony w elegancki czytnik wiadomości dostępny bezpośrednio w dowolnym wykresie cTrader!