見出し画像

Tradeクラスの実装例 ⑨タートルズのシステム1+2

バックテストで使用するTradeクラスの実装例として、タートルズのシステム1とシステム2を使用した例を挙げておきます。

from output.trade.trade_base import TradeBase, Reason
from signals.indicator import Indicator as Ind
from signals.price_util import PriceUtil as PUtil


class Trade(TradeBase):
    # 計算日数
    S1_BUY_DAYS = 20
    S1_SELL_DAYS = 10
    S2_BUY_DAYS = 55
    S2_SELL_DAYS = 20
    ATR_DAYS = 20

    def __init__(self, price_row, price_values, trade_values, investment):
        super().__init__(price_row, price_values, trade_values, investment)

    # 買い可能判定(売買)
    def is_buy_signal(self):
        can_buy = False
        if not self.trade.is_hold:
            price_days = self.price.days
            if price_days < self.S1_BUY_DAYS + 1:
                return False
            # 過去4週(20日)の高値ブレイクアウト
            # 前日
            high_list = self.price.high_list
            period = self.S1_BUY_DAYS
            back_days = 1
            s1_ytd_highest = Ind.highest(high_list, price_days, period, back_days)
            if s1_ytd_highest is None:
                return False
            # 本日
            today_close = self.price.close
            # 判定
            if today_close > s1_ytd_highest:
                # 前回のトレードで利益が出た場合は次のシグナルをスキップする。
                if self.trade.is_skip_trade:
                    self.trade.is_skip_trade = False
                    # ただし過去11週(55日)の高値ブレイクアウトの場合はスキップしない。
                    period = self.S2_BUY_DAYS
                    s2_ytd_highest = Ind.highest(high_list, price_days, period, back_days)
                    if s2_ytd_highest is None:
                        return False
                    if today_close > s2_ytd_highest:
                        can_buy = True
                        self.trade.is_last_exit_profit = True
                else:
                    can_buy = True
                    self.trade.is_last_exit_profit = False
        return can_buy
    # 売り可能判定(売買)
    def is_sell_signal(self):
        can_sell = False
        if self.trade.is_hold:
            low_list = self.price.low_list
            price_days = self.price.days
            if self.trade.is_last_exit_profit:
                # 過去4週(20日)の安値ブレイクアウト
                period = self.S2_SELL_DAYS
            else:
                # 過去2週(10日)の安値ブレイクアウト
                period = self.S1_SELL_DAYS
            back_days = 1
            ytd_lowest = Ind.lowest(low_list, price_days, period, back_days)
            if ytd_lowest is None:
                return False
            # 本日
            today_close = self.price.close
            # 判定
            if today_close < ytd_lowest:
                can_sell = True
        return can_sell

売買条件について

システム1の売買条件に以下の条件を追加しています。
①システム1の買いシグナルをスキップした場合にシステム2の判定を行う。
②システム2の判定は、終値が過去55日の高値を上抜けたら買い、過去20日の安値を下抜けたら売り(手仕舞い)。

今回はシステム2の売買判定を行うためにoutput/values/trade_values.pyに定義されているis_last_exit_profitをフラグとして使用しました。これはシステム2の判定用に用意したものではありません。別のトレードクラスで使用していたものを使い回ししています。値を保持し続けるフラグが必要な場合はoutput/values/trade_values.pyに新たに変数を追加してください。

残念ながらタートルズのシステムは勝率が低いです。この勝率の低さは逆に利用できないものかと考えてしまいます。


いいなと思ったら応援しよう!