Ir para o conteúdo

Obter dados de símbolos

Obter e interpretar dados de símbolos (por exemplo, os preços de abertura e fecho de todas as barras para um período específico) é essencial em qualquer aplicação que tenha qualquer uma das seguintes funcionalidades:

  • Gráficos – para construir gráficos de barras ou linhas, precisa de conhecer tanto os dados históricos como os dados em tempo real das barras e cotações.
  • Estatísticas de mercado – se quiser exibir estatísticas de mercado (como alterações diárias de preços para símbolos individuais), tem de obter tanto preços históricos como em tempo real.
  • Replays – na sua aplicação, pode permitir que os traders voltem a um período anterior e negoceiem com dados históricos. Para isso, precisaria de obter e processar dados passados de barras e ticks.

Neste tutorial, mostraremos como pode obter e processar dados históricos e em tempo real de barras e ticks, e cotações de profundidade em tempo real.

Note que o tutorial apenas fornece um excerto de código para obter dados históricos de barras. Como a lógica central permanece a mesma independentemente da ação que está a executar, pode adaptar este excerto para obter outros tipos de dados.

Operar com JSON

Ao operar com JSON, ainda pode reutilizar código deste tutorial; no entanto, precisaria de o modificar ligeiramente dependendo da sua abordagem à serialização e desserialização.

Obter dados históricos de barras

Para receber dados históricos de barras, execute as seguintes ações:

  • Inicialize um objeto que representa a mensagem ProtoOAGetTrendbarsReq.
  • Preencha as propriedades do objeto com o ctidTraderAccountId necessário, o symbolId, o ProtoOATrendbarPeriod, a count de trendbars a retornar e os timestamps Unix toTimestamp e fromTimestamp.

Restrições de carimbo de data

Note que existem algumas restrições sobre a distância máxima possível entre o toTimestamp e o fromTimestamp. Estas restrições dependem do ProtoOATrendPeriod especificado. Para saber mais, clique aqui.

  • Envie a mensagem recém-criada e receba uma resposta do tipo ProtoOAGetTrendbarsRes. Aceda ao seu campo trendbar para obter uma lista de barras de tendência.
  • Transforme os dados do formato relativo para o preço real do símbolo. Para isso, primeiro obtenha o preço baixo de uma barra de tendência e divida-o por 100000. Em seguida, arredonde o resultado para os dígitos do símbolo (por exemplo, dois números após o delimitador). Para obter os preços alto, de abertura e fecho de uma barra de tendência, adicione o delta da barra de tendência de cada um destes preços ao preço baixo da barra de tendência. Depois, divida cada número por 100000 e arredonde o resultado para os dígitos do símbolo.

Pode completar estas ações reutilizando o código abaixo.

 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
private static async void TrendbarRequest(ProtoOATrendbarPeriod period, int accountId, int symbolId, int days)
{
    Console.WriteLine("Sending ProtoOAGetTrendbarsReq...");

    var request = new ProtoOAGetTrendbarsReq
    {
        CtidTraderAccountId = accountId,
        SymbolId = symbolId,
        Period = period,
        FromTimestamp = DateTimeOffset.UtcNow.AddDays(-days).ToUnixTimeMilliseconds(),
        ToTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
    };

    Console.WriteLine($"FromTimestamp: {request.FromTimestamp} | ToTimestamp: {request.ToTimestamp}");

    await _client.SendMessage(request);
}

public static double GetPriceFromRelative(ProtoOASymbol symbol, long relative) => Math.Round(relative / 100000.0, symbol.Digits);

private List<Trendbar> OnHistoricalTrendbarsReceived(ProtoOAGetTrendbarsRes message) 
{
    var trendbars = message.Trendbar;

    var data = new List<Trendbar>();

    foreach (var trendbar in trendbars) 
    {
        data.Add(new Trendbar
        {
            Low = GetPriceFromRelative(symbol, trendbar.Low),
            High = GetPriceFromRelative(symbol, trendbar.Low + (int)trendbar.DeltaHigh),
            Open = GetPriceFromRelative(symbol, trendbar.Low + (int)trendbar.DeltaOpen),
            Close = GetPriceFromRelative(symbol, trendbar.Low + (int)trendbar.DeltaClose),
        }
        );
    }

    return data;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def sendProtoOAGetTrendbarsReq(ctidTraderAccountId, weeks, period, symbolId, clientMsgId = None):
    request = ProtoOAGetTrendbarsReq()
    request.ctidTraderAccountId = ctidTraderAccountId
    request.period = ProtoOATrendbarPeriod.Value(period)
    request.fromTimestamp = int(calendar.timegm((datetime.datetime.utcnow() - datetime.timedelta(weeks=int(weeks))).utctimetuple())) * 1000
    request.toTimestamp = int(calendar.timegm(datetime.datetime.utcnow().utctimetuple())) * 1000
    request.symbolId = int(symbolId)
    deferred = client.send(request, clientMsgId = clientMsgId)

def getPriceFromRelative(symbol, relative): round(relative / 100000.0, symbol.digits)

def onHistoricalTrendbarsReceived(message):

    trendbars = message.trendbars

    data = []

    for trendbar in trenbars:
        data.append(Trendbar(low=getPriceFromRelative(symbol, trendbar.low), high=getPriceFromRelative(symbol, trendbar.low + int(trendbar.deltaHigh)), open=getPriceFromRelative(symbol, trendbar.low + int(trendbar.deltaHigh)), close=getPriceFromRelative(symbol, trendbar.low +int(trendbar.deltaClose))))

    return data

Obter dados históricos de ticks

Para receber dados históricos de ticks, execute as seguintes ações:

  • Inicialize um objeto representando a mensagem ProtoOAGetTickDataReq.
  • Preencha as propriedades do objeto com o ctidTraderAccountId necessário, o symbolId, o type da cotação, bem como o fromTimestamp e o toTimestamp.

Restrições de carimbo de data

É impossível solicitar dados históricos de ticks para um período superior a uma semana. Como tal, a diferença entre o toTimestamp e o fromTimestamp especificados não deve ser superior a 604800000.

  • Envie a mensagem recém-criada e receba uma resposta do tipo ProtoOAGetTickDataRes. Aceda ao seu campo tickData para obter uma lista de elementos do tipo ProtoOATickData.
  • Transforme os dados do formato relativo para o preço real do símbolo. Para isso, divida cada tick por 100000 e arredonde o resultado para os dígitos do símbolo.

A solicitar um grande número de ticks

Existe um limite no número de ticks que podem ser retornados numa mensagem ProtoOAGetTickDataRes. Se este limite for excedido (por exemplo, houve um número significativo de ticks durante o período especificado), a mensagem ProtoOAGetTickDataRes incluirá apenas os primeiros X ticks, onde X é um número inferior ao limite de ticks. O limite exato depende da configuração do backend do cTrader.

Para verificar se existem mais ticks do que os que foram retornados na mensagem recebida, use a flag hasMore.

Obter dados de barras em tempo real

Para receber barras em tempo real, execute as seguintes ações:

  • Inicialize uma variável representando a mensagem ProtoOAGetTrendbarsReq.
  • Preencha as propriedades do objeto com o ctidTraderAccountId necessário, o symbolId, o ProtoOATrendbarPeriod, a count de barras de tendência a retornar, o toTimestamp e fromTimestamp Unix timestamps.

Restrições de carimbo de data

Existem algumas restrições sobre a distância máxima possível entre o toTimestamp e o fromTimestamp. Estas restrições dependem do ProtoOATrendPeriod especificado. Para saber mais, clique aqui.

  • Envie a mensagem recém-criada e receba uma resposta do tipo ProtoOAGetTrendbarsRes. Aceda ao seu campo trendbar para obter uma lista de barras de tendência.

  • Transforme os dados do formato relativo para o preço real do símbolo. Para isso, primeiro obtenha o preço baixo de uma barra de tendência e divida-o por 100000. Em seguida, arredonde o resultado para os dígitos do símbolo (por exemplo, dois números após o delimitador). Para obter os preços alto, de abertura e fecho de uma barra de tendência, adicione o delta da barra de tendência de cada um destes preços ao preço baixo da barra de tendência. Depois, divida cada número por 100000 e arredonde o resultado para os dígitos do símbolo.

  • Inicialize um objeto representando a mensagem ProtoOASubscribeLiveTrendbarReq.

  • Preencha as propriedades do objeto com o ctidTraderAccountId necessário, o ProtoOATrendbarPeriod e o symbolId.

  • Faça o mesmo para um objeto representando a mensagem ProtoOASubscribeSpotsReq.

  • Envie a mensagem ProtoOASubscribeSpotsReq e a mensagem ProtoOASubscribeLiveTrendbarReq nessa ordem e receba respostas dos tipos ProtoOASubscribeSpotsRes e ProtoOASubscribeLiveTrenbarsRes. Neste momento, está subscrito aos dados de barras em tempo real e deverá receber mensagens do tipo ProtoOASpotEvent.

Subscrever a barras de tendência em tempo real

A subscrição bem-sucedida de trendbars em tempo real requer primeiro uma subscrição de eventos spot.

  • Quando receber uma nova mensagem ProtoOASpotEvent, utilize o seu campo trendbar para obter os dados da última barra fechada.
  • Transforme os dados do formato relativo para os preços reais do símbolo. Para isso, primeiro obtenha o preço baixo de uma barra de tendência e divida-o por 100000. Em seguida, arredonde o resultado para os dígitos do símbolo (por exemplo, dois números após o delimitador). Para obter os preços alto, de abertura e fecho de uma barra de tendência, adicione o delta da barra de tendência de cada um destes preços ao preço baixo da barra de tendência. Depois, divida cada número por 100000 e arredonde o resultado para os dígitos do símbolo.

Para cancelar a subscrição de dados de trendbar em tempo real, pode sempre enviar a mensagem ProtoOAUnsubscribeLiveTrendbarsReq contendo o symbolId, o period e o seu ctidTraderAccountId. Se o seu pedido for bem-sucedido, deverá receber uma resposta do tipo ProtoOAUnsubscribeLiveTrenbarRes. A sua subscrição de eventos spot permanecerá ativa.

Obter cotações em tempo real

Para receber cotações de venda e compra em tempo real para um símbolo, execute as seguintes ações:

  • Inicialize um objeto que represente a mensagem ProtoOASubscribeSpotsReq.
  • Preencha as propriedades do objeto com o ctidTraderAccountId, o symbolId e, opcionalmente, o bool subscribeToSpotTimestamp.
  • Envie a mensagem recém-criada e receba uma resposta do tipo ProtoOASubscribeSpotsRes. Neste momento, está subscrito aos dados de cotações em tempo real e deverá receber mensagens do tipo ProtoOASpotEvent.
  • Quando receber uma nova mensagem ProtoOASpotEvent, aceda aos seus campos bid e ask para obter as últimas cotações. Note que ainda tem de transformar os dados num valor de preço real dividindo-o por 100000 e arredondando-o para os dígitos do símbolo.

Campos de venda e compra

Como os campos bid e ask são opcionais, pode não ver necessariamente mensagens ProtoOASpotEvent onde ambos estejam especificados.

Para cancelar a subscrição de dados de cotações, pode sempre enviar a mensagem ProtoOAUnsubscribeSpotsReq contendo o symbolId e o seu ctidTraderAccountId. Se o seu pedido for bem-sucedido, deverá receber uma resposta do tipo ProtoOAUnsubscribeSpotsRes. Neste momento, deverá parar de receber eventos spot.

Cotações de profundidade

Por último, mas não menos importante, também pode receber cotações de profundidade ou de Nível II em tempo real para um símbolo. Para tal, execute as seguintes ações.

Pode subscrever e receber cotações de profundidade ou de Nível II em tempo real para um símbolo a partir da API.

  • Inicialize um objeto que represente a mensagem ProtoOASubscribeDepthQuotesReq.
  • Preencha as propriedades do objeto com o ctidTraderAccountId e o symbolId.
  • Envie a mensagem recém-criada e receba uma resposta do tipo ProtoOASubscribeDepthQuotesRes. Neste momento, está subscrito às cotações de profundidade, o que significa que deverá começar a receber mensagens ProtoOADepthEvent.
  • Quando receber uma nova mensagem ProtoOADepthEvent, precisará de utilizar os seus campos newQuotes e deletedQuotes para obter os dados de profundidade mais recentes. Também precisará de transformar os dados num valor de preço real dividindo-o por 100000 e arredondando o resultado para os dígitos do símbolo. Também precisará de transformar o tamanho da cotação de profundidade em unidades dividindo-o por 100.

Para cancelar a subscrição de eventos de profundidade, pode sempre utilizar a mensagem ProtoOAUnsubscribeDepthQuotesReq especificando o symbolId e o ctidTraderAccountId. Deverá receber uma mensagem do tipo ProtoOAUnsubscribeDepthQuotesRes; depois disso, deverá parar de receber eventos de profundidade.