コンテンツにスキップ

シンボルデータを取得する

シンボルデータを取得し、解釈すること(例えば、特定の期間のすべてのバーの開始価格と終了価格)は、以下の機能のいずれかを持つアプリケーションでは不可欠です:

  • チャート – バーまたはラインチャートを構築するためには、過去およびライブのバーとクォートデータを知る必要があります。
  • 市場統計 – 市場統計(例えば、個々のシンボルの日々の価格変動)を表示したい場合、過去およびライブの価格を取得する必要があります。
  • リプレイ – アプリケーションでは、トレーダーが過去の期間に戻って過去のデータで取引できるようにすることができます。 そのためには、過去のバーとティックデータを取得し、処理する必要があります。

このチュートリアルでは、過去およびライブのバーとティックデータ、およびライブの深度クォートを取得し、処理する方法を示します。

チュートリアルでは、過去のバーデータを取得するためのコードスニペットのみを提供していることに注意してください。 実行するアクションに関係なく、コアロジックは同じであるため、このスニペットを他のタイプのデータを取得するために適応させることができます。

JSONを操作する

JSONを操作する場合でも、このチュートリアルのコードを再利用できますが、シリアライゼーションとデシリアライゼーションのアプローチに応じて、少し変更する必要があります。

過去のバーデータを取得する

過去のバーデータを受信するには、次のアクションを実行します:

  • ProtoOAGetTrendbarsReqメッセージを表すオブジェクトを初期化します。
  • オブジェクトのプロパティに必要なctidTraderAccountIdsymbolIdProtoOATrendbarPeriod、返すトレンドバーのcount、およびtoTimestampfromTimestampのUnixタイムスタンプを入力します。

タイムスタンプの制約

toTimestampfromTimestampの間の最大可能な距離にはいくつかの制約があることに注意してください。 これらの制約は、指定されたProtoOATrendPeriodに依存します。 詳細は、こちらをクリックしてください。

  • 新しく作成したメッセージを送信し、ProtoOAGetTrendbarsResタイプの応答を受け取ります。 そのtrendbarフィールドにアクセスして、トレンドバーのリストを取得します。
  • データを相対形式から実際のシンボル価格に変換します。 これを行うには、まずトレンドバーの安値を取得し、それを100000で割ります。 次に、結果をシンボルの桁数(例えば、区切り文字の後の2桁)に丸めます。 トレンドバーの高値、始値、終値を取得するには、これらの各価格のトレンドバーデルタをトレンドバーの安値に加えます。 その後、各数値を100000で割り、結果をシンボルの桁数に丸めます。

以下のコードを再利用してこれらのアクションを完了できます。

 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

過去のティックデータを取得する

過去のティックデータを受け取るには、以下のアクションを実行します:

  • ProtoOAGetTickDataReqメッセージを表すオブジェクトを初期化します。
  • オブジェクトのプロパティに必要なctidTraderAccountIdsymbolId、引用type、およびfromTimestamptoTimestampを入力します。

タイムスタンプの制約

1週間以上の期間の過去のティックデータをリクエストすることはできません。 そのため、指定されたtoTimestampfromTimestampの差は604800000を超えてはいけません。

  • 新しく作成したメッセージを送信し、ProtoOAGetTickDataResタイプの応答を受け取ります。 そのtickDataフィールドにアクセスして、ProtoOATickDataタイプの要素のリストを取得します。
  • データを相対形式から実際のシンボル価格に変換します。 これを行うには、各ティックを100000で割り、結果をシンボルの桁数に丸めます。

多数のティックをリクエストする

ProtoOAGetTickDataResメッセージで返されるティックの数には制限があります。 この制限を超えた場合(例えば、指定された期間中にティックが大量にあった場合)、ProtoOAGetTickDataResメッセージには最初のXティックのみが含まれます。ここで、Xはティック制限よりも小さい数です。 正確な制限はcTraderバックエンドの設定に依存します。

受信したメッセージで返されたティックよりも多くのティックが存在するかどうかを確認するには、hasMoreフラグを使用します。

ライブバーデータを取得する

ライブバーを受け取るには、以下のアクションを実行します:

  • ProtoOAGetTrendbarsReqメッセージを表す変数を初期化します。
  • オブジェクトのプロパティに必要なctidTraderAccountIdsymbolIdProtoOATrendbarPeriod、返すトレンドバーのcounttoTimestampおよびfromTimestampのUnixタイムスタンプを入力します。

タイムスタンプの制約

toTimestampfromTimestampの間の最大可能な距離にはいくつかの制約があります。 これらの制約は、指定されたProtoOATrendPeriodに依存します。 詳細は、こちらをクリックしてください。

  • 新しく作成したメッセージを送信し、ProtoOAGetTrendbarsResタイプの応答を受け取ります。 そのtrendbarフィールドにアクセスして、トレンドバーのリストを取得します。

  • データを相対形式から実際のシンボル価格に変換します。 これを行うには、まずトレンドバーの安値を取得し、それを100000で割ります。 次に、結果をシンボルの桁数(例えば、区切り文字の後の2桁)に丸めます。 トレンドバーの高値、始値、終値を取得するには、これらの各価格のトレンドバーデルタをトレンドバーの安値に加えます。 その後、各数値を100000で割り、結果をシンボルの桁数に丸めます。

  • ProtoOASubscribeLiveTrendbarReqメッセージを表すオブジェクトを初期化します。

  • オブジェクトのプロパティに必要なctidTraderAccountIdProtoOATrendbarPeriod、およびsymbolIdを入力します。

  • ProtoOASubscribeSpotsReqメッセージを表すオブジェクトについても同様に行います。

  • ProtoOASubscribeSpotsReqメッセージとProtoOASubscribeLiveTrendbarReqメッセージをその順序で送信し、ProtoOASubscribeSpotsResおよびProtoOASubscribeLiveTrenbarsResタイプの応答を受け取ります。 この時点で、ライブバーデータにサブスクライブされており、ProtoOASpotEventタイプのメッセージを受け取るはずです。

ライブトレンドバーにサブスクライブする

ライブトレンドバーに正常にサブスクライブするには、まずスポットイベントにサブスクライブする必要があります。

  • 新しいProtoOASpotEventメッセージを受信したら、そのtrendbarフィールドを使用して最後に閉じたバーのデータを取得します。
  • 相対形式のデータを実際のシンボル価格に変換します。 これを行うには、まずトレンドバーの安値を取得し、それを100000で割ります。 次に、結果をシンボルの桁数(例えば、区切り文字の後の2桁)に丸めます。 トレンドバーの高値、始値、終値を取得するには、これらの各価格のトレンドバーデルタをトレンドバーの安値に加えます。 その後、各数値を100000で割り、結果をシンボルの桁数に丸めます。

ライブトレンドバーデータの購読を解除するには、symbolIdperiod、およびctidTraderAccountIdを含むProtoOAUnsubscribeLiveTrendbarsReqメッセージを送信できます。 リクエストが成功した場合、ProtoOAUnsubscribeLiveTrenbarResタイプのレスポンスを受信するはずです。 スポットイベントの購読は引き続き維持されます。

ライブクォートを取得する

シンボルのライブ売値と買値を取得するには、次のアクションを実行します。

  • ProtoOASubscribeSpotsReqメッセージを表すオブジェクトを初期化します。
  • オブジェクトのプロパティにctidTraderAccountIdsymbolId、およびオプションでsubscribeToSpotTimestampブール値を入力します。
  • 新しく作成したメッセージを送信し、ProtoOASubscribeSpotsResタイプのレスポンスを受信します。 この時点で、ライブクォートデータに購読しており、ProtoOASpotEventタイプのメッセージを受信するはずです。
  • 新しいProtoOASpotEventメッセージを受信したら、そのbidaskフィールドにアクセスして最新のクォートを取得します。 データを100000で割り、シンボルの桁数に丸めることで、実際の価格値に変換する必要があることに注意してください。

売値と買値フィールド

bidaskフィールドはオプションであるため、両方が指定されているProtoOASpotEventメッセージが必ずしも表示されるわけではありません。

クォートデータの購読を解除するには、symbolIdctidTraderAccountIdを含むProtoOAUnsubscribeSpotsReqメッセージを送信できます。 リクエストが成功した場合、ProtoOAUnsubscribeSpotsResタイプのレスポンスを受信するはずです。 この時点で、スポットイベントの受信を停止するはずです。

デプスクォート

最後に、シンボルのライブデプスまたはレベルIIクォートも取得できます。 これを行うには、次のアクションを実行します。

APIからシンボルのライブデプスまたはレベルIIクォートを購読して受信できます。

  • ProtoOASubscribeDepthQuotesReqメッセージを表すオブジェクトを初期化します。
  • オブジェクトのプロパティにctidTraderAccountIdsymbolIdを入力します。
  • 新しく作成したメッセージを送信し、ProtoOASubscribeDepthQuotesResタイプのレスポンスを受信します。 この時点で、デプスクォートに購読しており、ProtoOADepthEventメッセージの受信を開始するはずです。
  • 新しいProtoOADepthEventメッセージを受信したら、そのnewQuotesdeletedQuotesフィールドを使用して最新のデプスデータを取得する必要があります。 また、データを100000で割り、結果をシンボルの桁数に丸めることで、実際の価格値に変換する必要があります。 また、デプスクォートサイズを100で割ることで単位に変換する必要があります。

デプスイベントの購読を解除するには、symbolIdctidTraderAccountIdを指定してProtoOAUnsubscribeDepthQuotesReqメッセージを使用できます。 ProtoOAUnsubscribeDepthQuotesResタイプのメッセージを受信するはずです。その後、デプスイベントの受信を停止するはずです。