Vue.js と vue-chart.js によってWEBアプリとしてbitFlyerから流れてくる「板データ」を可視化する実験。
板情報可視化に関する実験の詳細を知りたい場合は私の過去の記事(難易度:ちょっとむずかしい/非常にめんどい)
かなりマニアック。
Vue.jsはともかくvue-chart.jsを使っていくので学習コストが必要。
難易度的には板情報の可視化より、Tickerの可視化のほうが先にやるべきだった。
では、早速本題にはいっていく。
私のYoutubeチャンネルをサブスクしなさいと言っているわけではない。socket.ioで情報(channel)を受信することを「subscribe」と公式に呼ぶ。
Tickerのチャンネルは lightning_ticker_プロダクトコード
なので、FXのTickerを見たい場合は次のコードのようにする。
socket.on("connect", () => {
const publicChannels = [
"lightning_ticker_FX_BTC_JPY" //これがTicker
];
for (const ch of publicChannels) {
socket.emit("subscribe", ch, err => {
if (err) {
console.error(ch, "Subscribe Error:", err);
return;
}
console.log(ch, "Subscribed.");
});
}
//まだ続く
今回は「TickerLine.js」とした。
やたら易しいvue-chart.js解説で紹介しているように、vue-chart.jsは新しいグラフを作成する時は毎回別ファイルで用意するという決まりである。
ただ、これ自体は簡単で記事内で紹介しているプログラムをまずはコピーして、必要な箇所を修正すればよい。
今回は棒グラフではなく線グラフ(Line)である箇所だけ変更する(2箇所で指定)
TickerLine.js
import { Line, mixins } from 'vue-chartjs' // ここにLine
const { reactiveProp } = mixins
export default {
mixins: [Line,reactiveProp], // ここにもLine
props: ['options'],
mounted() {
this.renderChart(this.data, this.options)
}
}
今回は上と同じjsに入ってきたTickerの生データを処理してchart.js描画用のオブジェクトに整形しreturn
する関数を実装した。
export const renewTicker = (message, datacollection, maxCnt) => {
//ラベルは「時:分:秒」で表示
const date = new Date(message.timestamp)
const time = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds()
//Tickerの生データ(message)をグラフ用にpush
datacollection.labels.push(time)
datacollection.datasets[0].data.push(message.best_bid)
datacollection.datasets[1].data.push(message.best_ask)
datacollection.datasets[2].data.push(message.ltp)
//画面に表示する件数を超えたらshiftで削る
if (datacollection.labels.length > maxCnt) {
datacollection.labels.shift()
datacollection.datasets.forEach((array) =>{
array.data.shift()
})
}
//ラベルの通り表示する線は3本
//上からbid,ask,ltp
const return_datacollection = {
labels: datacollection.labels,
datasets: [
{
label: "bid",
data: datacollection.datasets[0].data,
fill: false,
borderColor: "green"
},
{
label: "ask",
data: datacollection.datasets[1].data,
fill: false,
borderColor: "red"
},
{
label: "Last Trade Price",
data: datacollection.datasets[2].data,
fill: false,
borderColor: "gray"
},
]
}
return return_datacollection
}
必ず読み込む側のvueファイルでインポートしておく。
import TickerLine, { renewTicker } from "./TickerLine.js";
export default {
components: {
TickerLine
},
テンプレート部
<TickerLine :chart-data="datacollection_ticker" :options="options_ticker" />
data部にdatacollection_tickerの初期化を忘れないように。
datacollection_ticker: {
labels: [],
datasets: [
{
label: [],
data: []
},
{
label: [],
data: []
},
{
label: [],
data: []
}
]
}
vue-chart.jsの決まりごと!必ずmounted
でオプションを設定すること。
mounted() {
this.options_ticker = {
responsive: true, //レスポンシブにサイズが変わる
maintainAspectRatio: false, //縦サイズを固定する
scales: {
yAxes: [
{
position: "right" //Y軸のラベルを右にしている
}
]
}
}
socket.ioもmounted
で登録しておく。
const socket = io("https://io.lightstream.bitflyer.com", {
transports: ["websocket"] // specify explicitly
});
socket.on("connect", () => {
const publicChannels = [
"lightning_ticker_FX_BTC_JPY"
];
for (const ch of publicChannels) {
socket.emit("subscribe", ch, err => {
if (err) {
console.error(ch, "Subscribe Error:", err);
return;
}
console.log(ch, "Subscribed.");
});
}
//ticker
socket.on("lightning_ticker_FX_BTC_JPY", message => {
this.datacollection_ticker = renewTicker(
message, //第一引数にTicker
this.datacollection_ticker, //データを追記して返す為渡す
30 //表示する最大数 これはユーザーが入力出来るように後に変更
)
}
});
完成品 - 謎のチャートはこちら
これまた探せば何処かにありそうだが無骨に現在価格を表示するよりかはより詳細が目視できるようになった。
あいかわらずこれだけの可視化で勝てるほど甘くない。ただ、とりあえず出来ることを淡々とこなすことも重要な一歩だ。
あとは約定あたりでなにかアイデアがあれば可視化してみたい。