目次
概要
この記事では、『FXチャート実践帳・スキャルピング編』(二階堂重人)に記載されているトレードルールをもとにEAを作成します。
また、作成したEAが儲かるかどうか検証結果を記載しています。
トレードルールの確認
『FXチャート実践帳・スキャルピング編』(二階堂重人)に記載されているトレードルールを確認します。
エントリー(買い)の条件
以下の6つの条件を全て満たした際に、エントリーする。
※条件1~条件6は同時に満たすのではなく、条件1→条件2→…→条件6の順番に満たしていく
条件1 急騰か大きく上昇してセンターバンドが上向きになっている
条件2 ストキャスティクスが80パーセント以上になる
条件3 +2σと-2σの間隔が目安以上に広がる
条件4 陰線を中心にして下落
条件5 ストキャスティクスが20パーセントを割る
条件6 センターバンド付近でV字反発
エントリー(売り)の条件
以下の6つの条件を全て満たした際に、エントリーする。
※条件1~条件6は同時に満たすのではなく、条件1→条件2→…→条件6の順番に満たしていく
条件1 急落か大きく下降して、センターバンドが下向きになっている
条件2 ストキャスティクスが20パーセント以下になる
条件3 +2σと-2σの間隔が目安以上に広がる
条件4 陽線を中心にして下落
条件5 ストキャスティクスが80パーセント以上になる
条件6 センターバンド付近で逆V字反落
トレードルールのEA化
上記のルールをソースコードに落とし込む際に、トレードルールにあいまいな所(数値に落とし込みづらい所)があります。
まずは、1つ1つの条件をどのように、数式として定義していくか考えてみましょう。
以下では、エントリー(買い)の条件を対象に考えます。
※エントリー(売り)の条件はエントリー(買い)の条件の裏返しなので確認しません。
条件1 急騰か大きく上昇してセンターバンドが上向きになっている
この条件は、以下のように2つ分割できます。
「急騰か大きく上昇して」「センターバンドが上向きになっている」
「急落か大きく下降して」の部分の定義は、何をもって、「急落」と定義するのか人によって変わるので、数値化するのは難しいです。
「急落」の考えられる解釈は以下の通りです。
・センターバンドの傾きが過去の一定期間で、負から正になったか?
・センターバンドの傾きが過去の一定期間で、劇的に変化した箇所があるか?
・ボリンジャーバンドで+2σタッチしているか?
※この部分はあいまいさがあるので、以下で紹介するEAには条件として組み込んでいません。
「センターバンドが上向きになっている」は、以下のように解釈できます。
(現在のセンターバンドの数値)-が(1つ前の足のセンターバンドの数値)より大きい。
これを素直に数値化すると以下のようになります。
(現在のセンターバンドの数値)- (1つ前の足のセンターバンドの数値)>0
しかし、この条件だと、(現在のセンターバンドの数値)と(1つ前の足のセンターバンドの数値)の値がほぼ等しい状況でも条件に当てはまってしまいます。その結果、傾きがほぼないフラットな状況でも条件を満たしてしまいます。
そこで、十分に傾いていることを条件にしたいのなら、以下のようにします。
(現在のセンターバンドの数値)- (1つ前の足のセンターバンドの数値)>1Pips
条件2 ストキャスティクスが80パーセント以上になる
この条件自体にはほとんどあいまいさがありません。
※ストキャスティクスの判断の仕方に若干のブレが発生するかもしれません。ただ、ぶっちゃけ結果にほとんど差異を与えないと思われます
・MT4でストキャスティクスを表示するとMainラインとSignalラインの2つが表示されるが、どちらを使用するか?
・MT4でapplied_fieldをLow/Highにするか、Close/Closeにするか?
・足が確定してから判断するか、リアルタイムで判断するか?
プログラムを組む上で難しいのは、「ストキャスティクスが80パーセント以上になる」になったというシグナルをどのように管理するかです。
本書のトレードルールは、条件1→条件2→…→条件6の順番に満たしてからトレードします。
条件3以降で、条件を満たさなかった場合、条件2のシグナルを破棄する必要があります。
今回作成するEAでは、
「条件5 ストキャスティクスが20パーセントを割る」を満たしていることを確認してから、過去一定期間を探索して「条件2 ストキャスティクスが80パーセント以上になる」を満たしているかどうか確認しています。
条件3 +2σと-2σの間隔が目安以上に広がる
本章のP59には。「大きく上昇した高値、大きく下降した安値の位置で±2σの幅を確認」と記載されています。
プログラムを組む上で面倒なのは、どこまでの範囲(あるいはどうやって)高値・安値を探すかです。
まじめにやるなら、「条件2 ストキャスティクスが80パーセント以上になる」を満たしている付近で、一定の期間分の高値を探索すればいいです。
以下のEAでは、
現在の足から、さかのぼっていって最初に見つかった「条件2 ストキャスティクスが80パーセント以上になる」を満たす足に対して、+2σと-2σの間隔を確認するというロジックを組んでいます。
そのため、必ずしも、その付近の高値であるとは限りません。
+2σと-2σの間隔、P59に、ユーロ/米ドルなら、35Pipsあればいいと本書では記載されています。
以下のEAでは、少し条件を緩めて20Pips(200Point)としています。
条件4 陰線を中心にして下落
この部分は非常にあいまいで、どのようにでも解釈できてしまいます。
本章P68では「きれいに並んでいるときだけエントリーする」と記載されていますが、「きれい」って何?ってつっこみたい気分です。
考えられる解釈は以下の通りです。
・陰線の割合が一定以上
(例)80%以上が陰線
・陽線がある場合、それより以前にある陰線の高値を上回っていない
この条件はあいまいなので、EAにはこの条件を組み込みません。
条件5 ストキャスティクスが20パーセントを割る
「条件2 ストキャスティクスが80パーセント以上になる」と内容が被るので、割愛します。
条件6 センターバンド付近でV字反発
この条件は、以下のように2つ分割できます。
「センターバンド付近」で「V字反発」
「センターバンド付近」という記載がかなりあいまいです。
本書では、以下のような記載があります。
「センターバンドから少し離れている場合は、各自の判断でエントリーしてよい」
「大きく離れている場合は見送ります」
「V字の確定足の終値はセンターバンドの上にあることが絶対条件です」
「センターバンド付近」というのは以下のような解釈ができます。
V字を構成する3本の足(1つ目の足・2つ目の足・3つ目の足・全部・どれか1本)
の値段(始値・終値)が
・±1σラインの内側にある
・センターバンドから一定の値幅以内である
このように自由に「センターバンド付近」という条件を決められるので、いったんこの条件は考えず、プログラムのロジックには組み込みません。
「V字反発」していることは陰線→陽線→陽線となっているかどうかで判断します。
「V字の確定足の終値はセンターバンドの上にあることが絶対条件です」という記載があるので、現在の足が、センターバンドより上にあるという条件を加えます
EA作成にあたって無視したルール
以上まとめると、以下の部分を無視してEAを作成します。
条件1 「急騰か大きく上昇して」
条件4 「陰線を中心にして下落」
条件6 「センターバンド付近」
EA作成にあたって追加したルール
・利確20Pips。損切10Pips
・現在のセンターバンドの傾きが上(下)に切り替わったら、エントリーの売り(買い)の条件を途中まで満たしている場合でも、その条件を一度白紙に戻す
ソースコード
※以下のソースコードは、
『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 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
// マイライブラリー #include <MyLib.mqh> // マジックナンバー #define MAGIC 20094060 #define COMMENT "二階堂本(公開用)" // 外部パラメータ extern double Lots=0.1; extern int Slippage=3; extern int SLpips= 10; // 損切り値幅(pips) extern int TPpips= 20; // 利食い値幅(pips) extern int BandsPeriod=20; extern int BandsDeviation=2; extern int HighStochastic=80; extern int LowStochastic=20; extern int LimitSlopePoint=10; //300から条件緩める extern int LimitVolatilityPoint=200; //メンバ変数 bool _entry_Buy=false; bool _entry_Sell=false; bool _signal_Buy=false; bool _signal_Sell=false; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int EntrySignal(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); double mainBand_close0=iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_MAIN,0); //センターバンドの傾き double mainBandSlope_close0=(iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_MAIN,0) -iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_MAIN,1))*2/Point; bool isUpMA=mainBandSlope_close0>0; bool isDownMA=mainBandSlope_close0<0; double stochastic=iStochastic(NULL,NULL,5,3,3,MODE_SMA,0,MODE_MAIN,0); bool isOverHighStochastic=stochastic>HighStochastic; bool isUnderLowStochastic=stochastic<LowStochastic; if(isUpMA && isUnderLowStochastic && SearchHighStochastic()>0 && pos==0) { bool isEnoughHighSlope=MainBandSlope(SearchHighStochastic())>LimitSlopePoint; bool isEnoughVolatility_Buy=Volatility(SearchHighStochastic())>LimitVolatilityPoint; if(isEnoughHighSlope && isEnoughVolatility_Buy) { //買いシグナル _signal_Buy=true; } } if(isDownMA && isOverHighStochastic && SearchLowStochastic()>0 && pos==0) { bool isEnoughLowSlope=MainBandSlope(SearchLowStochastic())<-LimitSlopePoint; bool isEnoughVolatility_Sell=Volatility(SearchLowStochastic())>LimitVolatilityPoint; if(isEnoughLowSlope && isEnoughVolatility_Sell) { //売りシグナル _signal_Sell=true; } } //買いシグナルの消失 if(!isUpMA) { _signal_Buy=false; } //売りシグナルの消失 if(!isDownMA) { _signal_Sell=false; } //現在の値段がセンターバンドより上 bool isOverMA=Close[0]>mainBand_close0; bool isUnderMA=Close[0]<mainBand_close0; //1つ前の足(V字の3本目)が陽線+2つ前の足(V字の2本目)が陽線+3つ前の足(V字の1本目)が陰線 bool isVShaped=IsWhiteCandl(1) && IsWhiteCandl(2) && !IsWhiteCandl(3); //1つ前の足(逆V字の3本目)が陰線+2つ前の足(逆V字の2本目)が陰線+3つ前の足(逆V字の1本目)が陽線 bool isReverseVShaped=!IsWhiteCandl(1) && !IsWhiteCandl(2) && IsWhiteCandl(3); bool buyEntry=_signal_Buy && isOverMA && isVShaped; bool sellEntry=_signal_Sell && isUnderMA && isReverseVShaped; int ret=0; // 買いシグナル if(pos<=0 && buyEntry) { ret=1; _signal_Buy=false; _signal_Sell=false; } // 売りシグナル if(pos>=0 && sellEntry) { ret=-1; _signal_Buy=false; _signal_Sell=false; } return(ret); } // スタート関数 int start() { // エントリーシグナル int sig_entry=EntrySignal(MAGIC); // 買い注文 if(sig_entry>0) { MyOrderClose(Slippage,MAGIC); MyOrderSendSL(OP_BUY,Lots,Ask,Slippage,SLpips,TPpips,COMMENT,MAGIC); } // 売り注文 if(sig_entry<0) { MyOrderClose(Slippage,MAGIC); MyOrderSendSL(OP_SELL,Lots,Bid,Slippage,SLpips,TPpips,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)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsWhiteCandl(int timeshift) { if(Close[timeshift]>Open[timeshift]) { return true; } else { return false; } } //Stochasticが20になった状態で直近の最大値を探す //3回連続最大値が更新されなかったら探索打ち切り //80以上が見つかったら探索打ち切り int SearchHighStochastic() { int nowMaxStochastic=0; //最後にnowMaxStochasticをUpdateしたのかを管理する int lastUpdate=0; int searchRange=20; for(int i=0;i<searchRange;i++) { double stochastic=iStochastic(NULL,NULL,5,3,3,MODE_SMA,0,MODE_MAIN,i); if(stochastic>nowMaxStochastic) { nowMaxStochastic=stochastic; lastUpdate=0; } else { lastUpdate+=1; } if(lastUpdate>2) { return -1;//見つからなかったら-1を返す } if(nowMaxStochastic>HighStochastic) { return i; } } } //+------------------------------------------------------------------+ //Stochasticが80になった状態で直近の最小値を探す //3回連続最小値が更新されなかったら探索打ち切り //20以下が見つかったら探索打ち切り int SearchLowStochastic() { int nowMinStochastic=100; //最後にnowMinStochasticをUpdateしたのかを管理する int lastUpdate=0; int searchRange=20; for(int i=0;i<searchRange;i++) { double stochastic=iStochastic(NULL,NULL,5,3,3,MODE_SMA,0,MODE_MAIN,i); if(stochastic<nowMinStochastic) { nowMinStochastic=stochastic; lastUpdate=0; } else { lastUpdate+=1; } if(lastUpdate>2) { return -1;//見つからなかったら-1を返す } if(nowMinStochastic<LowStochastic) { return i; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double MainBandSlope(int timeshift) { return (iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_LOWER,timeshift) -iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_LOWER,timeshift+1))*2/Point; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double Volatility(int timeshift) { //ボラリティの判断 return (iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_UPPER,timeshift) -iBands(NULL,0,BandsPeriod,1,0,PRICE_CLOSE,MODE_LOWER,timeshift))/Point; } //+------------------------------------------------------------------+ |
作成したEAの結果
2017~2018年の期間で、スプレッド10Point(1Pips)で検証しています。
プロフィットファクタは1.24で、利益を出しています。
※(注)記事には記載していないが、2016~2017年では利益を上げていなかったので、安定しているとは言い難いです。
考察
条件6の「センターバンド付近」を無視した結果、あまり想定していない箇所でエントリーしています。
センターバンドの大きく外れた2σライン付近でエントリーしていることがそこそこあります。
本書で紹介されている手法は押し目買いや戻り売りを狙うのですが、自分の作成したEAは、押し目・戻りを捉えているとは言い難いです。
改善案
・損切の位置を改善する。
(案1)±1σラインを使う
(案2)条件6のV字の真ん中の足の安値・高値を使う
・上位時間軸の情報を取り込む
・時間軸を変える
・深めの押し目・戻りを捉えられるようにする
→「V字の確定足の終値はセンターバンドの上にある」という条件を緩める必要がある。
・無視した条件(条件1・4・6)をルールに組み込む。
今後の予定
作成してみた結果、そんなに悪い結果ではなかったです。
改造すれば、実用に耐えうるEAができるのではないかと思っています。
機会があれば、いつか改善します。
~FXを始めてみませんか?~
XMは、口座を開設するだけで、3000円のボーナスが無料でもらえます。
資金はないけど、FXを試しに挑戦してみたい方でも大丈夫です。
(サイト主もXMを使用しています)
コメント