Przejdź do treści

Dostęp do sieci

Ten przewodnik definiuje, jak możesz tworzyć algorytmy, które mogą uzyskiwać dostęp do Internetu. Poniżej znajduje się jednominutowe podsumowanie tej funkcji API.

Dostęp do sieci w jedną minutę!

  • Twoje rozwiązania algorytmiczne mogą czerpać informacje ze stron internetowych z wiadomościami handlowymi lub interfejsów API internetowych zorientowanych na Forex. Użyj tej funkcji, aby upewnić się, że Twoje cBoty, wtyczki i wskaźniki reagują na rzeczywiste wydarzenia i informacje.
  • Korzystając z metod w przestrzeniach nazw System.Text.Json i System.Text.Json.Serialization, możesz szybko serializować lub deserializować obiekty do i z plików JSON, umożliwiając cBotom łatwe korzystanie z punktów końcowych i przetwarzanie cennych informacji.
  • Protokół WebSocket umożliwia odbieranie danych z usługi w czasie rzeczywistym zamiast konieczności wykonywania żądania HTTP za każdym razem. Użyj websocket, aby płynnie zintegrować swoje algorytmy z zasobami internetowymi. Klasa WebSocketClient zawiera wszystkie metody i parametry niezbędne do korzystania z połączeń websocket.
  • Podczas korzystania z websocket możesz wysyłać i odbierać ciągi znaków oraz surowe dane bajtowe. Pracuj z różnymi strukturami danych i serializuj je do bajtów, aby korzystać z cennych usług zewnętrznych.
  • AccessRights.None jest wystarczające dla funkcji sieciowych.

HTTP

Nowy interfejs Http zawiera kilka metod, które po zaimplementowaniu powinny umożliwić cBotom i innym typom algorytmów dostęp do Internetu. Aby zobaczyć ilustrację, zobacz poniżej:

  • HttpResponse Http.Get(string uri). Wykonuje żądanie GET do URI określonego w przekazanym ciągu znaków uri i zwraca obiekt HttpsResponse zawierający wyniki tego żądania.

Klasa HttpsRequest umożliwia wykonywanie bardziej złożonych żądań, w tym żądań POST. Aby wykonać te żądania, ustaw właściwość HttpsRequest.Method na jedną z wartości enum HttpMethod, taką jak HttpMethod.Put lub HttpMethod.Patch.

Z kolei właściwość HttpsRequest.Uri zawiera URI, do którego wysyłane jest żądanie, podczas gdy właściwość HttpsRequest.Body może być użyta do ustawienia treści żądania. Zobacz poniżej przykład, jak możesz użyć obiektu HttpsRequest.

  • HttpResponse Http.Send(HttpRequest request). Wykonuje żądanie do URI określonego jako wartość właściwości request.Uri obiektu HttpsRequest przekazanego do tej metody. Następnie zwraca obiekt HttpsResponse zawierający wyniki tego żądania. Typ żądania jest ustawiony jako wartość właściwości equest.Method.

Dostęp do sieci w backtestingu i optymalizacji

Wszystkie metody w interfejsie Http działają zgodnie z przeznaczeniem w backtestingu i optymalizacji. Należy pamiętać, że podczas uzyskiwania dostępu do zasobu internetowego w backtestingu lub optymalizacji zostanie zażądana aktualna wersja tego zasobu zamiast historycznej.

Tworzenie przykładowych cBotów

Wykonywanie żądania GET

Utworzymy prosty cBot, który wykonuje następujące działania:

  • Wysyła żądanie GET i uzyskuje dostęp do pliku JSON za pośrednictwem API pod adresem https://forexApiExample.com/v1/exchangerate (należy pamiętać, że to API jest całkowicie fikcyjne).
  • Jeśli odpowiedź GET zakończy się sukcesem, cBot deserializuje treść odpowiedzi do obiektu niestandardowej klasy SymbolPrice (utworzyliśmy tę klasę w celach demonstracyjnych).
  • Składa zlecenie Sell Limit na symbol po cenie nieco wyższej niż cena określona w API.

Należy pamiętać, że cBot jest całkowicie wymyślony. Chociaż kod zostanie zbudowany, nie wykona żadnych znaczących działań.

Jak serializować lub deserializować ciągi znaków z plików JSON

Kod naszego cBota zawiera dwie ważne instrukcje using, a mianowicie System.Text.Json i System.Text.Json.Serialization. Te przestrzenie nazw zawierają kilka metod, które umożliwiają łatwą serializację i deserializację ciągów znaków z plików JSON, takich jak JsonSerializer.Deserialize<T>().

Oto kod naszego przykładowego cBota:

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

Gdyby ten cBot miał uzyskać dostęp do prawdziwego API, zrobiłby to pomyślnie.

Wykonywanie żądania POST

Możemy również utworzyć bardziej zaawansowany cBot, który osiąga następujące cele:

  • Wysyła żądanie POST do tego samego fikcyjnego API pod adresem https://anotherForexApiExample.com/commodities/v1/getaccesstoken. Ma to na celu uzyskanie tokena dostępu dla tego API.
  • Przechowuje token z treści odpowiedzi w zmiennej token.
  • Wykonuje żądanie GET do tego samego API z wartością zmiennej token przekazaną jako parametr zapytania w URI (https://anotherForexApiExample.com/commodities/v1/getprices).
  • Używając serializacji JSON (omówionej powyżej), składa zlecenie Buy Stop po cenie nieco niższej niż cena otrzymana z API.

Jeszcze raz należy pamiętać, że ten cBot nie wykona żadnych znaczących działań po skompilowaniu. Istnieje wyłącznie w celach przykładowych.

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

Klient WebSocket

Algo API umożliwia każdemu korzystanie z różnych usług i zasobów internetowych przy użyciu połączenia websocket. W porównaniu z protokołem HTTP, który jest używany w funkcji dostępu do sieci, protokół WebSocket jest szybszy i umożliwia odbieranie danych w czasie rzeczywistym.

Korzystanie z klienta WebSocket

Korzystanie z klienta WebSocket jest proste:

  1. Wybierz usługę, która udostępnia punkt końcowy dla połączenia websocket
  2. Zainicjuj obiekt klasy WebSocketClientOptions i określ jego parametry, aby skonfigurować swojego klienta.
  3. Zainicjuj obiekt klasy WebSocketClient i przekaż wcześniej utworzone opcje do konstruktora.
  4. Użyj metody Connect(), aby połączyć się z wybranym zasobem i wysyłać dane za pomocą metody Send().
  5. Użyj procedur obsługi zdarzeń TextReceived() i BinaryReceived(), aby ustawić, co Twój algorytm powinien zrobić, gdy klient WebSocket otrzyma nowe dane.

Poniżej utworzymy prosty cBot, który łączy się z wyimaginowaną usługą wiadomości ekonomicznych za pośrednictwem websocket. Gdy zostanie opublikowana nowa wiadomość dotycząca symbolu, do którego cBot jest obecnie dołączony, algorytm wyświetli okno komunikatu zawierające tekst wiadomości.

Uwaga

Ten cBot służy wyłącznie celom przykładowym. Chociaż buduje się pomyślnie, nie wykonuje żadnych działań po dołączeniu do wykresu.

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

Jak widać, nasz kod jest dość kompaktowy, ponieważ możemy obsłużyć zdarzenie WebSocketClient.TextReceived, aby wyświetlić okno komunikatu. Należy pamiętać, że nasz cBot nie żąda aktywnie informacji z usług. Zamiast tego dynamicznie reaguje na nowe informacje dostarczane do niego.

Ostrzeżenie

Gdy Twój klient websocket rozłączy się z jakiegokolwiek powodu (takiego jak błąd po stronie serwera prowadzący do przekroczenia interwału keep-alive), będziesz musiał ponownie wywołać metodę WebSocketClient.Connect(). Aby obsłużyć takie przypadki programowo, użyj zdarzenia WebSocketClient.Disconnected.

Korzyści z WebSocket

Ponieważ websocket umożliwia reagowanie na nowe dane z sieci w czasie rzeczywistym, jest idealny do integracji z usługami zewnętrznymi, które mogą autonomicznie powiadamiać Twoje algorytmy o czymś. Oto kilka przykładów zasobów internetowych, z którymi możesz używać klienta WebSocket.

  • Kalendarz wiadomości ekonomicznych. Gdy zostanie opublikowana nowa wiadomość, Twój algorytm może wyświetlić okno komunikatu z kluczowymi informacjami.
  • Usługa generatywnej sztucznej inteligencji. Gdy usługa AI zacznie dostarczać odpowiedź na monit, możesz wyświetlać wynik słowo po słowie, zamiast czekać na pełną odpowiedź.
  • Strumień cen dla wszystkich symboli skorelowanych z tym, do którego dołączony jest algorytm. Gdy ceny są aktualizowane, są natychmiast i dokładnie wyświetlane użytkownikom algorytmu.
  • Sieć społecznościowa skoncentrowana na handlu. Gdy nowe wiadomości są publikowane na temat konkretnego symbolu, algorytm może wyświetlać ich treść użytkownikom.

Ogólnie rzecz biorąc, połączenia websocket oferują następujące korzyści w porównaniu ze zwykłym HTTPS:

  • Połączenia WebSocket są bardziej wydajne. Każde żądanie HTTP musi zawierać dodatkowe dane, takie jak nagłówki. Dzięki websocket Twoje połączenie jest nawiązywane tylko raz, po czym nie ma potrzeby wysyłania zbędnych danych.
  • Połączenia WebSocket oferują lepszą współbieżność. Nie ma potrzeby wstrzymywania operacji algorytmu, dopóki nie oczekujesz odpowiedzi po wysłaniu żądania HTTP. Dzięki websocket możesz wysyłać i odbierać dane w dowolnym momencie i obsługiwać je asynchronicznie.

Klient WebSocket umożliwia wszystkim typom algorytmów dynamiczną interakcję z zasobami internetowymi; ta interakcja jest szybsza i bardziej wydajna w porównaniu z użyciem HTTP. Użyj klienta WebSocket, aby budować zaawansowane algorytmy zintegrowane z usługami zewnętrznymi.

Dostęp do sieci i właściwość AccessRights

Krótko mówiąc, AccessRights enum określa, czy algorytmy mają dostęp do danych zewnętrznych względem cTrader, takich jak system plików na komputerze lokalnym. Więcej informacji znajdziesz w tym samouczku.

Ustawienie AccessRights na AccessRights.FullAccess pozwala algorytmom wykonywać zaawansowane operacje (takie jak pozyskiwanie informacji z rejestru Windows). Użytkownicy końcowi mogą jednak uznać przyznanie cBotom lub wskaźnikom pełnego dostępu za ryzykowne, ponieważ może to prowadzić do naruszenia danych.

W rezultacie AccessRights.None jest zazwyczaj najbardziej rozsądną opcją, jeśli chcesz udostępniać swoje produkty algorytmiczne innym. Jednak nawet jeśli wybierzesz tę opcję, Twoje produkty cTrader mogą swobodnie uzyskiwać dostęp do sieci. Dodanie funkcji dostępu do sieci do cTrader Algo API oznacza, że cBoty nie wymagają już ustawienia właściwości AccessRights na AccessRights.FullAccess, aby współpracować z zasobami w Internecie.

To znacznie poszerza możliwości deweloperów algorytmów podczas kodowania produktów cTrader, które zamierzają dystrybuować innym traderom.

Podsumowanie

Podsumowując, dostęp do sieci to zaawansowana funkcja, która pozwala znacznie rozszerzyć liczbę operacji, które mogą wykonywać Twoje algorytmy, nie wprowadzając przy tym dodatkowego ryzyka.