docker-composeで株価データの自動取得

# はじめに

銘柄選びをする際、証券会社のサイトで用意されたツールを使う訳ですが、チャート表示ぐらいはそれで十分なんですが、少し変わったスクリーニングをしたいような場合やシステムトレードのバックテストをするときなどは、自分で株価データを持ちたいですよね。

毎日の日本株の株価データを公開している<a href="https://mujinzou.com/">無尽蔵</a>というサイトがあります。
自分で株価データを持つために、ここから、毎日定時に、その日の株価一覧の取得を試みます。

# 無尽蔵サイトから株価データを取得するpythonスクリプト

無尽蔵サイトのデータ取得のurlは、例えば2020/11/04の株価データなら、

http://mujinzou.com/k_data/2020/20_11/T201104.zip

当日の株価データを取得し、zipを展開するスクリプトの例：


~~~python:get_todays_csv_zip_from_muzinzo.py
# -*- coding: utf-8 -*-
import urllib.request
import zipfile
import datetime
import os
import logging
import sys

def download_csv_zip(output_dir, year, month, day):
    base_url = 'http://mujinzou.com/k_data/'+str(year)+'/'
    subdir = '{0:02d}_{1:02d}/'.format(year-2000, month)
    filename = 'T20{0:02d}{1:02d}.zip'.format(month, day)
    url = base_url + subdir + filename
    now = datetime.datetime.now()
    try:
        urllib.request.urlretrieve(url, filename)
        with zipfile.ZipFile(filename, 'r')as zf:
            zf.extractall(output_dir)
        os.remove(filename)
        logging.info(str(now)+' success to get file: '+filename)
    except urllib.error.HTTPError:
        logging.error(str(now)+' error')
                

def main():
    args = sys.argv
    if len(args)==2:
        output_dir = args[1]
        if output_dir[-1]!='/':
            output_dir = output_dir + '/'
    else:
        output_dir = './'
    logging.basicConfig(level=logging.INFO)
    today = datetime.date.today()
    download_csv_zip(output_dir, today.year, today.month, today.day)

if __name__ == '__main__':
    main()
~~~

使い方の例：

~~~bash
$ python get_todays_csv_zip_from_muzinzo.py ~/tmp
~~~

引数としてダウンロード先のディレクトリを指定できます。指定しなければ、ダウンロード先はカレントディレクトリになります。

サイトに当日の株価データが置かれるには概ね夕方以降なので留意。つまり、このスクリプトで当日の株価データが取得できるのは、当日の夕方から深夜0時まで。

# docker-composeでpythonスクリプトを動かす

pythonスクリプトの定時実行の布石として、docker-composeでpythonスクリプトを動かします。

docker-compose.ymlとDockerfileは、以下から借用。

https://qiita.com/reflet/items/4b3f91661a54ec70a7dc
dockerで簡易にpython3の環境を作ってみる

ディレクトリ構成

~~~
python3\
    Dockerfile
    docker-compose.yml
    opt\
        get_todays_csv_zip_from_muzinzo.py
        exec_cmd.sh
~~~

~~~Dockerfile:Dockerfile
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 less cron
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
#RUN echo '0 20 * * 1-5 root /root/opt/exec_cmd.sh' >> /etc/crontab
#CMD ["cron", "-f"]
~~~

~~~yml:docker-compose.yml
version: '3'
services:
  python3:
    restart: always
    build: .
    container_name: 'python3'
    working_dir: '/root/opt'
    tty: true
    volumes:
      - ./opt:/root/opt
~~~

起動

~~~bash
$ docker-compose up -d --build
~~~

pythonスクリプトの実行

~~~bash
$ docker-compose exec python3 python /root/opt/get_todays_csv_zip_from_muzinzo.py
~~~

これでoptディレクトリ内に、当日の株価データ「Tyymmdd.csv」が生成されます。


# pythonスクリプトを毎日定時実行する

先のDockerfileの末尾2行をコメントアウトします。
これは、cronにより、月曜日～金曜日の20時に、スクリプトexec_cmd.shを実行するための設定です。

~~~Dockerfile:Dockerfile
  ...
RUN echo '0 20 * * 1-5 root /root/opt/exec_cmd.sh' >> /etc/crontab
CMD ["cron", "-f"]
~~~


~~~bash:opt/exec_cmd.sh
#!/bin/bash
/usr/local/bin/python /root/opt/get_todays_csv_zip_from_muzinzo.py /root/opt >> /root/opt/exec_cmd.log 2>&1
~~~

これを忘れずに

~~~bash
$ chmod a+x exec_cmd.sh
~~~


ここまで用意したら、常時稼働サーバで起動しておく。

~~~bash
$ docker-compose up -d --build
~~~

株価データの取得だけでなく、いっしょにデータベースへの格納もやっておけば、いつでも最新株価データが使えて、とても便利。

pythonの実行環境とcronによる定時実行をコンテナにまとめてすっきり仕上がった。