見出し画像

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

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

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):
    # 計算日数
    BUY_DAYS = 20
    SELL_DAYS = 10
    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.BUY_DAYS + 1:
                return False
            # 過去4週(20日)の高値ブレイクアウト
            # 前日
            high_list = self.price.high_list
            period = self.BUY_DAYS
            back_days = 1
            ytd_highest = Ind.highest(high_list, price_days, period, back_days)
            if ytd_highest is None:
                return False
            # 本日
            today_close = self.price.close
            # 判定
            if today_close > ytd_highest:
                # 前回のトレードで利益が出た場合は次のシグナルをスキップする。
                if self.trade.is_skip_trade:
                    self.trade.is_skip_trade = False
                else:
                    can_buy = True
        return can_buy

    # ロスカット価格の算出
    def calc_loss_cut_price(self, open_price):
        # ATR
        high_list = self.price.high_list
        low_list = self.price.low_list
        close_list = self.price.close_list
        price_days = self.price.days
        period = self.ATR_DAYS
        back_days = 0
        atr = Ind.atr(high_list, low_list, close_list, price_days, period, back_days)
        if atr is None:
            return None
        # 購入価格-2N(NはATRのこと)
        loss_cut_price = round(open_price - (atr * 2), 2)
        return loss_cut_price

    # 売り可能判定(売買)
    def is_sell_signal(self):
        can_sell = False
        if self.trade.is_hold:
            # 過去2週(10日)の安値ブレイクアウト
            low_list = self.price.low_list
            price_days = self.price.days
            period = self.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
    # 損切
    def loss_cut(self):
        can_sell = False
        if self.trade.is_hold:
            # 購入日以外で始値、安値がロスカット価格以下
            if self.trade.buy_date is not None:
                if self.trade.buy_date != self.price.date:
                    loss_cut_price = self.trade.loss_cut_price
                    if self.price.open <= loss_cut_price or self.price.low <= loss_cut_price:
                        can_sell = True
        return can_sell
    # 売買結果を作成
    def trading(self):
        if self.trade.hold_days is not None:
            self.trade.hold_days += 1
        # 買い
        if self.can_buy():
            if not self.ignore_signal():
                loss_cut_price = self.calc_loss_cut_price(self.price.open)
                if loss_cut_price is not None:
                    self.trade.loss_cut_price = loss_cut_price
                    self.buy(self.price.open)
                    self.trade.buy_date = self.price.date
                    self.trade.hold_days = 1
        elif self.loss_cut():
            loss_cut_price = self.trade.loss_cut_price
            sell_price = loss_cut_price
            # 始値がロスカット価格以下なら始値
            if self.price.open <= loss_cut_price:
                sell_price = self.price.open
            self.sell(sell_price, Reason.LOSS.value)
        # 損益の判定
        if self.trade.profit is not None:
            if self.trade.profit >= 0:
                # 利益
                self.trade.is_skip_trade = True
            else:
                # 損失
                self.trade.is_skip_trade = False
        # シグナル
        self.set_signals()
        # 売買結果
        return self.trade.get_trading_values()

タートルズのシステム1について

タートルズのシステム1については以下のサイトを参考にしてください。

売買条件について

終値が過去20日の高値を上抜けたら買い、過去10日の安値を下抜けたら売り(手仕舞い)、購入時の株価から20日ATRの2倍逆行した場合損切となっています。前回のトレードで利益が出た場合は次のシグナルをスキップします。

その他にユニットという考え方による資金管理と増し玉(ピラミッティング)がありますが、私はプログラマーを引退して3年以上経っており面倒くさいので実装しておりません。興味のある方はチャレンジしてみてはいかがでしょうか。

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