Zum Inhalt

Symboldaten abrufen

Das Abrufen und Interpretieren von Symboldaten (zum Beispiel der Eröffnungs- und Schlusskurse aller Bars für einen bestimmten Zeitraum) ist in jeder Anwendung mit einer der folgenden Funktionalitäten unerlässlich:

  • Charts – um Bar- oder Liniencharts zu erstellen, müssen Sie sowohl historische als auch Live-Bar- und Kursdaten kennen.
  • Marktstatistiken – wenn Sie Marktstatistiken (wie tägliche Preisänderungen für einzelne Symbole) anzeigen möchten, müssen Sie sowohl historische als auch Live-Preise abrufen.
  • Replays – in Ihrer Anwendung können Sie Händlern erlauben, zu einem früheren Zeitraum zurückzugehen und auf Basis historischer Daten zu handeln. Dazu müssten Sie vergangene Bar- und Tick-Daten abrufen und verarbeiten.

In diesem Tutorial zeigen wir Ihnen, wie Sie historische und Live-Bar- und Tick-Daten sowie Live-Markttiefe-Kurse abrufen und verarbeiten können.

Beachten Sie, dass das Tutorial nur einen Codeausschnitt zum Abrufen historischer Bar-Daten bereitstellt. Da die Kernlogik unabhängig von der ausgeführten Aktion gleich bleibt, können Sie diesen Ausschnitt anpassen, um andere Arten von Daten abzurufen.

Mit JSON arbeiten

Wenn Sie mit JSON arbeiten, können Sie weiterhin Code aus diesem Tutorial wiederverwenden; Sie müssten ihn jedoch je nach Ihrem Ansatz zur Serialisierung und Deserialisierung leicht anpassen.

Historische Bar-Daten abrufen

Um historische Bar-Daten zu erhalten, führen Sie die folgenden Aktionen aus:

  • Initialisieren Sie ein Objekt, das die Nachricht ProtoOAGetTrendbarsReq darstellt.
  • Füllen Sie die Objekteigenschaften mit der erforderlichen ctidTraderAccountId, der symbolId, dem ProtoOATrendbarPeriod, der count der zurückzugebenden Trendbars sowie den Unix-Zeitstempeln toTimestamp und fromTimestamp.

Zeitstempel-Einschränkungen

Beachten Sie, dass es einige Einschränkungen hinsichtlich des maximal möglichen Abstands zwischen toTimestamp und fromTimestamp gibt. Diese Einschränkungen hängen vom angegebenen ProtoOATrendPeriod ab. Um mehr zu erfahren, klicken Sie hier.

  • Senden Sie die neu erstellte Nachricht und erhalten Sie eine Antwort des Typs ProtoOAGetTrendbarsRes. Greifen Sie auf das Feld trendbar zu, um eine Liste von Trendbalken zu erhalten.
  • Wandeln Sie die Daten vom relativen Format in den tatsächlichen Symbolpreis um. Nehmen Sie dazu zunächst den niedrigsten Preis eines Trendbalkens und teilen Sie ihn durch 100000. Runden Sie dann das Ergebnis auf die Symbolstellen (zum Beispiel zwei Zahlen nach dem Trennzeichen). Um den höchsten, den Eröffnungs- und den Schlusspreis eines Trendbalkens zu erhalten, addieren Sie das Trendbalken-Delta jedes dieser Preise zum niedrigsten Preis des Trendbalkens. Teilen Sie anschließend jede Zahl durch 100000 und runden Sie das Ergebnis auf die Symbolstellen.

Sie können diese Aktionen durch Wiederverwendung des untenstehenden Codes durchführen.

 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

Historische Tick-Daten abrufen

Um historische Tick-Daten zu erhalten, führen Sie die folgenden Aktionen aus:

  • Initialisieren Sie ein Objekt, das die Nachricht ProtoOAGetTickDataReq darstellt.
  • Füllen Sie die Objekteigenschaften mit der erforderlichen ctidTraderAccountId, der symbolId, dem Kurs-type sowie fromTimestamp und toTimestamp.

Zeitstempel-Einschränkungen

Es ist nicht möglich, historische Tick-Daten für einen Zeitraum von mehr als einer Woche anzufordern. Daher darf die Differenz zwischen den angegebenen Werten toTimestamp und fromTimestamp nicht größer als 604800000 sein.

  • Senden Sie die neu erstellte Nachricht und erhalten Sie eine Antwort vom Typ ProtoOAGetTickDataRes. Greifen Sie auf das Feld tickData zu, um eine Liste von Elementen des Typs ProtoOATickData zu erhalten.
  • Wandeln Sie die Daten vom relativen Format in den tatsächlichen Symbolpreis um. Dividieren Sie dazu jeden Tick durch 100000 und runden Sie das Ergebnis auf Symbolstellen.

Anfordern einer großen Anzahl von Ticks

Es besteht eine Begrenzung für die Anzahl der Ticks, die in einer ProtoOAGetTickDataRes-Nachricht zurückgegeben werden können. Wird dieses Limit überschritten (zum Beispiel, wenn es im angegebenen Zeitraum eine erhebliche Anzahl von Ticks gab), enthält die Nachricht ProtoOAGetTickDataRes nur die ersten X Ticks, wobei X eine Zahl ist, die niedriger als das Tick-Limit ist. Das genaue Limit hängt von der Konfiguration des cTrader-Backends ab.

Um zu überprüfen, ob mehr Ticks vorhanden sind, als in der empfangenen Nachricht zurückgegeben wurden, verwenden Sie das Flag hasMore.

Live-Bar-Daten abrufen

Um Live-Bars zu erhalten, führen Sie die folgenden Aktionen aus:

  • Initialisieren Sie eine Variable, die die Nachricht ProtoOAGetTrendbarsReq darstellt.
  • Füllen Sie die Objekteigenschaften mit der erforderlichen ctidTraderAccountId, der symbolId, dem ProtoOATrendbarPeriod, der count der zurückzugebenden Trendbars sowie den Unix-Zeitstempeln toTimestamp und fromTimestamp.

Zeitstempel-Einschränkungen

Es gibt einige Einschränkungen hinsichtlich des maximal möglichen Abstands zwischen toTimestamp und fromTimestamp. Diese Einschränkungen hängen vom angegebenen ProtoOATrendPeriod ab. Um mehr zu erfahren, klicken Sie hier.

  • Senden Sie die neu erstellte Nachricht und erhalten Sie eine Antwort des Typs ProtoOAGetTrendbarsRes. Greifen Sie auf das Feld trendbar zu, um eine Liste von Trendbalken zu erhalten.

  • Wandeln Sie die Daten vom relativen Format in den tatsächlichen Symbolpreis um. Nehmen Sie dazu zunächst den niedrigsten Preis eines Trendbalkens und teilen Sie ihn durch 100000. Runden Sie dann das Ergebnis auf die Symbolstellen (zum Beispiel zwei Zahlen nach dem Trennzeichen). Um den höchsten, den Eröffnungs- und den Schlusspreis eines Trendbalkens zu erhalten, addieren Sie das Trendbalken-Delta jedes dieser Preise zum niedrigsten Preis des Trendbalkens. Teilen Sie anschließend jede Zahl durch 100000 und runden Sie das Ergebnis auf die Symbolstellen.

  • Initialisieren Sie ein Objekt, das die Nachricht ProtoOASubscribeLiveTrendbarReq darstellt.

  • Füllen Sie die Objekteigenschaften mit der erforderlichen ctidTraderAccountId, dem ProtoOATrendbarPeriod und der symbolId.

  • Verfahren Sie ebenso mit einem Objekt, das die Nachricht ProtoOASubscribeSpotsReq darstellt.

  • Senden Sie die Nachrichten ProtoOASubscribeSpotsReq und ProtoOASubscribeLiveTrendbarReq in dieser Reihenfolge und erhalten Sie Antworten der Typen ProtoOASubscribeSpotsRes und ProtoOASubscribeLiveTrenbarsRes. An diesem Punkt sind Sie für Live-Balkendaten abonniert und sollten Nachrichten des Typs ProtoOASpotEvent erhalten.

Live-Trendbalken abonnieren

Um erfolgreich Live-Trendbalken zu abonnieren, ist zunächst ein Abonnement für Spot-Ereignisse erforderlich.

  • Wenn Sie eine neue Nachricht ProtoOASpotEvent erhalten, verwenden Sie deren Feld trendbar, um die Daten für den letzten geschlossenen Balken zu erhalten.
  • Wandeln Sie die Daten vom relativen Format in die tatsächlichen Symbolpreise um. Nehmen Sie dazu zunächst den niedrigsten Preis eines Trendbalkens und teilen Sie ihn durch 100000. Runden Sie dann das Ergebnis auf die Symbolstellen (zum Beispiel zwei Zahlen nach dem Trennzeichen). Um den höchsten, den Eröffnungs- und den Schlusspreis eines Trendbalkens zu erhalten, addieren Sie das Trendbalken-Delta jedes dieser Preise zum niedrigsten Preis des Trendbalkens. Teilen Sie anschließend jede Zahl durch 100000 und runden Sie das Ergebnis auf die Symbolstellen.

Um die Abonnierung von Live-Trendbalkendaten aufzuheben, können Sie jederzeit die Nachricht ProtoOAUnsubscribeLiveTrendbarsReq senden, die die symbolId, den period und Ihre ctidTraderAccountId enthält. Wenn Ihre Anfrage erfolgreich ist, sollten Sie eine Antwort des Typs ProtoOAUnsubscribeLiveTrenbarRes erhalten. Ihr Abonnement für Spot-Ereignisse bleibt weiterhin bestehen.

Live-Kurse erhalten

Um Live-Geld- und Briefkurse für ein Symbol zu erhalten, führen Sie die folgenden Schritte aus:

  • Initialisieren Sie ein Objekt, das die Nachricht ProtoOASubscribeSpotsReq darstellt.
  • Füllen Sie die Objekteigenschaften mit der ctidTraderAccountId, der symbolId und optional dem booleschen Wert subscribeToSpotTimestamp.
  • Senden Sie die neu erstellte Nachricht und erhalten Sie eine Antwort des Typs ProtoOASubscribeSpotsRes. An diesem Punkt sind Sie für Live-Kursdaten abonniert und sollten Nachrichten des Typs ProtoOASpotEvent erhalten.
  • Wenn Sie eine neue Nachricht ProtoOASpotEvent erhalten, greifen Sie auf deren Felder bid und ask zu, um die aktuellsten Kurse zu erhalten. Beachten Sie, dass Sie die Daten weiterhin in einen tatsächlichen Preiswert umwandeln müssen, indem Sie sie durch 100000 teilen und auf die Symbolstellen runden.

Geld- und Brieffelder

Da die Felder bid und ask optional sind, sehen Sie möglicherweise nicht immer ProtoOASpotEvent-Nachrichten, in denen beide angegeben sind.

Um die Abonnierung von Kursdaten aufzuheben, können Sie jederzeit die Nachricht ProtoOAUnsubscribeSpotsReq senden, die die symbolId und Ihre ctidTraderAccountId enthält. Wenn Ihre Anfrage erfolgreich ist, sollten Sie eine Antwort des Typs ProtoOAUnsubscribeSpotsRes erhalten. An diesem Punkt sollten Sie keine Spot-Ereignisse mehr erhalten.

Tiefenkurse

Zu guter Letzt können Sie auch Live-Tiefen- oder Level-II-Kurse für ein Symbol erhalten. Führen Sie dazu die folgenden Schritte aus.

Sie können Live-Tiefen- oder Level-II-Kurse für ein Symbol von der API abonnieren und erhalten.

  • Initialisieren Sie ein Objekt, das die Nachricht ProtoOASubscribeDepthQuotesReq darstellt.
  • Füllen Sie die Objekteigenschaften mit der ctidTraderAccountId und der symbolId.
  • Senden Sie die neu erstellte Nachricht und erhalten Sie eine Antwort des Typs ProtoOASubscribeDepthQuotesRes. An diesem Punkt sind Sie für Tiefenkurse abonniert, was bedeutet, dass Sie beginnen sollten, ProtoOADepthEvent-Nachrichten zu erhalten.
  • Wenn Sie eine neue Nachricht ProtoOADepthEvent erhalten, müssen Sie deren Felder newQuotes und deletedQuotes verwenden, um die neuesten Tiefendaten zu erhalten. Sie müssen die Daten außerdem in einen tatsächlichen Preiswert umwandeln, indem Sie sie durch 100000 teilen und das Ergebnis auf die Symbolstellen runden. Sie müssen außerdem die Tiefenkursgröße in Einheiten umwandeln, indem Sie sie durch 100 teilen.

Um die Abonnierung von Tiefenereignissen aufzuheben, können Sie jederzeit die Nachricht ProtoOAUnsubscribeDepthQuotesReq verwenden und dabei die symbolId und die ctidTraderAccountId angeben. Sie sollten eine Nachricht des Typs ProtoOAUnsubscribeDepthQuotesRes erhalten; danach sollten Sie keine Tiefenereignisse mehr erhalten.