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

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

backtrader 最初の戦略その1

f:id:dogwood008:20201023005656j:plain
Photo by Pixabay from Pexels

前回の振り返り

前回はヒストリカルデータ(過去データ)を読み込めるようにした。

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

今回の内容

最初の取引戦略1を実装していく。

www.backtrader.com

# 以下引用: mementum, "Quickstart Guide - Backtrader", 
# "https://www.backtrader.com/docu/quickstart/quickstart/#our-first-strategy", 
# アクセス日:2020年10月26日, 日本語のコメント部と1,2行目のコメントアウトは著者による

# 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


# Create a Stratey ここから売買戦略だが、まだ基本的には何かを参照して売買を決めるような戦略は作らない
class TestStrategy(bt.Strategy):

    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close  # `self.dataclose` に今着目しているローソク足の終値を代入する
        # 「今」とは、バックテスト中では1営業日ずつ進むその年月日を指す

    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])


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

    # Add a strategy
    cerebro.addstrategy(TestStrategy)

    # 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 before this date
        todate=datetime.datetime(2000, 12, 31),
        # Do not pass values after this date
        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())

中でも着目すべきは、下記の TestStrategy である。 TestStrategybacktrader.Strategy を継承して作成する。

# Create a Stratey ここから売買戦略だが、まだ基本的には何かを参照して売買を決めるような戦略は作らない
class TestStrategy(bt.Strategy):

そこでは log __init__ next が並んでいる。それぞれ次のような役割を持つ。

log(self, txt, datetime): ログを出力するロジック。サンプルでは print() が使われているが、あまり推奨しない。代わりに logginglogger を使用したい(理由:ログ出力のための print と import logging はやめてほしい - Qiita)。

    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

__init__(self): バックテスト実行直前2に実行される。 self.dataclose に今着目しているローソク足の終値が代入されるように、参照(ポインタ)を格納しておく

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close  # `self.dataclose` に今着目しているローソク足の終値が代入されるように、参照(ポインタ)を格納しておく
        # 「今」とは、バックテスト中では1営業日ずつ進むその年月日を指す

next(self): 次のローソク足が読み込まれたタイミングで呼ばれる。

    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])

次回はもう少し突っ込んで、これを実行した結果を見てみる。


  1. Out First Strategy

  2. インスタンスが作成された際

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