ロスカットとトレイリングストップの有効性を検証|日経225 FX 4時間足

Posted on July 27th, 2018Updated on October 30th, 2020
ロスカットとトレイリングストップの有効性を検証|日経225 FX 4時間足

※ この記事は最終更新日から4年以上が経過しています。

どんな記事

この記事を読むと、次のことがわかるようになります。

  • ロスカット(Stop Order)の有効性とデータによる裏付け
  • 固定のロスカットとトレイリングストップはどちらが良いのか
  • ATRを基準にする場合、「2-ATR」「3-ATR」のどちらが良いのか

ロスカットは必ず設定しなくてはならない――

これは、投資を長く続けていくのなら絶対に必要なことです。なぜなら、〝絶対はなく、いつ何が起こるかわからない〟のが「相場」 だからです。

そんな「相場」の中、ロスカットの設定は**〝登山家の命綱〟のようにトレーダーを守ってくれます**。

そして、ロスカットと言っても様々なノウハウがあって、実際に運用するとなると何を採用して良いのか迷ってしまいます。そんなときは、確かなデータの裏付けがあると大変心強いです。

最近、ボク自身のトレードルールを再考するにあたって行った「ロスカットに関する検証(バックテスト)」を、備忘録も兼ねてまとめました。

バックテストに使用したツールと価格データ

ここは過去に書いた記事と一緒なので、引用します。

使用したツール

前回同様、バックテストには以下のツールを使用しました。

Python(Google Colaboratory)

Pythonを手軽に試したいなら、Google Colaboratoryがめちゃくちゃオススメです。Google Driveでドキュメントやスプレッドシートを作る感覚でPythonを試すことができます。今回のような、ちゃちゃっと検証したいときに非常に便利です。

使用した価格データ

こちらも前回と同様です。

1分毎の価格データを含むcsvファイル
日経225

MT4のhstファイル
USDJPY、EURJPY、GBPJPY、AUDJPY、EURUSD、GBPUSD、AUDUSD

日経225は独自に保有しているもので、hstファイルはFXDDさんのものを使用しています。

テストする手法

今回はロスカットの検証なので、エントリーやエグジットも以前のロジックを一部流用しています。

今回のバックテストの目的

ロスカットに関する以下の項目の有効性を検証する

  • ロスカットは必要か
  • 固定ロスカットとトレイリングストップ
  • 固定ロスカットの有効な幅
  • トレイリングストップの有効な幅
  • ATRの数値には素直に従うべきか

エントリー

今回は、次の2パターンのエントリーでバックテストを行いました。

ENTRY_Cycle63_FILTER_none
通常のパターン

ENTRY_Cycle63_FILTER_UpperCycle63
上位足のフィルター有りのパターン

「ENTRY」は4時間足のステージで、「FILTER」は日足相当のステージです。

日足のトレンドを、4時間足のエントリーのフィルターとする

バックテスト エントリー

日足のトレンドを確認すると言っても毎回チャートを切り替えるのは手間なので、次の考え方を用います。以下は4時間足であっても、120本の移動平均線は20日相当、240本は40日相当になるということです。

  • 4時間 ✕ 6 = 1日(24時間)
  • 4時間 ✕ 120 = 20日
  • 4時間 ✕ 240 = 40日

また、移動平均のもみ合い時の「だまし」を軽減するために、小次郎講師による移動平均線大循環分析の「ステージ」の考えを用います。

4時間足のトレンド
EMA5とEMA20、EMA40の関係でステージを判断する

日足のトレンド
4時間足のEMA5とEMA120、EMA240の関係でステージを判断する

上昇トレンド
ステージ6:早仕掛け、ステージ1:本仕掛け

下降トレンド
ステージ3:早仕掛け、ステージ4:本仕掛け

決済1

決済1も以前と同じものです。

決済1は、同じく小次郎講師による移動平均線大循環分析の「ステージ」の考えに基づくものです。主に、「利益確定」や、「トレンドがなくなったことを確認した損切り」の決済です。

今回のバックテストでは、ステージによる決済は以下で統一しています。

EXIT1_CycleStage36

通常のパターン(エントリーが遅くなりがち)
買いエントリー(ステージ6か1)はステージ3で決済
売りエントリー(ステージ3か4)はステージ6で決済

バックテスト 決済

決済2

今回の検証の最重要項目です。
まずは検証するパターンをご紹介し、その下でスキームの詳細を解説します。

決済2(EXIT2)のパターン

none
SO_Entry_3_UMSO_Close_3_UM
SO_Entry_3_20SO_Close_3_20
SO_Entry_2_UMSO_Close_2_UM
SO_Entry_2_20SO_Close_2_20

「none」とは

「none」は、ロスカットもトレイリングストップも設定しないパターンです。「ロスカットは必要か」を確認します。

「SO_Entry_N_」「SO_Close_N_」の意味

  • 「固定ロスカットとトレイリングストップ」どちらが良いのか
  • 「固定ロスカットの有効な幅」
  • 「トレイリングストップの有効な幅」

を、確認します。

SO_Entry_N_
エントリーの価格から「N ✕ ATR」マイナス方向にロスカットを設置(固定)
例)SO_Entry_2_:エントリーから2-ATRマイナス方向

SO_Close_N_
「N ✕ ATR」マイナス方向にロスカットを設置し、終値がプラス方向に推移するごとに追随させる
例)SO_Close_3_:3-ATRマイナス方向に設置し、プラス方向に追随

※「SO_Entry_」「SO_Close_」の後ろに記載している数値を「N」とする
バックテスト 決済

「_20」「_UM」とは

この2つのパターンで「ATRの数値には素直に従うべきか」を確認します。

_20(ATR20)
ロスカットやトレイリングストップを「N ✕ 20日ATR」で算出する。

_UM(Upper Middle of ATR20)
ロスカットやトレイリングストップの算出に使用するATRを、過去1800本さかのぼった20日ATRの最高値と最安値の中間以上の値とし(UM-ATR)、「N ✕ UM-ATR」で算出する。

言葉で書くとややこしいので、次のグラフをご覧いただくのが良いと思います。

ATR Upper Middle ATR

上がATR20、下がUM-ATRです。UM-ATRは、「ATR20 > 過去1800本最高値と最安値の中間」のときはATR20を、「ATR20 < 中間の値」のときは中間の値を使います。「なぜ、こんなことをするのか」については、次回の記事で解説したいと思います。

テストするパターン

ここまで解説してきたENTRYやFILTER、EXIT1、EXIT2を組み合わせた以下のパターンの検証を行いました。

EntryFilterExit1Exit2
1Cycle63noneCycle36none
2Cycle63noneCycle36SO_Entry_3_UM
3Cycle63noneCycle36SO_Entry_3_20
4Cycle63noneCycle36SO_Entry_2_UM
5Cycle63noneCycle36SO_Entry_2_20
6Cycle63noneCycle36SO_Close_3_UM
7Cycle63noneCycle36SO_Close_3_20
8Cycle63noneCycle36SO_Close_2_UM
9Cycle63noneCycle36SO_Close_2_20
10Cycle63UpperCycle63Cycle36none
11Cycle63UpperCycle63Cycle36SO_Entry_3_UM
12Cycle63UpperCycle63Cycle36SO_Entry_3_20
13Cycle63UpperCycle63Cycle36SO_Entry_2_UM
14Cycle63UpperCycle63Cycle36SO_Entry_2_20
15Cycle63UpperCycle63Cycle36SO_Close_3_UM
16Cycle63UpperCycle63Cycle36SO_Close_3_20
17Cycle63UpperCycle63Cycle36SO_Close_2_UM
18Cycle63UpperCycle63Cycle36SO_Close_2_20

バックテストの実施と考察

バックテストの関数を作成

ここが一番重要だったりするのですが、ものすごく長くなってしまうので割愛します。こちらのサイトのコードを参考に作成しました((´・ω・`;)ヒィィッ すいません「バックテストを試してみました」

参考として、ストラテジー部分のみ掲載します。

GoogleColab
class Strategy_CycleEMA_Base(StrategyBase) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    StrategyBase.__init__(self ,symbol ,np_arr_dic ,df)

    self.ema5   = ta.EMA(self.c ,5)
    self.ema20  = ta.EMA(self.c ,20)
    self.ema40  = ta.EMA(self.c ,40)
    self.ema120 = ta.EMA(self.c ,120)
    self.ema240 = ta.EMA(self.c ,240)

    self.stage = np.array(list(map(lambda s ,m ,l :
                                  1 if s > m and m > l else \
                                  2 if m > s and s > l else \
                                  3 if m > l and l > s else \
                                  4 if l > m and m > s else \
                                  5 if l > s and s > m else \
                                  6 if s > l and l > m else \
                                  np.nan
                                  ,self.ema5 ,self.ema20 ,self.ema40)))

    self.upper_stage = np.array(list(map(lambda s ,m ,l :
                                    1 if s > m and m > l else \
                                    2 if m > s and s > l else \
                                    3 if m > l and l > s else \
                                    4 if l > m and m > s else \
                                    5 if l > s and s > m else \
                                    6 if s > l and l > m else \
                                    np.nan
                                    ,self.ema5 ,self.ema120 ,self.ema240)))

    self.atrL ,self.atrH = ta.MINMAX(self.atr20 ,1800)
    self.atrM = (self.atrH + self.atrL) / 2

    self.atrUM = np.array(list(map(lambda a ,b :
                                 a if a > b else \
                                 b if a < b else \
                                 a if np.isnan(b)==True and np.isnan(a)==False else \
                                 b if np.isnan(a)==True and np.isnan(b)==False else \
                                 np.nan
                                 ,self.atr20 ,self.atrM)))


  def Base_record_mgmt(self ,i) :

    Pos             = self.count_pos()
    self.count_days = np.nan if Pos==0 else self.count_days + 1
    b4_EntrySig     = False  if Pos==0 else abs(self.mgmt[-1]["EntrySig"])==1
    MTM             = 0      if Pos==0 else ((self.o[i] - self.entry_price) * self.l_s)
    b4_SO_Close     = np.nan if Pos==0 else self.mgmt[-1]["SO_Close"]
    b4_SO_Entry     = np.nan if Pos==0 else self.mgmt[-1]["SO_Entry"]
    pre_SO_Close    = np.nan if Pos==0 and not b4_EntrySig else self.c[i-1] - self.atr[i-1] * self.ATR_N * self.l_s
    pre_SO_Entry    = np.nan if Pos==0 and not b4_EntrySig else self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s
    SO_Close        = np.nan if Pos==0 and not b4_EntrySig else pre_SO_Close if b4_EntrySig or (self.l_s==1 and pre_SO_Close > b4_SO_Close) or (self.l_s==-1 and pre_SO_Close < b4_SO_Close) else b4_SO_Close
    SO_Entry        = np.nan if Pos==0 and not b4_EntrySig else pre_SO_Entry if b4_EntrySig or (self.l_s==1 and pre_SO_Entry > b4_SO_Entry) or (self.l_s==-1 and pre_SO_Entry < b4_SO_Entry) else b4_SO_Entry
    PL              = 0      if len(self.hst)==0 else self.hst[-1]['profit'] if self.mgmt[-1]['ExitSig']==1 else 0
    self.mgmt.append({
        'Time'        : self.df.index[i]
        ,'Open'       : self.o[i]
        ,'High'       : self.h[i]
        ,'Low'        : self.l[i]
        ,'Close'      : self.c[i]
        ,'ATR'        : self.atr[i]
        ,'EMA5'       : self.ema5[i]
        ,'EMA20'      : self.ema20[i]
        ,'EMA40'      : self.ema40[i]
        ,'EMA120'     : self.ema120[i]
        ,'EMA240'     : self.ema240[i]
        ,'Pos'        : Pos
        ,'CountDays'  : self.count_days
        ,'EntrySig'   : 1 if self.opbuy else -1 if self.opsell else 0
        ,'ExitSig'    : 1 if self.clbuy or self.clsell else 0
        ,'L/S'        : self.l_s
        ,'EntryPrice' : self.entry_price
        ,'MTM'        : MTM
        ,'PL'         : PL
        ,'Stage'      : self.stage[i]
        ,'UpperStage' : self.upper_stage[i]
        ,'SO'         : self.SO
        ,'SO_Close'   : SO_Close
        ,'SO_Entry'   : SO_Entry
    })



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_none(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      self.clbuy = any([clbuy_1 ,self.opsell])

    if self.count_sell() > 0 :
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      self.clsell = any([clsell_1 ,self.opbuy])

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Entry_3_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Entry_3_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Entry_2_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Entry_2_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Close_3_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Close_3_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Close_2_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_none__EXIT1_Cycle36__EXIT2_SO_Close_2_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = True
    buy_sig     = self.stage[i] == 6 or self.stage[i] == 1

    sell_filter = True
    sell_sig    = self.stage[i] == 3 or self.stage[i] == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_none(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      self.clbuy = any([clbuy_1 ,self.opsell])

    if self.count_sell() > 0 :
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      self.clsell = any([clsell_1 ,self.opbuy])

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Entry_3_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Entry_3_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Entry_2_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Entry_2_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Entry'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Entry   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Entry
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Entry    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Entry']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Entry
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Close_3_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Close_3_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 3


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Close_2_UM(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atrUM
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)



class ENTRY_Cycle63__FILTER_UpperCycle63__EXIT1_Cycle36__EXIT2_SO_Close_2_20(Strategy_CycleEMA_Base) :

  def __init__(self ,symbol ,np_arr_dic ,df) :

    Strategy_CycleEMA_Base.__init__(self ,symbol ,np_arr_dic ,df)
    self.atr = self.atr20
    self.ATR_N = 2


  def onTick(self ,i) :

    if self.is_nan[i] : return

    if any([self.opbuy ,self.opsell ,self.clbuy ,self.clsell]) :
      if self.SO :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.mgmt[-2]['SO_Close'] ,ATR=self.atr[i-1])
        self.SO = False
      else :
        self.order_proccesing(i ,Entry_Price=self.c[i-1] ,Exit_Price=self.c[i-1] ,ATR=self.atr[i-1])

    opbuy = opsell = clbuy_1 = clbuy_2 = clsell_1 = clsell_2 = False

    buy_filter  = self.upper_stage[i] == 6 or self.upper_stage[i] == 1
    buy_sig     = self.stage[i]       == 6 or self.stage[i]       == 1

    sell_filter = self.upper_stage[i] == 3 or self.upper_stage[i] == 4
    sell_sig    = self.stage[i]       == 3 or self.stage[i]       == 4

    self.opbuy  = buy_filter  and buy_sig  and self.count_buy()==0
    self.opsell = sell_filter and sell_sig and self.count_sell()==0

    if self.count_buy() > 0 :
      SO_Close   = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clbuy_1    = self.stage[i-1] < 3 and (self.stage[i] == 3 or self.stage[i] == 4)
      clbuy_2    = self.l[i] < SO_Close
      self.clbuy = any([clbuy_1 ,clbuy_2 ,self.opsell])
      self.SO    = clbuy_2

    if self.count_sell() > 0 :
      SO_Close    = self.entry_price - self.atr[i-1] * self.ATR_N * self.l_s if self.count_days==0 else self.mgmt[-1]['SO_Close']
      clsell_1    = (self.stage[i-1] < 6 and self.stage[i-1] >= 4) and (self.stage[i] == 6 or self.stage[i] == 1)
      clsell_2    = self.h[i] > SO_Close
      self.clsell = any([clsell_1 ,clsell_2 ,self.opbuy])
      self.SO     = clsell_2

    self.Base_record_mgmt(i)

バックテストを実行

諸々の準備が整ったら、バックテストを実行します。

EntryFilterExit1Exit2
1Cycle63noneCycle36none
2Cycle63noneCycle36SO_Entry_3_UM
3Cycle63noneCycle36SO_Entry_3_20
4Cycle63noneCycle36SO_Entry_2_UM
5Cycle63noneCycle36SO_Entry_2_20
6Cycle63noneCycle36SO_Close_3_UM
7Cycle63noneCycle36SO_Close_3_20
8Cycle63noneCycle36SO_Close_2_UM
9Cycle63noneCycle36SO_Close_2_20
10Cycle63UpperCycle63Cycle36none
11Cycle63UpperCycle63Cycle36SO_Entry_3_UM
12Cycle63UpperCycle63Cycle36SO_Entry_3_20
13Cycle63UpperCycle63Cycle36SO_Entry_2_UM
14Cycle63UpperCycle63Cycle36SO_Entry_2_20
15Cycle63UpperCycle63Cycle36SO_Close_3_UM
16Cycle63UpperCycle63Cycle36SO_Close_3_20
17Cycle63UpperCycle63Cycle36SO_Close_2_UM
18Cycle63UpperCycle63Cycle36SO_Close_2_20
取引回数勝率平均利益/atr平均損失/atr累計損益/atrRR比率期待値/atr
1593229.99%2.908-1.14444.3132.550.074
2595230.07%2.902-1.117554.162.60.092
3596230.24%3.859-1.452932.7112.660.154
4605930.07%2.878-1.078686.3052.670.111
5625629.56%3.803-1.351106.6642.820.173
6632330.97%2.775-1.111593.4782.50.092
7685031.55%3.411-1.387887.3642.460.127
8794733.32%2.323-1.025758.2732.270.091
91004835.10%2.474-1.1881090.3012.080.098
10357333.81%3.069-1.398406.1672.20.113
11363033.25%3.072-1.359436.7122.260.115
12368432.82%4.099-1.746682.2542.350.172
13379231.88%3.08-1.26520.9732.440.124
14404430.07%4.092-1.501837.3182.730.18
15398533.75%2.937-1.322477.5442.220.115
16446333.72%3.564-1.593697.8422.240.146
17528635.36%2.415-1.142674.7622.110.116
18695435.71%2.566-1.261880.7752.040.106

金額にかかる項目はすべてそのときのATRで割った数値を使っています。そうすることで、すべての銘柄の検証結果を同じように扱うことができます。

ロスカットは設定した方が良いか?

まず、ロスカットを設定しないパターンの結果をみてみましょう。

EntryFilterExit1Exit2
1Cycle63noneCycle36none
10Cycle63UpperCycle63Cycle36none
取引回数勝率平均利益/atr平均損失/atr累計損益/atrRR比率期待値/atr
1593229.99%2.908-1.14444.3132.550.074
10357333.81%3.069-1.398406.1672.20.113

次に、基本的な「固定ロスカット」を設定したパターンです。

EntryFilterExit1Exit2
3Cycle63noneCycle36SO_Entry_3_20
5Cycle63noneCycle36SO_Entry_2_20
12Cycle63UpperCycle63Cycle36SO_Entry_3_20
14Cycle63UpperCycle63Cycle36SO_Entry_2_20
取引回数勝率平均利益/atr平均損失/atr累計損益/atrRR比率期待値/atr
3596230.24%3.859-1.452932.7112.660.154
5625629.56%3.803-1.351106.6642.820.173
12368432.82%4.099-1.746682.2542.350.172
14404430.07%4.092-1.501837.3182.730.18

「累計損益」「期待値」ともに、すべてのパターンで上回っていますね。「3-ATR」よりも「2-ATR」の方が、成績が良くなる傾向がありそうです。

ロスカットは設置したほうが良い」と言えそうです。

固定ロスカットとトレイリングストップ

さらに、基本的な「トレイリングストップ」を設定したパターンもみてみましょう。

EntryFilterExit1Exit2
7Cycle63noneCycle36SO_Close_3_20
9Cycle63noneCycle36SO_Close_2_20
16Cycle63UpperCycle63Cycle36SO_Close_3_20
18Cycle63UpperCycle63Cycle36SO_Close_2_20
取引回数勝率平均利益/atr平均損失/atr累計損益/atrRR比率期待値/atr
7685031.55%3.411-1.387887.3642.460.127
91004835.10%2.474-1.1881090.3012.080.098
16446333.72%3.564-1.593697.8422.240.146
18695435.71%2.566-1.261880.7752.040.106

「ロスカットを設定しないパターン」より良い結果ですが、「固定ロスカット」と比較すると少し見劣りする結果になりました。

「固定ロスカット」と「トレイリングストップ」を比較すると、勝率は「トレイリングストップ」の方が良く、リスクリワード比率は「固定ロスカット」の方が良い傾向があります。この点から、「トレイリングストップ」は 早くに〝利確されてしまう〟 ことに問題がありそうです。

単純なトレイリングストップよりも固定ロスカットのほうが良い」と結論づけることができそうです。

固定ロスカット幅は2-ATRか3-ATRか

次は、「固定ロスカット」の幅の比較をします。

EntryFilterExit1Exit2
3Cycle63noneCycle36SO_Entry_3_20
5Cycle63noneCycle36SO_Entry_2_20
12Cycle63UpperCycle63Cycle36SO_Entry_3_20
14Cycle63UpperCycle63Cycle36SO_Entry_2_20
取引回数勝率平均利益/atr平均損失/atr累計損益/atrRR比率期待値/atr
3596230.24%3.859-1.452932.7112.660.154
5625629.56%3.803-1.351106.6642.820.173
12368432.82%4.099-1.746682.2542.350.172
14404430.07%4.092-1.501837.3182.730.18

「3-ATR」よりも「2-ATR」の方が良い結果 になっています。マイナス方向に「2-ATR」進んだエントリーは失敗と判断して良さそうです。

トレイリングストップの幅は2-ATRか3-ATRか

「トレイリングストップ」の幅も確認してみます。

EntryFilterExit1Exit2
7Cycle63noneCycle36SO_Close_3_20
9Cycle63noneCycle36