Channel Breakout Bot for bitflyer-FX (by Connie-Wild氏)読解メモ29

の続きです。
題材は https://github.com/Connie-Wild/ChannelBreakoutBot です。

前回まででloopメソッドを見終わったので次にバックテストを読んでいきます。

backtest.pyを見てみます。

#_*_ coding: utf-8 _*_
#https://sshuhei.com

import json
import logging
from src import channel

if __name__ == '__main__':
    #logging設定
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S')
    logfile=logging.handlers.TimedRotatingFileHandler(
        filename = 'log/backtest.log',
        when = 'midnight'
    )
    logfile.setLevel(logging.INFO)
    logfile.setFormatter(logging.Formatter(
        fmt='%(asctime)s %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'))
    logging.getLogger('').addHandler(logfile)
    logging.info('Wait...')

    #config.jsonの読み込み
    f = open('config/config.json', 'r', encoding="utf-8")
    config = json.load(f)

    #channelBreakOut設定値
    channelBreakOut = channel.ChannelBreakOut()
    channelBreakOut.entryTerm = config["entryTerm"]
    channelBreakOut.closeTerm = config["closeTerm"]
    channelBreakOut.rangePercent = config["rangePercent"]
    channelBreakOut.rangePercentTerm = config["rangePercentTerm"]
    channelBreakOut.rangeTerm = config["rangeTerm"]
    channelBreakOut.rangeTh = config["rangeTh"]
    channelBreakOut.waitTerm = config["waitTerm"]
    channelBreakOut.waitTh = config["waitTh"]
    channelBreakOut.candleTerm = config["candleTerm"]
    channelBreakOut.cost = config["cost"]
    channelBreakOut.fileName = config["fileName"]
    channelBreakOut.showFigure = config["showFigure"]
    channelBreakOut.sendFigure = config["sendFigure"]
    channelBreakOut.showTradeDetail = config["showTradeDetail"]

    #バックテスト
    channelBreakOut.describeResult()
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S')
    logfile=logging.handlers.TimedRotatingFileHandler(
        filename = 'log/backtest.log',
        when = 'midnight'
    )

ログ設定をまず行います。
参考: https://docs.python.jp/3/library/logging.html#logging.basicConfig
loggingを使って出力するログの設定です。
TimedRotatingFileHandlerでログローテーションを設定します。

    logfile.setLevel(logging.INFO)
    logfile.setFormatter(logging.Formatter(
        fmt='%(asctime)s %(levelname)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'))
    logging.getLogger('').addHandler(logfile)
    logging.info('Wait...')

ログファイルのフォーマット設定を行い、ログにwaitを出力します。

    #config.jsonの読み込み
    f = open('config/config.json', 'r', encoding="utf-8")
    config = json.load(f)

    #channelBreakOut設定値
    channelBreakOut = channel.ChannelBreakOut()
    channelBreakOut.entryTerm = config["entryTerm"]
    channelBreakOut.closeTerm = config["closeTerm"]
    channelBreakOut.rangePercent = config["rangePercent"]
    channelBreakOut.rangePercentTerm = config["rangePercentTerm"]
    channelBreakOut.rangeTerm = config["rangeTerm"]
    channelBreakOut.rangeTh = config["rangeTh"]
    channelBreakOut.waitTerm = config["waitTerm"]
    channelBreakOut.waitTh = config["waitTh"]
    channelBreakOut.candleTerm = config["candleTerm"]
    channelBreakOut.cost = config["cost"]
    channelBreakOut.fileName = config["fileName"]
    channelBreakOut.showFigure = config["showFigure"]
    channelBreakOut.sendFigure = config["sendFigure"]
    channelBreakOut.showTradeDetail = config["showTradeDetail"]

    #バックテスト
    channelBreakOut.describeResult()

バックテストしたい値を入力したconfigを読み込み、バックテストを開始します。

describeResultメソッドを見ていきます。

    def describeResult(self):
        """
        signalsは買い,売り,中立が入った配列
        """
        if self.fileName == None:
            if "H" in self.candleTerm:
                candleStick = self.cryptowatch.getSpecifiedCandlestick(2000, "3600")
            elif "30T" in self.candleTerm:
                candleStick = self.cryptowatch.getSpecifiedCandlestick(4000, "1800")
            elif "15T" in self.candleTerm:
                candleStick = self.cryptowatch.getSpecifiedCandlestick(5999, "900")
            elif "5T" in self.candleTerm:
                candleStick = self.cryptowatch.getSpecifiedCandlestick(5999, "300")
            elif "3T" in self.candleTerm:
                candleStick = self.cryptowatch.getSpecifiedCandlestick(5999, "180")
            else:
                candleStick = self.cryptowatch.getSpecifiedCandlestick(5999, "60")
        else:
            candleStick = self.readDataFromFile(self.fileName)

ファイルが指定されていない場合はgetSpecifiedCandlestickメソッドを使って指定された個数のローソク足を取得します。
ファイルが指定されている場合はそのファイルからローソク足情報を読み込みます。
readDataFromFileメソッドを見てみます。

    #csvファイル(ヘッダなし)からohlcデータを作成.
    def readDataFromFile(self, filename):
        with open(filename, 'r', encoding="utf-8") as f:
            reader = csv.reader(f)
            header = next(reader)
            for row in reader:
                candleStick = [row for row in reader if row[4] != "0"]
        dtDate = [datetime.datetime.strptime(data[0], '%Y-%m-%d %H:%M:%S') for data in candleStick]
        dtTimeStamp = [dt.timestamp() for dt in dtDate]
        for i in range(len(candleStick)):
            candleStick[i][0] = dtTimeStamp[i]
        candleStick = [[float(i) for i in data] for data in candleStick]
        return candleStick

readmeにある通り、対象ファイルにはohlcデータが入っていることが期待されています。
参考: https://github.com/Connie-Wild/ChannelBreakoutBot#optimization%E7%94%A8%E3%81%AEohlc%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%8F%96%E5%BE%97
対象ファイルを1行づつ読み、たまにcloseの値が0になるケースをskipしながらcandleStickにローソク足情報を入れていきます。
candleStickの0番目には日時情報が入っているので、それをdatetimeに変換した配列をdtDate配列とします。

15分経ったので今日はここまで。

↓次


この記事が気に入ったらサポートをしてみませんか?