Skip to content

Network Access

This guide defines how you can create algorithms that can access the Internet. Below, we provide a one-minute summary of this API feature.

Network Access in One Minute!

  • Your algo solutions can source information from trading news websites or Forex-oriented web APIs. Use this feature to ensure that your cBots, plugins, and indicators react to pressing real-life events and information!
  • By using methods in the System.Text.Json and System.Text.Json.Serialization namespaces, you can quickly serialise/deserialise objects to and from JSON files, allowing cBots to easily consume endpoints and process valuable information!
  • The websocket protocol allows for receiving data from a service in real time instead of having to make an HTTP request each time. Use websocket to smoothly integrate your algos with web resources! The WebSocketClient class contains all the methods and parameters necessary to use websocket connections.
  • When using websocket, you can send/receive strings and raw byte data. Work with different data structures and serialise them into bytes to use valuable third-party services!
  • AccessRights.None is sufficient for network functions.

HTTP

The new Http interface contains several methods that, when implemented, should enable cBots and other types of algorithms to access the Internet. For an illustration, see the following.

  • HttpResponse Http.Get(string uri). Performs a GET request to the URI specified in the passed string uri and returns an HttpsResponse object containing the results of this request.

The HttpsRequest class allows for performing more complex requests including POST requests. To perform these requests, set the HttpsRequest.Method property to one of the values of the HttpMethod enum such as HttpMethod.Put or HttpMethod.Patch.

In turn, the HttpsRequest.Uri property contains the URI to which a request is sent while the HttpsRequest.Body property can be used to set the request body. See below for an example of how you can use an HttpsRequest object.

  • HttpResponse Http.Send(HttpRequest request). Performs a request to the URI specified as the value of the request.Uri property of the HttpsRequest object passed into this method. Afterward, returns an HttpsResponse object containing the results of this request. The request type is set as the value of the equest.Method property.

Network Access in Backtesting and Optimisation

All methods in the Http interface work as intended in backtesting and optimisation. Note that, when accessin a web resource in backtesting or optimisation, the up-to-date version of this resource will be requested instead of a historical one.

Creating Example cBots

Performing a GET Request

We will create a simple cBot that performs the following actions.

  • Sends a GET request and accesses a JSON file via the API at https://forexApiExample.com/v1/exchangerate (note that this API is entirely fake).
  • If the GET response is successful, the cBot deserialises the response body into an object of a custom SymbolPrice class (we have created this class for demonstration purposes).
  • Places a Sell limit order for a symbol at a price that is slightly higher than the price specified in the API.

Note that the cBot is entirely made up. While the code will build, it will not perform any meaningful actions.

How to Serialise/Deserialise Strings From JSON Files

The code of our cBot includes two important using statements, namely System.Text.Json and System.Text.Json.Serialization. These namespaces contain several methods that allow for easily serialising and deserialising strings from JSON files such as JsonSerializer.Deserialize<T>().

Here is the code of our example cBot.

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

If this cBot was to access a real API, it would have done so successfully.

Performing a POST Request

We can also create a more advanced cBot that achieves the following goals.

  • Sends a POST request to the same fake API at https://anotherForexApiExample.com/commodities/v1/getaccesstoken. This is done to attain an access token for this API.
  • Stores the token from the response body in the token variable.
  • Performs a GET request to the same API with the value of the token variable passed as a query parameter in the URI (https://anotherForexApiExample.com/commodities/v1/getprices).
  • Using JSON serialisation (discussed above), places a Buy stop order at a price that is slightly lower than the price received from the API.

Once again, note that this cBot will not perform any meaningful actions when compiled. It exists for example purposes only.

 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 Client

The Algo API allows anyone to use various web services and resources using a websocket connection. Compared to the HTTP protocol which is used in the network access feature, the websocket procotol is faster and allows for receiving data in real time.

Using the WebSocket Client

Using the websocket client is simple:

  1. Choose a service that exposes an endpoint for a websocket connection
  2. Initialise an object of the WebSocketClientOptions class and specify its parameters to configure your client.
  3. Initialise an object of the WebSocketClient class and pass the previously created options to the constructor.
  4. Use the Connect() method to connect to your chosen resource and send data via the Send() method.
  5. Use the TextReceived() and BinaryReceived() event handlers to set what your algo should do when the websocket client receives new data.

Below, we will create a simple cBot that connects to an imaginary economic news service via websocket. When a new piece of news is posted about the symbol to which the cBot is currently attached, the algo will shows a message box containing the news text.

Note

Note that the cBot is provided for example purposes only. While it can be built inside cTrader, it will not perform any actions when attached to a chart.

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

As you can see, our code is pretty compact as we can simply handle the WebSocketClient.TextReceived event to show the message box. Note that our bot does not actively request information from the services. Instead, it dynamically reacts to new information being supplied to it.

Warning

When your websocket client disconnects for any reason (e.g., there is some sort of server-side error leading to the keep-alive interval being exceeded), you would need to call the WebSocketClient.Connect() method again. To handle such cases programmatically, use the WebSocketClient.Disconnected event.

Benefits of WebSocket

Because websocket allows for reacting to new data from the web in real time, it is perfect for integrating with third-party services that can autonomously notify your algos about something. Here are a few examples of the web resources with which you can use the websocket client.

  • An economic news calendar. When a new piece of news is released, your algo can show a message box with key information.S
  • A generative AI service. When an AI service starts to supply a response to a prompt, you can show the result word-by-word rather than having to wait for the complete response.
  • A stream of prices for all symbols correlated with the one to which an algo is attached. When prices are updated, they are immediately and accurately shown to algo users.
  • A social media network focused on trading. When new messages are posted about a particular symbol, an algo can show their contents to users.

In general, websocket connections offer the following benefits compared to regular HTTPS.

  • Websocket connections are more efficient. Any HTTP request has to contain additional data such as headers. With websocket, your connection is established only once, after which there is no need to send redundant data.
  • Websocket connections offer improved concurrency. There is no need to halt algo operations until you await a response after sending an HTTP request. With websocket, you can send and receive data at any time and handle it asynchronously.

The websocket client allows all types of algos to dynamically interact with web resources; this interaction is faster and more efficient compared to using HTTP. Use the websocket client to build powerful algos integrated with third-party services!

Network Access and the AccessRights Property

In brief, the AccessRights enum defines whether algorithms have access to data that is external to cTrader such as the file system of your local machine. You can learn more in this tutorial.

Setting AccessRights to AccessRights.FullAccess allows algos to perform advanced operations (e.g., sourcing information from the Windows registry). The end users, however, may find giving cBots or indicators full access risky as it may lead to a data breach.

As a result, AccessRights.None is usually the most sensible option if you want to share your algo products with others. However, even if you choose this option, your cTrader products are free to access the web! The addition of the network access functionality to the cTrader Algo API means that cBots no longer require the AccessRights property to be set to AccessRights.FullAccess to work with resources on the Internet.

This greatly expands the opportunities algo developers have when coding cTrader products that they intend to distribute to other traders.

Summary

In conclusion, network access is a powerful feature that allows for greatly expanding the number of operations that your algorithms can perform while introducing no additional risks.