はじめに
株価の時系列データが入ったcsvファイルがあればmplfinanceを使用すれば、pythonが動作する環境で簡単に株価チャートを表示させることができます。この株価チャートをwebブラウザでいつでも見れるようにするのが本稿の趣旨です。
使用するのは、python, mplfinance, flaskでこれらをまとめてdocker-composeでサクッと動かします。
実行環境
ディレクトリ構成
working_dir/
Dockerfile
docker-compose.yml
opt/
flask_chart.py
share/
data/
1000/
1001.csv
1002.csv
...
2000/
...
9000/
9001.csv
...
data/ ディレクトリの中に、1000/ ~ 9000/ のサブディレクトリを切ってその中に、「証券コード.csv」という名前の株価日足時系列データが置かれているものとします。
株価日足時系列データのcsvファイルの例は以下。
2015/01/05,275,277,274,275,239000000
2015/01/06,274,275,270,272,480000000
2015/01/07,270,273,270,271,217000000
...
2020/11/25,2839,2846,2795,2831,27800000
2020/11/26,2820,2826,2801,2809,8700000
2020/11/27,2807,2825,2803,2819,22000000
Flaskによる株価チャートサーバ
Flaskはpythonでwebサーバの振る舞いを記述できるんでとても便利。matplotlibで作ったグラフをFlaskで配信する例がネットに多くありますが、matplotlibだけでなく、mplfinanceのplotも同じ方法で出来ちゃうんです。
import os
import numpy as np
import io
from flask import Flask, send_file, request
from flask_cors import CORS
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pandas as pd
import mplfinance as mpf
app = Flask(__name__)
CORS(app)
# http://サーバ名:5000/
@app.route('/')
def root():
return "Chart Server"
# http://サーバ名:5000/candle?code=1001&term=200&volume=True
@app.route("/candle")
def candle():
code = request.args.get('code', default=None, type=int)
term = request.args.get('term', default=200, type=int)
volume = request.args.get('volume', default="True", type=str)
code_dir = int(code/1000)*1000
input_path = "/root/opt/share/data/" + str(code_dir) + "/" + str(code) + ".csv"
df = load_stock_price_csv(input_path, term=term)
image = io.BytesIO()
if len(df)>1:
mpf.plot(df, title=str(code), type='candle',
mav=[5, 25, 75], volume=str2bool(volume))
plt.savefig(image, format='png')
image.seek(0)
return send_file(image, attachment_filename="image.png")
def str2bool(s):
return s.lower() in ["True", "true", "TRUE", "1"]
def load_stock_price_csv(path, term=0):
if os.path.exists(path):
df = pd.read_csv(path, header=None, names=['Date','Open','High','Low','Close','Volume'], encoding='UTF-8')
else:
df = pd.DataFrame([[0, 0, 0, 0, 0, 0]])
df.columns = ['Date','Open','High','Low','Close','Volume']
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index("Date")
if term>0:
df = df.tail(term)
return df
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
http://サーバ名:5000/
によりroot()が走ります。ここでは、クライアントに"Chart Server"という文字列を表示させるだけです。
http://サーバ名:5000/candle?code=6897&term=200&volume=True
によりcandle()が走ります。
candle()では、urlパラメータを抽出し、それに従いmpl.plot()でチャートを表示し、それを(メモリ上の)imageにpngでセーブし、クライアントに返します。
docker-composeによる実装
pythonの実行イメージを作って、そこでflaskサーバを稼働させています。
FROM python:3
USER root
RUN apt-get update
RUN apt-get -y install locales && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm
RUN apt-get install -y vim
RUN pip install --upgrade pip && \
pip install --upgrade setuptools && \
pip install --upgrade Flask flask_cors mplfinance
CMD ["python", "/root/opt/flask_chart.py"]
株価データが置かれている場所を、opt/shareにマウントしています。
version: '3'
services:
chart:
restart: always
build: .
container_name: 'chart'
working_dir: '/root/opt'
tty: true
ports:
- 5000:5000
volumes:
- ./opt:/root/opt
- /home/samba/share/muzinzo:/root/opt/share
株価サーバの起動
$ docker-compose up -d --build
必要に応じてサーバの5000番ポートを開けて、webブラウザで、
を叩けば株価チャートが見れます。
とてもお手軽に、株価チャート配信サーバを構築できました。サーバでスクリーニングした結果を表示させたり、ページをデコったりと、夢は広がります。
参考までに、株価データを用意したり、チャートを描画したりは、拙文
がお役に立てるかもしれません。
2020/02/11追記
その後、少しWebアプリっぽくしてみました。とは言っても、単なる実装なんで、あえて追記するほどのものではありません。ソースはGutHubに置いています。
2021/2/16追記
作成したサイトをFrozen-Flaskで静的htmlサイトに変換し、GitHubに置いてデモサイトを作ってみました。レスポンシブデザインではないので、PC専用ですが。。
以上