株のシステムトレードをしよう - 1から始める株自動取引システムの作り方

株式をコンピュータに売買させる仕組みを少しずつ作っていきます。できあがってから公開ではなく、書いたら途中でも記事として即掲載して、後から固定ページにして体裁を整える方式で進めていきます。

backtrader クイックスタートその2

Trading
Photo by Adam Nowakowski on Unsplash

前回の振り返り

前回の記事では、初歩の初歩からはじめた。今回はもう少し発展的なサンプルに挑戦する。

how-to-make-stock-trading-system.dogwood008.com

なお、別の記事で docker-compose を導入したので、その前提で進めていく。

how-to-make-stock-trading-system.dogwood008.com

今回の変更差分

いつものように、 GitHub の Pull requests として用意してある。

github.com

サンプルの取得とビルド

まずは、backtrader の Docs から、下記の部分をコピーしてくる。

# 以下引用: mementum, "Quickstart Guide - Backtrader", 
# "https://www.backtrader.com/docu/quickstart/quickstart/#adding-a-data-feed", 
# アクセス日:2020年10月26日, 日本語のコメント部は著者による

# from __future__ import (absolute_import, division, print_function,
#                        unicode_literals)

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])

# Import the backtrader platform
import backtrader as bt

if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Datas are in a subfolder of the samples. Need to find where the script is
    # because it could have been called from anywhere
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt')

    # Create a Data Feed
    data = bt.feeds.YahooFinanceCSVData(
        dataname=datapath,
        # Do not pass values before this date
        fromdate=datetime.datetime(2000, 1, 1),
        # Do not pass values after this date
        todate=datetime.datetime(2000, 12, 31),
        reverse=False)

    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(100000.0)

    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

    # Run over everything
    cerebro.run()

    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

これを実行すると、次のようになる。

$ docker-compose build
(出力省略)
$ docker-compose up
Starting stock-trading-system_app_1 ... done
Attaching to stock-trading-system_app_1
app_1  | Starting Portfolio Value: 100000.00
app_1  | Traceback (most recent call last):
app_1  |   File "main.py", line 39, in <module>
app_1  |     cerebro.run()
app_1  |   File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.8/site-packages/backtrader/cerebro.py", line 1127, in run
app_1  |     runstrat = self.runstrategies(iterstrat)
app_1  |   File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.8/site-packages/backtrader/cerebro.py", line 1210, in runstrategies
app_1  |     data._start()
app_1  |   File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.8/site-packages/backtrader/feed.py", line 203, in _start
app_1  |     self.start()
app_1  |   File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.8/site-packages/backtrader/feeds/yahoo.py", line 94, in start
app_1  |     super(YahooFinanceCSVData, self).start()
app_1  |   File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.8/site-packages/backtrader/feed.py", line 674, in start
app_1  |     self.f = io.open(self.p.dataname, 'r')
app_1  | FileNotFoundError: [Errno 2] No such file or directory: '/app/../../datas/orcl-1995-2014.txt'
stock-trading-system_app_1 exited with code 1

これは /app/../../datas/orcl-1995-2014.txt に読み込むべきファイルが見つからない ( FileNotFoundError )を示している。

エラーの修正と再実行

サンプルのままでは動かないことがわかったので、コードを修正する。まずは、 Dockerfile から。 backtrader のリポジトリからファイル一式をクローンしてくる行を追加した。

# Dockerfile
FROM python:3.8.6
LABEL maintainer="dogwood008"
ARG workdir=/app

RUN mkdir $workdir
WORKDIR $workdir
COPY Pipfile $workdir
COPY Pipfile.lock $workdir

RUN pip install --upgrade pip && \
    pip install pipenv && \
    pipenv sync && \   # ←最後に "&&\" を追加
    git clone https://github.com/mementum/backtrader.git /opt/backtrader  # ←追加

CMD ["pipenv", "run", "python", "main.py"]

Dockerfile を修正後、 docker-compose build を実行して、エラー表示がなければOK。秘密鍵と公開鍵の作成を省くため、 Git でのクローンには SSH ではなく、 HTTPS 経由で行う。

次に、 backtrader に読み込ませるヒストリカルデータ(過去の始値高値安値終値、それぞれの頭文字を取ってOHLCデータ1ともいう)のパスを修正する。

# 以下引用: mementum, "Quickstart Guide - Backtrader", 
# "https://www.backtrader.com/docu/quickstart/quickstart/#adding-a-data-feed", 
# アクセス日:2020年10月26日, 最終行とその1行前の修正、日本語のコメント部は著者による
    # Datas are in a subfolder of the samples. Need to find where the script is
    # because it could have been called from anywhere
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    # datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt')  # オリジナル
    datapath = os.path.join(modpath, '/opt/backtrader/datas/orcl-1995-2014.txt')  # 読み込むファイルのパスを修正した

これで準備は整った。 docker-compose up を実行すると、下記のような出力を得られるだろう。

$ docker-compose up
Recreating stock-trading-system_app_1 ... done
Attaching to stock-trading-system_app_1
app_1  | Starting Portfolio Value: 100000.00
app_1  | Final Portfolio Value: 100000.00
stock-trading-system_app_1 exited with code 0

次回はストラテジー(売買戦略)の第一歩を作っていく予定である。


  1. Open, High, Low, Close

(C) 2020 dogwood008 禁無断転載 不許複製 Reprinting, reproducing are prohibited.