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

Сетевой доступ

В этом руководстве описано, как создавать алгоритмы с доступом к Интернету. Ниже приведена минутная сводка этой функции API.

Сетевой доступ за одну минуту!

  • Ваши алгоритмы могут получать информацию с новостных сайтов о торговле или веб-API, ориентированных на Forex. Используйте эту функцию, чтобы ваши сиБоты, плагины и индикаторы реагировали на важные события и информацию в реальном времени.
  • Используя методы из пространств имен System.Text.Json и System.Text.Json.Serialization, вы можете быстро сериализовать или десериализовать объекты в JSON-файлы и из них, что позволяет сиБотам легко использовать конечные точки и обрабатывать ценную информацию.
  • Протокол WebSocket позволяет получать данные от сервиса в режиме реального времени вместо того, чтобы каждый раз делать HTTP-запрос. Используйте websocket для плавной интеграции ваших алгоритмов с веб-ресурсами. Класс WebSocketClient содержит все методы и параметры, необходимые для использования websocket-соединений.
  • При использовании websocket вы можете отправлять и получать строки и необработанные байтовые данные. Работайте с различными структурами данных и сериализуйте их в байты для использования ценных сторонних сервисов.
  • Для сетевых функций достаточно AccessRights.None.

HTTP

Новый интерфейс Http содержит несколько методов, которые при реализации должны позволить сиБотам и другим типам алгоритмов получать доступ к Интернету. Для иллюстрации см. следующее:

  • HttpResponse Http.Get(string uri). Выполняет запрос GET к URI, указанному в переданной строке uri, и возвращает объект HttpsResponse, содержащий результаты этого запроса.

Класс HttpsRequest позволяет выполнять более сложные запросы, включая запросы POST. Чтобы выполнить эти запросы, установите свойство HttpsRequest.Method на одно из значений enum HttpMethod, например HttpMethod.Put или HttpMethod.Patch.

В свою очередь, свойство HttpsRequest.Uri содержит URI, на который отправляется запрос, а свойство HttpsRequest.Body можно использовать для установки тела запроса. См. ниже пример использования объекта HttpsRequest.

  • HttpResponse Http.Send(HttpRequest request). Выполняет запрос к URI, указанному в качестве значения свойства request.Uri объекта HttpsRequest, переданного в этот метод. После этого возвращает объект HttpsResponse, содержащий результаты этого запроса. Тип запроса устанавливается в качестве значения свойства equest.Method.

Сетевой доступ при бэктестинге и оптимизации

Все методы в интерфейсе Http работают должным образом при бэктестинге и оптимизации. Обратите внимание, что при обращении к веб-ресурсу во время бэктестинга или оптимизации будет запрошена актуальная версия этого ресурса, а не историческая.

Создайте примеры сиБотов

Выполнение GET-запроса

Мы создадим простой сиБот, который выполняет следующие действия:

  • Отправляет запрос GET и получает доступ к JSON-файлу через API по адресу https://forexApiExample.com/v1/exchangerate (обратите внимание, что этот API полностью вымышленный).
  • Если ответ GET успешен, сиБот десериализует тело ответа в объект пользовательского класса SymbolPrice (мы создали этот класс для демонстрационных целей).
  • Размещает лимитный ордер на продажу инструмента по цене, которая немного выше цены, указанной в API.

Обратите внимание, что сиБот полностью вымышленный. Хотя код будет собран, он не будет выполнять никаких значимых действий.

Как сериализовать или десериализовать строки из JSON-файлов

Код нашего сиБота включает два важных оператора using, а именно System.Text.Json и System.Text.Json.Serialization. Эти пространства имен содержат несколько методов, которые позволяют легко сериализовать и десериализовать строки из JSON-файлов, например JsonSerializer.Deserialize<T>().

Вот код нашего примера сиБота:

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

Если бы этот сиБот обращался к реальному API, он бы сделал это успешно.

Выполнение POST-запроса

Мы также можем создать более продвинутый сиБот, который достигает следующих целей:

  • Отправляет запрос POST к тому же вымышленному API по адресу https://anotherForexApiExample.com/commodities/v1/getaccesstoken. Это делается для получения токена доступа для этого API.
  • Сохраняет токен из тела ответа в переменной token.
  • Выполняет запрос GET к тому же API со значением переменной token, переданным в качестве параметра запроса в URI (https://anotherForexApiExample.com/commodities/v1/getprices).
  • Используя сериализацию JSON (обсуждалось выше), размещает стоп ордер на покупку по цене, которая немного ниже цены, полученной от API.

Еще раз обратите внимание, что этот сиБот не будет выполнять никаких значимых действий при компиляции. Он существует только для примера.

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

Клиент WebSocket

Algo API позволяет любому использовать различные веб-сервисы и ресурсы с помощью websocket-соединения. По сравнению с протоколом HTTP, который используется в функции сетевого доступа, протокол WebSocket быстрее и позволяет получать данные в режиме реального времени.

Использование клиента WebSocket

Использовать клиент WebSocket просто:

  1. Выберите сервис, который предоставляет конечную точку для websocket-соединения
  2. Инициализируйте объект класса WebSocketClientOptions и укажите его параметры для настройки вашего клиента.
  3. Инициализируйте объект класса WebSocketClient и передайте ранее созданные параметры в конструктор.
  4. Используйте метод Connect() для подключения к выбранному ресурсу и отправки данных через метод Send().
  5. Используйте обработчики событий TextReceived() и BinaryReceived(), чтобы установить, что должен делать ваш алгоритм при получении новых данных клиентом WebSocket.

Ниже мы создадим простой сиБот, который подключается к воображаемому сервису экономических новостей через websocket. Когда публикуется новая новость об инструменте, к которому в данный момент прикреплен сиБот, алгоритм показывает окно сообщения с текстом новости.

Примечание

Этот сиБот предназначен только для примера. Хотя он успешно собирается, он не выполняет никаких действий при прикреплении к графику.

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

Как видите, наш код довольно компактен, поскольку мы можем обработать событие WebSocketClient.TextReceived, чтобы показать окно сообщения. Обратите внимание, что наш сиБот не запрашивает информацию у сервисов активно. Вместо этого он динамически реагирует на новую информацию, поступающую к нему.

Предупреждение

Когда ваш websocket-клиент отключается по какой-либо причине (например, из-за ошибки на стороне сервера, приводящей к превышению интервала keep-alive), вам нужно будет снова вызвать метод WebSocketClient.Connect(). Для программной обработки таких случаев используйте событие WebSocketClient.Disconnected.

Преимущества WebSocket

Поскольку websocket позволяет реагировать на новые данные из Интернета в режиме реального времени, он идеально подходит для интеграции со сторонними сервисами, которые могут автономно уведомлять ваши алгоритмы о чем-либо. Вот несколько примеров веб-ресурсов, с которыми вы можете использовать клиент WebSocket.

  • Календарь экономических новостей. Когда публикуется новая новость, ваш алгоритм может показать окно сообщения с ключевой информацией.
  • Сервис генеративного ИИ. Когда сервис ИИ начинает предоставлять ответ на запрос, вы можете показывать результат слово за словом, а не ждать полного ответа.
  • Поток цен для всех инструментов, коррелирующих с тем, к которому прикреплен алгоритм. Когда цены обновляются, они немедленно и точно отображаются пользователям алгоритма.
  • Социальная сеть, ориентированная на трейдинг. Когда публикуются новые сообщения о конкретном инструменте, алгоритм может показывать их содержимое пользователям.

В целом, соединения websocket предлагают следующие преимущества по сравнению с обычным HTTPS:

  • Соединения WebSocket более эффективны. Любой HTTP-запрос должен содержать дополнительные данные, такие как заголовки. С websocket ваше соединение устанавливается только один раз, после чего нет необходимости отправлять избыточные данные.
  • Соединения WebSocket обеспечивают улучшенную параллельность. Нет необходимости останавливать операции алгоритма, пока вы ожидаете ответа после отправки HTTP-запроса. С websocket вы можете отправлять и получать данные в любое время и обрабатывать их асинхронно.

Клиент WebSocket позволяет всем типам алгоритмов динамически взаимодействовать с веб-ресурсами; это взаимодействие быстрее и эффективнее по сравнению с использованием HTTP. Используйте клиент WebSocket для создания мощных алгоритмов, интегрированных со сторонними сервисами.

Сетевой доступ и свойство AccessRights

Вкратце, AccessRights enum определяет, имеют ли алгоритмы доступ к данным, которые являются внешними по отношению к cTrader, таким как файловая система вашего локального компьютера. Вы можете узнать больше в этом руководстве.

Установка AccessRights в AccessRights.FullAccess позволяет алгоритмам выполнять расширенные операции (такие как получение информации из реестра Windows). Однако конечные пользователи могут счесть предоставление сиБотам или индикаторам полного доступа рискованным, поскольку это может привести к утечке данных.

В результате AccessRights.None обычно является наиболее разумным вариантом, если вы хотите делиться своими алгопродуктами с другими. Однако, даже если вы выберете этот вариант, ваши продукты cTrader могут свободно получать доступ к сети. Добавление функциональности сетевого доступа в cTrader Algo API означает, что сиБотам больше не требуется установка свойства AccessRights в AccessRights.FullAccess для работы с ресурсами в Интернете.

Это значительно расширяет возможности разработчиков алгоритмов при написании кода продуктов cTrader, которые они намерены распространять среди других трейдеров.

Обзор

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