目次
概要
『ボリンジャーバンドとMACDによるデイトレード』(マルクス・ヘイトコッター)に記載されているトレードルールの検証を行います。
検証方針
本書では、時間に基づいたチャートでなく、ボラティリティに基づいたチャート(レンジバーチャート)を推奨しています。
レンジバーチャートをMT4で表示するためにはインジケーターが必要になり、検証が複雑になります。
いったん普通のチャート(時間足に基づいたチャート)で検証します。
トレードルールの確認
本書に記載されているルールを確認します。
(以下は買う時のルール)
(1) MACDに基づく市場状態が上昇相場でなければならない
以下の2つの条件を満たしている時、上昇相場と考える。
・MACDがゼロラインを上回っている
・MACDがシグナルラインを上回っている
※MACDの設定
長期移動平均線→26期間
短期移動平均線→12期間
シグナルライン→9期間
(2) ボリンジャーバンドが上昇トレンドを示していなければならない
上のバンドが上昇トレンドになっている必要がある。
※ボリンジャーバンドの設定
期間は12で2σラインを使用する
(3) RSI は70を上回っていなければならない
※RSIの設定
期間は7期間を使用する
注文のタイミング
(1)~(3)の条件がすべて満たされたら 上のボリンジャーバンドか、その近くで引ける足の高値の1ティック上に買いの逆指値注文を置く。
利確・損切
7日分のADR(またはATR)を使用し、利確はADRの15%、損切はADRの10%とする。
その他ルール
・週明けの窓が開いている際は、必要に応じてトレードを見送る。
トレードルールの解釈・改造
(1) MACDに基づく市場状態が上昇相場でなければならない
このルールにあいまいさはないです。
(2) ボリンジャーバンドが上昇トレンドを示していなければならない
「上のバンドが上昇トレンドになっている必要がある」
という条件は、「上昇トレンド」をどのように解釈するか人によってぶれると思われます。
単純に解釈するなら、以下のようになります。
(現在の2σラインの値)-( 1つ前の足での2σラインの値)>0
しかし、この解釈だと、上のバンドがほとんど上昇していないフラットな状態でも条件にひっかけてしまう可能性があります。
今回の検証では、以下のように解釈します。
(現在の2σラインの値)-( 1つ前の足での2σラインの値)>10Point(1Pips)
(3)RSI は70を上回っていなければならない
このルールにあいまいさはないです。
注文のタイミング
(1)~(3)の条件がすべて満たされたら 上のボリンジャーバンドか、その近くで引ける足の高値の1ティック上に買いの逆指値注文を置く。
このルールは非常にあいまいです。
逆指値に使用する値は以下の2つがありますが、この2つをどのように使い分けるか全く記載されていません。
「上のボリンジャーバンド」
「その近くで引ける足の高値」
また、日本語もあいまいです。
「1ティック上」という言葉がどこまでかかっているのか不明瞭です。
「1ティック上」という言葉が「上のボリンジャーバンド」という言葉にかかっていると解釈するか、かかっていないと解釈するかで、以下の2パータンの解釈ができます。
・「上のボリンジャーバンド」に逆指値をおく
・「上のボリンジャーバンドの1ティック上」に逆指値をおく
※時間足でこのルールを使う時に、1ティックの値をどう解釈すべきかわかっていませんが、1~3Pips程度で考えればいいと考えています。
今回は時間足を使うので、2σラインを超えていた場合、成り行き注文で仕掛けることにします。
※本書の第7章の「2.成り行き注文を使って仕掛ける」の注意に以下のように記載されています。
「時間足を使っている場合の最も簡単な仕掛けは、成り行き注文で仕掛けることだ」
利確・損切
このルールにあいまいさはないです。
その他ルール
いったん今回の検証では考えないことにします。
ソースコード
※以下のソースコードは、
『FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ)』(豊嶋久道)
で紹介されているライブラリーを使用しています。
そのため、コピペだと動きません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
// マイライブラリー #include <MyLib.mqh> // マジックナンバー #define MAGIC 20094060 #define COMMENT "マルクス本" // 外部パラメータ extern double Lots=0.1; extern int Slippage=3; // エントリー関数 extern int FastMAPeriod = 12; // MACD短期MAの期間 extern int SlowMAPeriod = 26; // MACD長期MAの期間 extern int SignalPeriod= 9; // MACDシグナ宇の期間 extern int RSIHigh= 70; // RSIで売るときのトリガー値 extern int RSILow = 30; // RSIで買うときのトリガー値 extern bool IsUseADR= true; extern int SLpercent= 10; // 損切り値幅(%)。ADRの10% extern int TPpercent= 15; // 利食い値幅(%)。ADRの15% extern int SLpips= 10; // 損切り値幅(pips) extern int TPpips= 20; // 利食い値幅(pips) extern double SlopeLimit=10; extern int RSIPeriod=7; // RSIの期間 extern int ADRPeriod=7; // ADRの期間 extern int BandsPeriod=12; extern int BandsDeviation=2; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int EntrySignal(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); //条件1:MACDに基づく市場状態が上昇相場でなければならない double macd_main_0=iMACD(NULL,0,FastMAPeriod,SlowMAPeriod,SignalPeriod,PRICE_CLOSE,MODE_MAIN,0); double macd_signal_0=iMACD(NULL,0,FastMAPeriod,SlowMAPeriod,SignalPeriod,PRICE_CLOSE,MODE_SIGNAL,0); bool macdOverZero=macd_main_0>0; bool macdOverSignal=macd_main_0>macd_signal_0; bool macdUnderZero=macd_main_0<0; bool macdUnderSignal=macd_main_0<macd_signal_0; //条件2:上のバンドが上昇トレンドになっている必要がある double upperBB_0=iBands(NULL,0,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_UPPER,0); double upperBB_1=iBands(NULL,0,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_UPPER,1); double lowerBB_0=iBands(NULL,0,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_LOWER,0); double lowerBB_1=iBands(NULL,0,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_LOWER,1); double upperBBSlope_0=(upperBB_0-upperBB_1)/Point; double lowerBBSlope_0=(lowerBB_0-lowerBB_1)/Point; double isUpperBBup=upperBBSlope_0>SlopeLimit; double isLowerBBdown=lowerBBSlope_0<-SlopeLimit; //条件3:RSI は70を上回っていなければならない double rsi_0=iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0); bool rsiOverHigh=rsi_0>RSIHigh; bool rsiUnderLow=rsi_0<RSILow; //2σタッチしている bool overUpperBB=Close[0]>upperBB_0; bool underLowerBB=Close[0]<lowerBB_0; bool buySignal=macdOverZero && macdOverSignal && isUpperBBup && rsiOverHigh && overUpperBB; bool sellSignal=macdUnderZero && macdUnderSignal && isLowerBBdown && rsiUnderLow && underLowerBB; int ret=0; // 買いシグナル if(pos<=0 && buySignal) ret=1; // 売りシグナル if(pos>=0 && sellSignal) ret=-1; return(ret); } // スタート関数 int start() { // エントリーシグナル int sig_entry=EntrySignal(MAGIC); // 買い注文 if(sig_entry>0) { MyOrderClose(Slippage,MAGIC); MyOrderSendSL(OP_BUY,Lots,Ask,Slippage,GetSLpips(),GetTPpips(),COMMENT,MAGIC); } // 売り注文 if(sig_entry<0) { MyOrderClose(Slippage,MAGIC); MyOrderSendSL(OP_SELL,Lots,Bid,Slippage,GetSLpips(),GetTPpips(),COMMENT,MAGIC); } return(0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool MyOrderSendSL(int type,double lots,double price,int slippage,int slpips,int tppips,string comment,int magic) { int mult=1; if(Digits == 3 || Digits == 5) mult=10; slippage *= mult; if(type==OP_SELL || type==OP_SELLLIMIT || type==OP_SELLSTOP) mult*=-1; double sl=0,tp=0; if(slpips > 0) sl = price-slpips*Point*mult; if(tppips > 0) tp = price+tppips*Point*mult; return(MyOrderSend(type, lots, price, slippage, sl, tp, comment, magic)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetADR(int timespan) { double sum=0; for(int i=0; i<timespan; i++) { sum+=(iHigh(NULL,PERIOD_D1,i+1)-iLow(NULL,PERIOD_D1,i+1))/Point; } int mult=1; if(Digits==3 || Digits==5) mult=10; return sum/timespan/mult; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetSLpips() { if(IsUseADR) { return GetADR(ADRPeriod)*SLpercent/100; } else { return SLpips; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetTPpips() { if(IsUseADR) { return (int)GetADR(ADRPeriod)*TPpercent/100; } else { return TPpips; } } |
結果
2σラインを超えた状態で(1)~(3)の条件を満たしたら、何度でも、エントリーする頭の悪いEAになってしまいました。
トレードルールではなく、自分のロジックの組み方が悪いですね。
近いうちに少しトレードルールを改造して、再度EAを作成する予定です。
改善点
・損切・利確ルールの改善
利確はADRの15%、損切はADRの10%としていますが、この値が適切なのか少し疑問です。
極端な話をすると、日足でこのトレードルールを使用した時に、ADRの10%(15%)という数字は小さいです。
使用する時間足によって、ADRを計算するための期間や利確・損切に使うパーセントの値は変わると思っています。
また、そもそもADRを使うのが最適かどうかも検討の余地があります。
・エグジットルールの追加
固定した利益が確定したら、エグジットするのではなく、エクスパンションが終わったタイミングを見計らってエクジットを行う。
・リセットルールの追加
一度、エントリーしたら、ボリンジャーバンドの中央線(平均移動線)にタッチしない限り、再エントリーしない。
・エントリータイミングの変更
成り行き注文でなく、逆指値注文するようにロジックを組む。
・パラメータ(期間)の変更
MACD、ボリンジャーバンド、RSIの期間を変える。
特に、ボリンジャーバンドの期間は時間足の場合、20(または21)に設定するのが一般的だと思われます。
関連記事
- 『ボリンジャーバンドとMACDによるデイトレード』をもとに作成したEAを改造する
- 『ボリンジャーバンドとMACDによるデイトレード 世界一シンプルな売買戦略』(マルクス・ヘイトコッター)の感想・レビュー
~FXを始めてみませんか?~
XMは、口座を開設するだけで、3000円のボーナスが無料でもらえます。
資金はないけど、FXを試しに挑戦してみたい方でも大丈夫です。
(サイト主もXMを使用しています)
コメント