先週に引き続きBitcoin関連で週末コーディング。
取引アルゴリズムを考える前に、とりあえずは可視化(と仮説の検証)が必要だろうということで。
ポート管理やら各種パスやら環境変数やらに煩わされたくない怠惰系のアプリケーションエンジニアとしては、 この手のツールがDockerで用意されてると簡単に試せて本当に助かる。
以下Docker Compose導入後という前提で。
簡単なグラフ化ならGrowthForecast
表題どおり、何かしらの時間で変化する数値をサクッとグラフ化するだけの要件なら、GrowthForecastを立ち上げてスクリプトなり何なりから値を投げ込むのが楽だろう。
GrowthForecast - Lightning fast Graphing / Visualization
導入
適当にディレクトリを用意し(僕は~/Docker/[サービス名]みたいな感じでまとめてる)、下記のdocker-compose.ymlを作成して$ docker-compose up -d
で起動するだけ。
growthforecast: image: kazeburo/growthforecast ports: - 5125:5125 #ホストの5125番ポートにGrowthForecastで使用するコンテナの5125ポートを割り当てる volumes: - $PWD/data:/var/lib/growthforecast #ホストの./dataディレクトリにファイルを吐くようにする - /etc/localtime:/etc/localtime:ro #ホストとコンテナのタイムゾーンを合わせる
上手くいってればhttp://[サーバのIP]:5125/
にアクセスすると一覧ページが表示される。
データ投入
ドキュメント通り$ curl -XPOST http://localhost:5125/api/test1/test2/test3 -d number=12345
とか投げた後に再度ページにアクセスすれば、グラフ化されていることが確認できる。
実際的にはbtcboxのAPIから取り出した値をグラフ化したいので下記のようなrubyスクリプトを組んだ。
require 'btcbox' require 'net/http' require 'uri' btc = Btcbox::Client.new(PUBLIC_KEY, SECRET_KEY) balance = btc.balance res = Net::HTTP.post_form(URI.parse("http://localhost:5125/api/btcbox/jpy/lock"), {number: balance["jpy_lock"].to_i, type: "gauge"}) res = Net::HTTP.post_form(URI.parse("http://localhost:5125/api/btcbox/jpy/balance"), {number: balance["jpy_balance"].to_i, type: "gauge"})
(ていうか、今ドキュメント読みなおしてみたらそれ用のgemもあったのね。GitHub - tagomoris/rb-growthforecast )
そんなわけで「小難しいことはいいからとりあえず時系列グラフを!」という場合にGrowthForecastは非常に便利なのだが、一点注意しなければいけないことが。
投げ込めるnumberは整数のみ対応なので、小数を含む値を投げ込むとエラーとなってしまう。
$ curl -XPOST http://localhost:5125/api/test1/test2/test3 -d number=12345.5 {"messages":["a INT number is required for \"number\""],"error":1}
なので必要におうじて桁を繰り上げるなり四捨五入なりをする必要がある。
Bitcoin関連だと小数を扱う機会も少なくなく、変に繰り上げばかりしていると混乱してしまいそうなので、次のElasticsearch&Kibanaにも手を出してみた。
様々な要求に対応するならElasticsearch&Kibana
昨今なにかと名前を見かけるElasticsearch。
良い機会だったのでちょっとだけかじってみた。(その程度なんで僕自身まだ理解度は浅め)
全文検索エンジンであるElasticsearchと、フロントエンドであるKibanaを連結して使う。
導入
docker-compose.ymlは下記を使用。
elasticsearch: image: elasticsearch volumes: - $PWD/esdata:/usr/share/elasticsearch/data - /etc/localtime:/etc/localtime:ro #ホストとコンテナのタイムゾーンを合わせる ports: - 9200:9200 # データ投入用のポート kibana: image: kibana volumes: - /etc/localtime:/etc/localtime:ro #ホストとコンテナのタイムゾーンを合わせる links: - elasticsearch:elasticsearch ports: - 5601:5601 # フロントエンド用のポート
これでhttp://[サーバのIP]:5601
でKibanaのページが表示される。
データ投入
一応こちらもcurlからデータ投入できなくはないが、ちょっと面倒なJSONの形なので大人しく各言語のライブラリを使った方が良い。
以下rubyスクリプトで
require 'elasticsearch' require 'btcbox' btc = Btcbox::Client.new(PUBLIC_KEY, SECRET_KEY) orders = btc.orders es = Elasticsearch::Client.new log: false for order in orders id = order["tid"].to_i data = {price: order["price"], amount: order["amount"], type: order["type"]} data['@timestamp'] = Time.at(order["date"].to_i).utc.iso8601 es.index index: 'btcbox', type: 'order', id: id, body: data end es.indices.refresh index: 'btcbox'
btcbox
というインデックスにorder
のデータを突っ込んでいく。
時系列のイベントとして判定されるように@timestamp
というキーを用意していることに注意。
設定
さっき突っ込んだデータを表示するためにKibana上で設定を行う。
Index name or pattern
に先ほど指定していたbtcbox
、時間を示すTime-field name
に@timestamp
を指定してCreate。
これでスクリプトから突っ込んだデータを扱えるようになる。
グラフ描画
Visualize
メニューよりLine Chart
・From a new search
を選択する。
縦軸Y-Axis
としてAggregation
をAverage
、Field
をprice
として指定。
横軸としてX-Axis
にAggregation
をDate Histgram
、Field
を@timestamp
指定。
上の|>ボタンを押してグラフを描画できる。
時間の都合上あまりいじれなかったが、売り買いを別の線にするとか取引量をプロットの太さにするとか、もっと複雑なことだってできる。
サーバ/インフラエンジニア養成読本 ログ収集~可視化編 [現場主導のデータ分析環境を構築!] (Software Design plus)
- 作者: 鈴木健太,吉田健太郎,大谷純,道井俊介
- 出版社/メーカー: 技術評論社
- 発売日: 2014/08/08
- メディア: 大型本
- この商品を含むブログ (1件) を見る
怠惰なアプリケーションエンジニアへのDockerのススメ
今回いれてみたツールはいずれも導入が簡単だということが売りの一つだったりするので、 実のところ個々に入れたってそんなに苦になるものではない。
だた、そうはいっても僕のような怠惰なアプリケーションエンジニアにとっては、サーバに何か導入して管理するという事自体が面倒だったりする。
個々のツールの設定ファイルの場所は忘れるしポートはごっちゃごちゃになるし、挙句どこで起動したんだか、どう落とすのが安全なんだか分からなくなる。
そのあたりの面倒を最小化してくれるので、Docker(というかDocker Compose)はすごくありがたい。
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化
- 作者: 阿佐志保,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2015/11/20
- メディア: 大型本
- この商品を含むブログ (3件) を見る