Перейти к содержанию

Как использовать сетевой доступ

Доступ к интернету — распространенный вариант использования для плагинов, сиБотов и индикаторов. Ранее алгоритмам требовалось запрашивать специальные разрешения для выполнения любых сетевых операций, что могло вызывать некоторые опасения у пользователей, особенно если эти алгоритмы распространялись без исходного кода. К счастью, теперь cTrader позволяет всем алгоритмам получать доступ к веб-ресурсам без повышенных прав доступа.

В этой статье и соответствующем видео мы продемонстрируем, как получать новости из бесплатного API, который использует JSON для сериализации и десериализации.

Использование конечной точки API

В нашем примере мы будем использовать наш сиБот для чтения новостной информации из внешнего источника и вывода ее в журнал. Для этой цели мы будем использовать бесплатный API, предлагаемый NewsData.

Чтобы увидеть, как выглядит API в браузере, мы можем просто перейти по этой ссылке.

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

Как мы видим, конечная точка предоставляет последовательность пар ключ-значение, которые мы можем легко использовать с помощью сиБота. Начнем с добавления пространств имен, содержащих несколько классов и методов для десериализации и чтения данных в формате 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;

Затем мы можем объявить простой HttpClient(), который будет получать доступ к интернету.

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

После этого мы сможем читать данные в методе 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;
}

Запрос вернет необработанный ответ в формате JSON. Мы можем увидеть, как он выглядит, используя MessageBox.

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

Десериализация данных JSON

Для десериализации наших данных JSON мы будем использовать класс JsonSerialiser. Однако, прежде чем мы сможем это сделать, нам нужно будет определить классы, необходимые для десериализации.

  • NewsItem — этот класс представляет одну новостную статью.
  • News — этот класс содержит коллекцию объектов 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; }
}

Если вы хотите избежать написания этого шаблонного кода, вы также можете использовать онлайн-конвертер из JSON в C#.

Используя конвертер, мы определили наши классы следующим образом:

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

Теперь мы можем написать наш код десериализации.

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

Кроме того, мы можем добавить следующий код для вывода заголовков новостей в журнал.

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

Если мы соберем и запустим наш сиБот, то увидим, что в логе появилось исключение. Однако, если мы изменим права доступа сиБота на AccessRights.FullAccess, то увидим, что наш сиБот работает как задумано.

Доступ к интернету без повышенных прав доступа

Чтобы избежать ситуации, когда нашему сиБоту необходимо запрашивать повышенные права доступа, мы можем изменить наш метод OnStart() следующим образом.

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

Если мы установим права доступа на AccessRights.None и пересоберем наш сиБот, то увидим, что заголовки новостей выводятся в лог без каких-либо проблем. Приложив еще немного усилий, наш сиБот можно превратить в удобную программу для чтения новостей, доступную прямо на любом графике cTrader!