![見出し画像](https://assets.st-note.com/production/uploads/images/159047106/rectangle_large_type_2_4f73e3fd5862d8ddbe6ed65c5c3bd31c.png?width=1200)
Photo by
golchiki
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年以上経っており面倒くさいので実装しておりません。興味のある方はチャレンジしてみてはいかがでしょうか。