公式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");
先ずはcrypto
とsoket.io-client
をインポートして使用可能な状態にしてある。
実際に稼働する場合はsocket.io-client
だけnpm install
が必要。
2020/03/13 訂正:crypto
はNode.js
標準で使用できますのでインストール不要でした。
npm install socket.io-client
crypto
データを暗号化するライブラリ。仮想通貨をクリプトと呼ぶ人もいるが直接は関係ない。別の回で説明する。
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"];
key
とsecret
は各自ログインして取得する。これは別サイトを調べれば分かるだろう。個人それぞれの注文などのデータを扱うため(プライベートチャンネル)に必要だ。
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
等
つまり通貨ペアそれぞれの「約定履歴」が流れてくると思われる。他にも
以上を指定できるようだ。(product_codeに通貨ペアを記述する。各ページに詳細あり)
加えて配列になっている点も気にしておく。複数のデータを同時に受信できそうだ。今は種類がこれだけあることだけ覚えておけば良い。
privateChannels
の宣言には2つの文字列が渡されている。
child_order_events
: 注文イベント
LIMIT,MARKETの注文をchild order(子注文)と呼ぶようだ。
parent_order_events
: 親注文(特殊注文)イベント
それ以外の特殊注文は「親注文」と呼ばれる。少し複雑なので公式を参照していただきたい。
どちらにせよRealtime APIは受信専用なので注文は出せない。今はこの2種類あるという事だけ覚えておけば良い。
残りのコードは通信するためだけのコードなので基本的に以上までを理解していれば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
と明示してやることで、無駄な通信を省いている。
コードの冒頭部分だけとなったがこれだけでも結構勉強になる。名前空間とかそういう話は別のサイトで調べていただきたい(私もあんまり詳しく説明できない)
やはり無駄に長い説明になっただけで需要が無い気がする。