Saltar a contenido

Obtener datos de símbolos

Obtener e interpretar datos de símbolos (por ejemplo, los precios de apertura y cierre de todas las barras para un período específico) es esencial en cualquier aplicación que tenga alguna de las siguientes funcionalidades:

  • Gráficos – para construir gráficos de barras o líneas, necesita conocer tanto los datos históricos como en vivo de barras y cotizaciones.
  • Estadísticas de mercado – si desea mostrar estadísticas de mercado (como cambios de precios diarios para símbolos individuales), debe obtener tanto precios históricos como en vivo.
  • Reproducciones – en su aplicación, puede permitir que los operadores regresen a un período anterior y operen con datos históricos. Para hacerlo, necesitaría obtener y procesar datos históricos de barras y tics.

En este tutorial, mostraremos cómo puede obtener y procesar datos históricos y en tiempo real de barras y tics, y cotizaciones de profundidad en tiempo real.

Tenga en cuenta que el tutorial solo proporciona un fragmento de código para obtener datos históricos de barras. Como la lógica central sigue siendo la misma independientemente de la acción que esté realizando, puede adaptar este fragmento para obtener otros tipos de datos.

Operar con JSON

Cuando opere con JSON, aún puede reutilizar código de este tutorial; sin embargo, necesitaría modificarlo ligeramente según su enfoque de serialización y deserialización.

Obtener datos históricos de barras

Para recibir datos históricos de barras, realice las siguientes acciones:

  • Inicialice un objeto que represente el mensaje ProtoOAGetTrendbarsReq.
  • Complete las propiedades del objeto con el ctidTraderAccountId requerido, el symbolId, el ProtoOATrendbarPeriod, el count de trendbars a devolver y las marcas de tiempo Unix toTimestamp y fromTimestamp.

Restricciones de marca de tiempo

Tenga en cuenta que existen algunas restricciones sobre la distancia máxima posible entre toTimestamp y fromTimestamp. Estas restricciones dependen del ProtoOATrendPeriod especificado. Para saber más, haga clic aquí.

  • Envíe el mensaje recién creado y reciba una respuesta del tipo ProtoOAGetTrendbarsRes. Acceda a su campo trendbar para obtener una lista de barras de tendencia.
  • Transforme los datos del formato relativo al precio real del símbolo. Para hacerlo, primero obtenga el precio bajo de una barra de tendencia y divídalo por 100000. Luego, redondee el resultado a los dígitos del símbolo (por ejemplo, dos números después del delimitador). Para obtener los precios alto, de apertura y cierre de una barra de tendencia, agregue el delta de la barra de tendencia de cada uno de estos precios al precio bajo de la barra de tendencia. Después, divida cada número por 100000 y redondee el resultado a los dígitos del símbolo.

Puede completar estas acciones reutilizando el código a continuación.

 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

Obtener datos históricos de tics

Para recibir datos históricos de tics, realice las siguientes acciones:

  • Inicialice un objeto que represente el mensaje ProtoOAGetTickDataReq.
  • Complete las propiedades del objeto con el ctidTraderAccountId requerido, el symbolId, el type de cotización así como el fromTimestamp y el toTimestamp.

Restricciones de marca de tiempo

Es imposible solicitar datos históricos de tics para un período mayor a una semana. Por lo tanto, la diferencia entre el toTimestamp y el fromTimestamp especificados no debe ser mayor a 604800000.

  • Envíe el mensaje recién creado y reciba una respuesta del tipo ProtoOAGetTickDataRes. Acceda a su campo tickData para obtener una lista de elementos del tipo ProtoOATickData.
  • Transforme los datos del formato relativo al precio real del símbolo. Para hacerlo, divida cada tic por 100000 y redondee el resultado a los dígitos del símbolo.

Solicitar un gran número de tics

Existe un límite en el número de tics que pueden devolverse en un mensaje ProtoOAGetTickDataRes. Si se excede este límite (por ejemplo, ha habido un número significativo de tics durante el período especificado), el mensaje ProtoOAGetTickDataRes solo incluirá los primeros X tics, donde X es un número inferior al límite de tics. El límite exacto depende de la configuración del backend de cTrader.

Para verificar si existen más tics que los que se han devuelto en el mensaje recibido, use la bandera hasMore.

Obtener datos de barras en tiempo real

Para recibir barras en tiempo real, realice las siguientes acciones:

  • Inicialice una variable que represente el mensaje ProtoOAGetTrendbarsReq.
  • Complete las propiedades del objeto con el ctidTraderAccountId requerido, el symbolId, el ProtoOATrendbarPeriod, el count de trendbars a devolver, los timestamps Unix toTimestamp y fromTimestamp.

Restricciones de marca de tiempo

Existen algunas restricciones sobre la distancia máxima posible entre el toTimestamp y el fromTimestamp. Estas restricciones dependen del ProtoOATrendPeriod especificado. Para saber más, haga clic aquí.

  • Envíe el mensaje recién creado y reciba una respuesta del tipo ProtoOAGetTrendbarsRes. Acceda a su campo trendbar para obtener una lista de barras de tendencia.

  • Transforme los datos del formato relativo al precio real del símbolo. Para hacerlo, primero obtenga el precio bajo de un trendbar y divídalo por 100000. Luego, redondee el resultado a los dígitos del símbolo (por ejemplo, dos números después del delimitador). Para obtener los precios alto, de apertura y cierre de una barra de tendencia, agregue el delta de la barra de tendencia de cada uno de estos precios al precio bajo de la barra de tendencia. Después, divida cada número por 100000 y redondee el resultado a los dígitos del símbolo.

  • Inicialice un objeto que represente el mensaje ProtoOASubscribeLiveTrendbarReq.

  • Complete las propiedades del objeto con el ctidTraderAccountId requerido, el ProtoOATrendbarPeriod y el symbolId.

  • Haga lo mismo para un objeto que represente el mensaje ProtoOASubscribeSpotsReq.

  • Envíe el mensaje ProtoOASubscribeSpotsReq y el mensaje ProtoOASubscribeLiveTrendbarReq en ese orden y reciba respuestas de los tipos ProtoOASubscribeSpotsRes y ProtoOASubscribeLiveTrenbarsRes. En este punto, está suscrito a los datos de barras en vivo y debería recibir mensajes del tipo ProtoOASpotEvent.

Suscribirse a trendbars en vivo

Para suscribirse exitosamente a trendbars en vivo primero se requiere una suscripción a eventos spot.

  • Cuando reciba un nuevo mensaje ProtoOASpotEvent, use su campo trendbar para obtener los datos de la última barra cerrada.
  • Transforme los datos del formato relativo a los precios reales del símbolo. Para hacerlo, primero obtenga el precio bajo de una barra de tendencia y divídalo por 100000. Luego, redondee el resultado a los dígitos del símbolo (por ejemplo, dos números después del delimitador). Para obtener los precios alto, de apertura y cierre de una barra de tendencia, agregue el delta de la barra de tendencia de cada uno de estos precios al precio bajo de la barra de tendencia. Después, divida cada número por 100000 y redondee el resultado a los dígitos del símbolo.

Para cancelar la suscripción a datos de trendbar en vivo, siempre puede enviar el mensaje ProtoOAUnsubscribeLiveTrendbarsReq que contenga el symbolId, el period y su ctidTraderAccountId. Si su solicitud es exitosa, debería recibir una respuesta del tipo ProtoOAUnsubscribeLiveTrenbarRes. Su suscripción a eventos spot permanecerá.

Obtener cotizaciones en vivo

Para recibir cotizaciones de oferta y demanda en vivo para un símbolo, realice las siguientes acciones:

  • Inicialice un objeto que represente el mensaje ProtoOASubscribeSpotsReq.
  • Complete las propiedades del objeto con el ctidTraderAccountId, el symbolId y, opcionalmente, el booleano subscribeToSpotTimestamp.
  • Envíe el mensaje recién creado y reciba una respuesta del tipo ProtoOASubscribeSpotsRes. En este punto, está suscrito a los datos de cotizaciones en vivo y debería recibir mensajes del tipo ProtoOASpotEvent.
  • Cuando reciba un nuevo mensaje ProtoOASpotEvent, acceda a sus campos bid y ask para obtener las últimas cotizaciones. Tenga en cuenta que aún debe transformar los datos en un valor de precio real dividiéndolo por 100000 y redondeándolo a los dígitos del símbolo.

Campos de oferta y demanda

Como los campos bid y ask son opcionales, es posible que no vea necesariamente mensajes ProtoOASpotEvent donde ambos estén especificados.

Para cancelar la suscripción a los datos de cotizaciones, siempre puede enviar el mensaje ProtoOAUnsubscribeSpotsReq que contenga el symbolId y su ctidTraderAccountId. Si su solicitud es exitosa, debería recibir una respuesta del tipo ProtoOAUnsubscribeSpotsRes. En este punto, debería dejar de recibir eventos spot.

Cotizaciones de profundidad

Por último, pero no menos importante, también puede recibir cotizaciones en vivo de profundidad o de Nivel II para un símbolo. Para hacerlo, realice las siguientes acciones.

Puede suscribirse y recibir cotizaciones en vivo de profundidad o de Nivel II para un símbolo desde la API.

  • Inicialice un objeto que represente el mensaje ProtoOASubscribeDepthQuotesReq.
  • Complete las propiedades del objeto con el ctidTraderAccountId y el symbolId.
  • Envíe el mensaje recién creado y reciba una respuesta del tipo ProtoOASubscribeDepthQuotesRes. En este punto, está suscrito a las cotizaciones de profundidad, lo que significa que debería comenzar a recibir mensajes ProtoOADepthEvent.
  • Cuando reciba un nuevo mensaje ProtoOADepthEvent, necesitará usar sus campos newQuotes y deletedQuotes para obtener los últimos datos de profundidad. También necesitará transformar los datos en un valor de precio real dividiéndolo por 100000 y redondeando el resultado a los dígitos del símbolo. También necesitará transformar el tamaño de la cotización de profundidad en unidades dividiéndolo por 100.

Para cancelar la suscripción a los eventos de profundidad, siempre puede usar el mensaje ProtoOAUnsubscribeDepthQuotesReq especificando el symbolId y el ctidTraderAccountId. Debería recibir un mensaje del tipo ProtoOAUnsubscribeDepthQuotesRes; después, debería dejar de recibir eventos de profundidad.