ラズパイのC#でbitFlyerの板を取得(Json.NETでデシリアライズ)~ビットコイン自動売買の準備~

「ラズパイのC#でbitFlyerの板を取得」の続きです。
今回はJson.NETを使ってbitFlyerの板データをC#のオブジェクトに変換してみます。
標準ライブラリでもJSON形式のデータを扱えますが、どうやら性能的にはJson.NETが優れているようなので、これを使うことにします。

Json.NETはこちらからダウンロードします。
www.newtonsoft.com


とりあえずDownloadボタンをクリックするとこちらのポップアップが開きます。
ダイレクトダウンロードを選択します。
f:id:zhihong:20170910222124p:plain
解凍して得られる"Bin/net45/Newtonsoft.Json.dll"が必要なdllです。
適当なディレクトリに置いておきます。


板のユーザモデルはこんな感じです。
仲値,買い気配配列,売り気配配列がメンバ変数になっています。
気配は価格とサイズをメンバ変数に持ったクラスです。

[JsonObject]
public class Board
{
    [JsonProperty("mid_price")]
    public string MidPrice { get; set; }

    [JsonProperty("bids")]
    public Quote[] Bids { get; set; }

    [JsonProperty("asks")]
    public Quote[] Asks { get; set; }

    [JsonObject]
    public class Quote
    {
        [JsonProperty("price")]
        public string Price { get; set; }

        [JsonProperty("size")]
        public string Size { get; set; }
    }
}


シリアライズ部分です。
responseがJSON形式の文字列です。

Board board = JsonConvert.DeserializeObject<Board>(response);


ソースコード全体はこんな感じになります。
最良気配から5本だけ表示するようにしてみます。

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;

[JsonObject]
public class Board
{
    [JsonProperty("mid_price")]
    public string MidPrice { get; set; }

    [JsonProperty("bids")]
    public Quote[] Bids { get; set; }

    [JsonProperty("asks")]
    public Quote[] Asks { get; set; }

    [JsonObject]
    public class Quote
    {
        [JsonProperty("price")]
        public string Price { get; set; }

        [JsonProperty("size")]
        public string Size { get; set; }
    }
}

class Sample
{
    static readonly Uri endpointUri = new Uri("https://api.bitflyer.jp");

    public static async Task GetBoard()
    {
        var method = "GET";
        var path = "/v1/getboard";
        var query = "";

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
        {
            client.BaseAddress = endpointUri;
            var message = await client.SendAsync(request);
            var response = await message.Content.ReadAsStringAsync();

            Board board = JsonConvert.DeserializeObject<Board>(response);

            Console.WriteLine("mid_price: {0}", board.MidPrice);
            Console.WriteLine("asks");
            for(int i=0; i < board.Asks.Length; ++i)
            {
                Board.Quote quote = board.Asks[i];
                Console.WriteLine("    price: {0}, size: {1}", quote.Price, quote.Size);
                if (5 == i) break;
            }
            Console.WriteLine("bids");
            for(int i=0; i < board.Asks.Length; ++i)
            {
                Board.Quote quote = board.Bids[i];
                Console.WriteLine("    price: {0}, size: {1}", quote.Price, quote.Size);
                if (5 == i) break;
            }
        }
    }

    static void Main(string[] args)
    {
        GetBoard().Wait();
    }
}


コンパイル
リソースにNewtonsoft.Json.dllを追加指定します。

$ mcs getboard_json.cs -r:/usr/lib/mono/4.6.2-api/System.Net.Http.dll,/usr/lib/mono/4.6.2-api/Facades/System.Threading.Tasks.dll,./Newtonsoft.Json.dll


実行

$ ./getboard_json.exe
mid_price: 443180.0
asks
    price: 443299.0, size: 0.14522859
    price: 443399.0, size: 0.41834898
    price: 443400.0, size: 0.5607
    price: 443445.0, size: 0.00319999
    price: 443460.0, size: 0.083
    price: 443505.0, size: 0.8059
bids
    price: 443061.0, size: 0.1562
    price: 443002.0, size: 12.0
    price: 443001.0, size: 0.33477141
    price: 443000.0, size: 0.50839729
    price: 442603.0, size: 1.96
    price: 442510.0, size: 27.4
$

よさそうですね。