Kibana+elasticsearchによる株価データベース
January 29, 2021
株価サーバー python目次
はじめに
筆者は、無尽蔵サイトから株価データを入手し、株価データベースを構築しています。株価データベースといっても、単にLinuxファイルシステム上に銘柄毎の株価時系列データが入ったcsvファイルを生成しているだけで、これだけでは、何も気の利いたことはできません。
サーバ上に構築された株価データベースをWebブラウザから株価チャートとして可視化できたらいいなぁ~、と思いつつ、お手軽な実現方法を検討してみました。その結果、候補に上がったのがKibanaとelasticsearchによるソリューションです。
- elasticsearch:時系列データを扱うに適したデータベース
- Kibana:elasticsearchのデータを可視化するためのWebアプリ
という筆者の認識です。
elasticsearchは、全文検索エンジンfessのデータベースにも採用されており、テキストの扱いに強いと言われており、株価のような数値を扱うにはどうかなという不安はありますが、将来的に株価だけでなく、決算データや企業ニュースなんかもデータベースにぶち込んで、何か分析出来たらという思惑もあります。
早速、Kibanaとelasticsearchのインストールからはじめてみます。
Kibanaとelasticsearchのインストール
ディレクトリ構成
kibana/
docker-compose.yml
kibana/
kibana.yml
es-data/
【注意】es-dataのパーミッションを777にしておく必要がある。
Kibanaとelasticsearchをdocker-composeでインストールします。docker-compose.ymlファイルは、基本的には、fessの公式docker-composeファイルを取得し、そこからfessの部分を取り除いたものです。
version: "3"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
environment:
- discovery.type=single-node
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 9200:9200
volumes:
- ./es-data:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:7.6.2
ports:
- 5601:5601
volumes:
- ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
environment:
- "I18N_LOCALE=ja-JP"
kibanaをサブディレクトリにインストール
kibanaをデフォルトでインストールした場合、
http://サーバ名:5601/
でkibanaにアクセスすることになるが、次のようにサブディレクトリ/kibanaでアクセスするように変更する。
http://サーバ名:5601/kibana
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
server.basePath: "/kibana"
#server.rewriteBasePath: true
Kibanaの日本語化
docker-compose.ymlのenvironmentで指定
kibana:
environment:
- "I18N_LOCALE=ja-JP"
リバースプロキシの設定
server {
location /kibana/ {
proxy_pass http://localhost:5601;
rewrite /kibana/(.*)$ /$1 break;
access_log off;
}
この設定により、
http://サーバ名:5601/kibana
ではなく、
http://サーバ名/kibana
でアクセスできるようになる。
firewallの設定
本サイトに公開した手順でファイアーウォール(awall)を設定している場合は、ポート9200, 9201, 9300番を開ける必要があります。
{
"//": "elasticsearch",
"in": "LAN",
"out": "_fw",
"service":[ {"proto": "tcp", "port": "9200"},
{"proto": "tcp", "port": "9201"},
{"proto": "tcp", "port": "9300"}
],
"action": "accept"
},
elasticsearch+Kibana起動
起動
$ docker-compose up -d
elasticsearchの動作確認
$ curl -X GET http://192.168.1.13:9200/
{
"name" : "6223a3fcfd3f",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "GjRZPKXERGm47w-t5PSRQw",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
elasticsearchにデータ投入
日経平均株価の4本値時系列データを投入
データ形式
2021/01/21,28710,28846,28677,28757,1144470000000
2021/01/22,28580,28698,28527,28631,1217520000000
2021/01/25,28698,28822,28566,28822,1016450000000
2021/01/26,28696,28740,28527,28546,1070610000000
以下のpythonスクリプトでelasticsearchにデータ投入します。
その前に、elasticsearchパッケージを入れておく。
$ pip install elasticsearch
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from datetime import datetime as dt
import pandas as pd
from elasticsearch import Elasticsearch
def generate_doc(row):
doc = {
'start_value': row[1],
'end_value': row[4],
'low_value': row[3],
'high_value': row[2],
'timestamp': dt.strptime(row[0], '%Y/%m/%d')
}
return doc
def uploader():
df = pd.read_csv('1001.csv', header=None, encoding='UTF-8')
es = Elasticsearch('http://elastic:changeme@192.168.1.13:9200')
for row in df.iterrows():
doc = generate_doc(row[1])
type = '1001'
res = es.index(index="stock", doc_type=type, id=str(row[0]), body=doc)
return
def main():
uploader()
return
if __name__ == '__main__':
main()
データが投入されたことを確認
$ curl -XGET 'http://localhost:9200/stock/1001/0?pretty=true'
{
"_index" : "stock",
"_type" : "1001",
"_id" : "0",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"start_value" : 17325,
"end_value" : 17409,
"low_value" : 17219,
"high_value" : 17540,
"timestamp" : "2015-01-05T00:00:00"
}
}
Kibanaで可視化
Kibanaにアクセス
http://サーバ名/kibana
「独りで閲覧」をクリック
「Discover」をクリック
インデックスパターン の作成
「新規データを確認」をクリック
インデックスパターン の作成
インデックスパターン:stock
を指定し、「次のステップ」をクリック
時間フィルターのフィールド名:時間フィルターを使用しない
を指定し、「インデックスパターンを作成」をクリック
インデックスパターン:stockが作成された。
「Visualize」をクリック
「新規ビジュアライゼーションを追加」をクリック
「折れ線」をクリック
インデックスパターン「stock」をクリック
メトリック、バケットを以下のように指定し、「▶」アイコンをクリック。
メトリック
Y軸
集約:平均
フィールド:end_value
バケット
X軸
集約:日付ヒストグラム
フィールド:timestamp
最低間隔:日ごと
日経平均株価終値のグラフが完成。
おわりに
株価データをelasticsearchに投入し、Kibanaで可視化する流れの動作確認はとれたのだが、Kibanaの癖が筆者にはしっくりこず、ここから筆者が思い描く株価分析結果の可視化ツールに発展させていく道のりはかなり遠いように思える。
Kibanaにプラグインを入れてローソク足チャートを表示させた事例もあるようだが、筆者の技術力不足もあり、ちょっと敷居が高い。Kibanaは諦めてもう少しお手軽な方法を探そうと思う。