The Manager’s API is a powerful tool that allows for creating custom systems of communication with the cTrader backend. In essence, it enables you to perform nearly all major operations on server entities in a manner that is most convenient to you.
The Manager’s API uses Protocol Buffers (or Protobufs), a language and architecture-neutral solution originally developed by Google. Protobufs offer a lightweight and easy-to-use means for serializing structured data which makes them the ideal choice for transferring information between the cTrader backend and any custom control systems you may create.
Each Protobuf message consists of structured name-value pairs. Consider the following example.
message SampleSymbolUpdateReq {
required string symbolName = 1;
required int32 symbolID = 2;
required string baseAssetName = 3;
required string quoteAssetName = 4;
required UpdateOperation operation = 5;
}
The structure of Protobuf message is essentially a sequence of numbered fields. Each field may belong to a variety of types including string
, int32
, or even custom value types.
When sent between different solutions/applications, Protobuf messages are used to create objects of certain types directly from raw bytes. As a result, you can use a wide variety of programming languages and approaches when performing server-side integration using the Manager’s API.
As the Manager’s API is a powerful tool for integration purposes, using it improperly may have a detrimental effect on your cServer instances, potentially impacting the performance or even causing an outage. We therefore advise that you proceed with caution.
Protobufs constitute a lightweight tool for data serialization. Identifying the correct library to use for serializing and/or deserializing objects to and from Protobut messages will obviously vary according to the language you are using for integration, and in some cases several may exist. Many libraries also include some implementation of the protogen tool which allows you to automatically generate the appropriate classes and objects based on the .proto
files supplied by our support team.
This API uses syntax version 2 (Proto2), so please ensure that whichever library you select supports this version.
The examples below use C# syntax and the
protobuf-net
library.
All connections for the Manager’s API are handled by our proxy cloud, and are encrypted . You can obtain specific connection details from our support team. Establishing a connection is as simple as opening a TCP connection to port 5011 of the desired proxy, and then performing any necessary validation of the SSL certificate.
TcpClient client = new TcpClient();
client.Connect(proxyHost, proxyPort);
SslStream stream = new SslStream(client.GetStream(), false);
stream.AuthenticateAsClient(proxyHost);
Once you have successfully established connection to the proxy you will immediately receive the HelloEvent
message. To ensure that the connection stays open you shoud send a HeartbeatEvent
message every 25 seconds. The proxy will send its own HeartbeatEvent
message if no other data is being sent.
When reading messages from the stream, the first 4 bytes indiciate the length of the actual data. The message which follows is always wrapped within the ProtoMessage
structure, which is described below.
message ProtoMessage {
/*
* Contains the unsigned-integer representation of the payload type, which can be found from ProtoPayloadType
* or ProtoCSPayloadType enums.
*/
required uint32 payloadType = 1;
/*
* Contains the actual payload, which can be deserialized to the type identified by payloadType.
*/
optional bytes payload = 2;
/*
* A user-defined string which can be specified in requests sent to the proxy, and will be included in the
* corresponding response in order to allow matching it to the corresponding request.
*/
optional string clientMsgId = 3;
}
The process for working with received data can be broken down into four steps.
ProtoMessage
.ProtoMessage.payload
.ProtoMessage.payload
to the appropriate type.To extract the length of the payload you must first reverse the 4-byte array, and then convert it to an integer value.
// where bytes is the 4-byte array
Span<byte> lengthSpan = bytes.AsApan();
lengthSpan.Reverse();
int length = BitConverter.ToInt32(lengthSpan);
From this you can determine that the next length
bytes of the stream contain the actual message.
After the message has been read from the stream, you can then proceed to deserialize this data to the ProtoMessage
structure.
// assuming `buffer` is the byte array read from the stream
ProtoMessage message = Serializer.Deserialize<ProtoMessage>(new MemoryStream(buffer));
Once the ProtoMessage
has been deserialized, you can then use the ProtoMessage.payloadType
property to identify the type of ProtoMessage.payload
, and then proceed to deserializing of the contents.
With the appropriate type identified, you can now proceed to deserialize ProtoMessage.payload
to this type.
// assuming that `payloadType` represents the Type that you wish to deserialize to.
var payload = Serializer.Deserialize(payloadType, new MemoryStream(message.Payload));
Sending messages to the proxy follows the same basic principals as receiving, in that the payload should be wrapped within the ProtoMessage
structure, and a 4-byte array indicating the length prepended to the generated byte array.
ProtoHeartbeatEvent payload = new ProtoHeartbeatEvent();
MemoryStream payloadStream = new MemoryStream();
Serializer.Serialize(payloadStream, payload);
ProtoMessage message = new ProtoMessage()
{
PayloadType = ProtoPayloadType.PROTO_HEARTBEAT_EVENT,
Payload = payloadStream.ToArray()
};
MemoryStream messageStream = new MemoryStream();
Serializer.Serialize(messageStream, message);
byte[] bytes = messageStream.ToArray();
// calculate the length of bytes, reverse it, and append the `bytes` array to the result
byte[] data = BitConverter.GetBytes(bytes.Length).Reverse().Concat(bytes).ToArray();
The resulting data
array can then be written to the established stream.
Specifying
ProtoMessage.clientMsgId
is optional, but recommended when you need to match a specific response to the request.
Both the Reporting API and the Manager’s API are powerful tools that could be used for receiving statistics from the cTrader backend.
Compared to the Manager’s API, the Reporting API has several characteristics that limit its functionality to just reporting. The following table summarizes the main differences between the APIs.
Characteristic | Manager’s API | Reporting API |
---|---|---|
Authorization/authentication mechanism | Each participant has to be authorized using a special manager’s token which can only be received after gaining access to the cBroker back office. | There are no additional authorization/authentication mechanisms. The full functionality can be accessed by any manager from any business entity that has access to your server and knows the API connection details. |
Access rights | Each participant can only perform actions that they have specifically been granted permissions to perform in the cBroker back office. | Each participant can always perform all actions that are permitted by the API. |
Possible actions | Participants can receive statistics, manage trading conditions, oversee accounts, etc. | Participants can only receive statistics. |
As a result, integration with the Manager’s API is preferable in the following cases.
In any other case, integration with the Reporting API may be a valid alternative.
This guide is not intended as a full-scale documentation for the Manager’s API, nor does it contain links to the Protobuf files that include the full API structure.
Instead, the guide lists the key types of messages included in the Manager’s API and their definitions. You can consult it to attain a general idea of what you can do when using the Manager’s API. To request access to the .proto
files containing the fields included in each message as well as model messages (custom value types used in the API), please contact Spotware’s service assurance team.
The guide is separated into four sub-sections.