2020-03-12

Node.jsで仮想通貨の自動取引(bitFlyer編 #3) Realtime API公式コードを詠む

bitFlyer Realtime API(Socket.io)公式のコードを読み解く。

Article Image

公式が用意しているサンプルを読み解く

公式URL:https://bf-lightning-api.readme.io/docs/endpoint-socket-io より「利用例」のコードを見ていく。

このコードはパブリックチャンネルとプライベートチャンネルの2種から送られてくるデータを画面にひたすら表示するだけのプログラムである。

なお、前回の記事で比較した結果を受けてSocket.ioを利用して接続することとした。

インポート

// Node.js (JavaScript)
const crypto = require("crypto");
const io = require("socket.io-client");

先ずはcryptosoket.io-clientをインポートして使用可能な状態にしてある。

実際に稼働する場合はsocket.io-clientだけnpm installが必要。

2020/03/13 訂正:cryptoNode.js標準で使用できますのでインストール不要でした。

npm install socket.io-client
  1. crypto

    データを暗号化するライブラリ。仮想通貨をクリプトと呼ぶ人もいるが直接は関係ない。別の回で説明する。

  2. socket.io-client

    解説は必要ないだろう。これがリアルタイムで通信をするクライアント側のライブラリだ。サーバー側を作る場合は別のライブラリを使う。

定数宣言

const key = "{{ YOUR API KEY }}";
const secret = "{{ YOUR API SECRET }}";

const publicChannels = ["lightning_executions_BTC_JPY"];
const privateChannels = ["child_order_events", "parent_order_events"];

keysecretは各自ログインして取得する。これは別サイトを調べれば分かるだろう。個人それぞれの注文などのデータを扱うため(プライベートチャンネル)に必要だ。

publicChannelsには配列が宣言されておりlightning_executions_BTC_JPYとある。これはなんだろうか。

公式の「約定」ページに詳細がある。

  • BTC/JPY (現物):lightning_executions_BTC_JPY
  • BTC/JPY FX:lightning_executions_FX_BTC_JPY
  • ETH/BTC:lightning_executions_ETH_BTC
  • Lightning Futures:lightning_executions_BTCJPY28JUN2019

つまり通貨ペアそれぞれの「約定履歴」が流れてくると思われる。他にも

  1. 板情報のスナップショット : lightning_board_snapshot_{product_code}
  2. 板情報の差分 : lightning_board_{product_code}
  3. Ticker : lightning_ticker_{product_code}

以上を指定できるようだ。(product_codeに通貨ペアを記述する。各ページに詳細あり)

加えて配列になっている点も気にしておく。複数のデータを同時に受信できそうだ。今は種類がこれだけあることだけ覚えておけば良い。

privateChannelsの宣言には2つの文字列が渡されている。

  1. child_order_events注文イベント

    LIMIT,MARKETの注文をchild order(子注文)と呼ぶようだ。

  2. parent_order_events親注文(特殊注文)イベント

    それ以外の特殊注文は「親注文」と呼ばれる。少し複雑なので公式を参照していただきたい。

どちらにせよRealtime APIは受信専用なので注文は出せない。今はこの2種類あるという事だけ覚えておけば良い。

実はこれだけ覚えておけばほぼAPIに関しての知識は集まった

残りのコードは通信するためだけのコードなので基本的に以上までを理解していればAPIに関しては覚えることはないといって良い。詳細はその都度公式のリファレンスを見れば十分だろう。

とはいえここで終わってしまうのは流石に早すぎるので残りのコードも順を追って読んでいく。

定数宣言 Socket.io の箇所

const socket = io("https://io.lightstream.bitflyer.com", {
    transports: ["websocket"] // specify explicitly
});

ここからはSocket.io用のプログラムコードになる。APIはあまり関係なく汎用的なコードである。

最初にioとしてインポートしてきたモジュールに通信先に関する値を渡してsocketという名前空間に閉じ込めて簡単に使える状態にする。

もはや名前空間という概念が若干厄介しれないが(私の使い方が間違っていたら申し訳ないが)表現がこれしかできない。

たとえばsocket1 = io(接続先1) と socket2 = io(接続先2)のように同じioでも複数に分けて動作させることができるプログラムの一般的な概念だ。

また、この名前空間を使わない場合は次からのコードがこんなふうに冗長になるので、これを短くするメリットもある。

//本来コレが
io("https://io.lightstream.bitflyer.com", {     transports: \["websocket"] // specify explicitly }).on("connect", () => { なんやかんや~~
   
//こう短くできるメリットもある
socket.on("connect", () => { なんやかんや~~

さて、名前空間が一段落したところでioに渡している最初のパラメタは接続先のURLなのは分かるが次のtransports: ["websocket"]とはなんなのだろうか。

これはsocket.ioはlong-polling方式の接続を試して、だめなら他の接続方式に移る(これをアップグレードと呼ぶ)そうでこのコードでwebsocketと明示してやることで、無駄な通信を省いている。

今回はここまで

コードの冒頭部分だけとなったがこれだけでも結構勉強になる。名前空間とかそういう話は別のサイトで調べていただきたい(私もあんまり詳しく説明できない)

やはり無駄に長い説明になっただけで需要が無い気がする。



この記事をシェア


謎の技術研究部 (謎技研)