目次
はじめに
スキャルピングを扱った『最強のFX 1分足スキャルピング』(ぶせな)の手法が有効か確認します。
まずはこの本で紹介されているトレードルールから見ていきましょう。
トレードルール
エントリールール
・1分足で、エンベロープの偏差0.1%のラインにタッチ
※偏差0.1%ラインだけでなく、0.15%、0.2%、0.25%、0.3%、0.4%も使用する。
・タッチ後、ヒゲがでる(反転を確認する)
※偏差0.1%は0.15%の場合は、1回分値段が反転したら、エントリーする。
※偏差0.2%以上の場合は、2回分値段が反転したら、エントリーする。
エクジットルール
・利確、損切は2Pips
その他ルール
・一度エントリーしたら、平均移動線にタッチするか、より偏差の大きいラインにタッチするまで、エントリーしない
・一度偏差の大きいラインにタッチしたら、偏差の小さいラインにタッチしてもエントリーしない
(例)偏差0.15%のラインをタッチしでエントリーしたら、偏差0.1%のラインではエントリーしない
トレードルールの改造
さて、このトレードルールを検証するにあたって、以下のルールが問題となります。
「偏差0.1%は0.15%の場合は、1回分値段が反転したら、エントリーする。」
MT4がどのように疑似ティックを生成しているのか不明ですが、実際の取引を正確に再現はできません。
「1回分値段が反転」するという1分足以下のデータを要するバックテストを正確に行うことは難しいです。
そこで、本記事では、このルールの代わりに
「直近の最大値(最小値)と比較して、1Pips以上戻ったタイミングでエントリーする」
というルールを採用します。
また、偏差0.15%、0.2%、0.25%、0.3%、0.4%での取引は行いません。
偏差0.1%以外のラインでタッチが発生することは稀な上、ソースコードが複雑になるためです。
本記事では、以下の2つのトレードルールで検証します。
(1)反転を確認しないパターン
エントリールール
・エンベロープの偏差0.1%のラインにタッチした直後、逆張りする
エクジットルール
・利確、損切は2Pips
・平均移動線に交差する。
※『最強のFX 1分足スキャルピング』の取引頻度は本当に少ないか?の記事の名残で残っているルールです。このルールは基本使われません。「利確、損切は2Pips」のルールが先に使用されます。
(2)反転を確認するパターン
エントリールール
・エンベロープの偏差0.1%のラインにタッチした後、直近の最大値(最小値)と比較して、1Pips以上戻ったタイミングで逆張りする
エクジットルール
・利確、損切は2Pips
・平均移動線に交差する。
※『最強のFX 1分足スキャルピング』の取引頻度は本当に少ないか?の記事の名残で残っているルールです。このルールは基本使われません。「利確、損切は2Pips」のルールが先に使用されます。
(1) 反転を確認しないパターンのソースコード
※以下のソースコードは、
『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 |
// マイライブラリー #include <MyLib.mqh> // マジックナンバー #define MAGIC 20094060 #define COMMENT "ぶせな本(簡易版)" // 外部パラメータ extern double Lots=0.1; extern int Slippage=3; extern int SLpips=2; // 損切り値幅(pips) extern int TPpips=2; // 利食い値幅(pips) extern ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; extern ENUM_MA_METHOD ma_method=MODE_EMA; extern int ma_period=20; //状態管理(どのラインでエントリーしたか管理する) bool _entry_P10=false; bool _entry_M10=false; datetime _latestTime=0;; //+------------------------------------------------------------------+ int EntrySignal(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); double envelope_P10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_UPPER,0); double envelope_M10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_LOWER,0); //closeがenvelope_P10より高い bool isOverP10=Close[0]>envelope_P10; bool isUnderM10=Close[0]<envelope_M10; bool BuySignal=isUnderM10 && !_entry_M10; bool SellSignal=isOverP10 && !_entry_P10; int ret=0; // 買いシグナル if(pos<=0 && BuySignal) { _entry_M10=true; ret=1; } // 売りシグナル if(pos>=0 && SellSignal) { _entry_P10=true; ret=-1; } return(ret); } // エグジット関数 void ExitPosition(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); double ma=iMA(NULL,0,ma_period,0,ma_method,applied_price,0); double envelope_P10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_UPPER,0); double envelope_M10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_LOWER,0); //平均移動線が交差する bool isOverMa=Close[0]>ma; bool isUnderMa=Close[0]<ma; int ret=0; //if(pos < 0 && 売りポジションの決済シグナル) ret = 1; if(pos<0 && isUnderMa) ret=1; //if(pos > 0 && 買いポジションの決済シグナル) ret = -1; if(pos>0 && isOverMa) ret=-1; // オープンポジションの決済 if(ret!=0) MyOrderClose(Slippage,magic); } // スタート関数 int start() { CheckCrossMa(); // 売買ポジションのエグジット ExitPosition(MAGIC); // エントリーシグナル 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)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CheckCrossMa() { double ma_0=iMA(NULL,0,ma_period,0,ma_method,applied_price,0); //平均移動線が交差する bool isOverMa=Open[0]<ma_0 && High[0]>ma_0; bool isUnderMa=Open[0]>ma_0 && Low[0]<ma_0; if(isOverMa || isUnderMa) { _entry_P10=false; _entry_M10=false; } } //+------------------------------------------------------------------+ |
(1)反転を確認しないパターンの結果
利確、損切は2Pipsの場合、きれいな右肩下がりになりました。
利確10Pips、損切は5Pipsの場合、下がっていますが、一定の割合できれいに下がっているわけではありません。
※この検証だけ、1年間分検証を行っています。他の検証は3年間分行っています。
(2) 反転を確認するパターンのソースコード
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 |
// マイライブラリー #include <MyLib.mqh> // マジックナンバー #define MAGIC 20094060 #define COMMENT "ぶせな本(簡易版)_反転ロジックを追加" // 外部パラメータ extern double Lots=0.1; extern int Slippage=3; extern int SLpips=2; // 損切り値幅(pips) extern int TPpips=2; // 利食い値幅(pips) extern int ShadowPoint=10; // 反転確認用のヒゲの長さ(point) extern ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; extern ENUM_MA_METHOD ma_method=MODE_EMA; extern int ma_period=20; //状態管理(どのラインでエントリーしたか管理する) //エントリーしたかどうか把握する。エントリーをしたらTrueで、平均移動線と交差したら、Falseにする bool _entry_P10=false; bool _entry_M10=false; //偏差0.1%のラインにタッチしたかどうか把握する。ポジションをもっていない状態で偏差0.1%のラインにタッチしたらTrue。エントリしたら、Falseにする bool _signal_P10=false; bool _signal_M10=false; //シグナル発生後の高値・安値を把握する。エントリーしたら初期化する double _latestHighPrice= 0; double _latestLowPrice = 99999; datetime _latestTime=0; //+------------------------------------------------------------------+ int EntrySignal(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); double envelope_P10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_UPPER,0); double envelope_M10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_LOWER,0); //closeがenvelope_P10より高い bool isOverP10=Close[0]>envelope_P10; bool isUnderM10=Close[0]<envelope_M10; if(!_signal_P10 && pos==0 && !_entry_P10) { _signal_P10=isOverP10; } if(!_signal_M10 && pos==0 && !_entry_M10) { _signal_M10=isUnderM10; } bool SellSignal=false; bool BuySignal=false; if(_signal_P10) { if(High[0]>_latestHighPrice) { _latestHighPrice=High[0]; } if(Close[0]<_latestHighPrice-ShadowPoint*Point && !_entry_P10) { SellSignal=true; } } if(_signal_M10) { if(Low[0]<_latestLowPrice) { _latestLowPrice=Low[0]; } if(Close[0]>_latestLowPrice+ShadowPoint*Point && !_entry_M10) { BuySignal=true; } } int ret=0; // 買いシグナル if(pos<=0 && BuySignal) { _entry_M10=true; _signal_M10=false; _latestHighPrice= 0; _latestLowPrice = 99999; ret=1; } // 売りシグナル if(pos>=0 && SellSignal) { _entry_P10=true; _signal_P10=false; _latestHighPrice=0; _latestLowPrice=99999; ret=-1; } return(ret); } // エグジット関数 void ExitPosition(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); double ma=iMA(NULL,0,ma_period,0,ma_method,applied_price,0); double envelope_P10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_UPPER,0); double envelope_M10=iEnvelopes(NULL,0,ma_period,ma_method,0,applied_price,0.10,MODE_LOWER,0); //平均移動線が交差する bool isOverMa=Close[0]>ma; bool isUnderMa=Close[0]<ma; int ret=0; //if(pos < 0 && 売りポジションの決済シグナル) ret = 1; if(pos<0 && isUnderMa) ret=1; //if(pos > 0 && 買いポジションの決済シグナル) ret = -1; if(pos>0 && isOverMa) ret=-1; // オープンポジションの決済 if(ret!=0) MyOrderClose(Slippage,magic); } // スタート関数 int start() { CheckCrossMa(); // 売買ポジションのエグジット ExitPosition(MAGIC); // エントリーシグナル 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)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CheckCrossMa() { double ma_0=iMA(NULL,0,ma_period,0,ma_method,applied_price,0); //平均移動線が交差する bool isOverMa=Open[0]<ma_0 && High[0]>ma_0; bool isUnderMa=Open[0]>ma_0 && Low[0]<ma_0; if(isOverMa || isUnderMa) { _entry_P10=false; _entry_M10=false; _signal_P10=false; _signal_M10=false; _latestHighPrice= 0; _latestLowPrice = 99999; } } //+------------------------------------------------------------------+ |
(2) 反転を確認するパターンの結果
利確、損切は2Pipsの場合、プロフィットファクタが1.47で、きれいな右肩上がりになりました。
利確10Pips、損切は5Pipsの場合、プロフィットファクタが1.01で、ほとんど、利益を上げていません。
結果考察
(2) 反転を確認するパターンで、利確、損切は2Pipsの場合、きれいな右肩上がりなのが逆に胡散臭いです。
(1) 反転を確認しないパターンで、利確、損切は2Pipsの場合、きれいな右肩下がりになっていることを考慮して考えると、利確、損切の値が小さいと正しく検証ができないのではないかという疑念がわきます。
本当にこの手法が有効であることを確認するなら、実際のトレードかデモトレードの環境で動かすしかなさそうです。
もしも、実際のトレード環境でも、この成績を保てるなら、実践に耐えうるトレードルールだと思われます。
疑問点
総取引回数は5932回でした。
これは、『最強のFX 1分足スキャルピング』の取引頻度は本当に少ないか?の記事で確認した4880回よりも多いです。
ビジュアルモードでエントリーのタイミングを確認しましたが、明らかにおかしい箇所は見当たらなかったです。
※2019/8/7追記
以下のような状況で、トレードルールの通りに動かないことがあります。
(1)1本の足で一気に、平均移動線から偏差0.1%のラインに接触した場合
(2)週明けで窓が開いている場合
(1)の原因は、平均移動線にタッチした際に、エントリーフラグを消すロジックが少し適当なためです。
今のロジックだと、1本の足で平均移動線と偏差0.1%のラインに触れている場合、エントリーしてもすぐにエントリーフラグを消されてしまいます。
改善案
・1分足より大きな時間足を使用する。
(その際は、偏差0.1%ラインでなく、もっと大きな偏差ラインを採用する必要があります)
・上位足の動きをもとにフィルターをかける。
・逆張りでなく、順張りにしてみる
※補足:行き過ぎた値段になった際に、一般的に、逆張りする戦略と順張りをする戦略があります。ボリンジャーバンドで2σラインをタッチした際に、逆張りを狙う戦略と順張りを狙う戦略があることをイメージするとわかりやすいです。
関連記事
~FXを始めてみませんか?~
XMは、口座を開設するだけで、3000円のボーナスが無料でもらえます。
資金はないけど、FXを試しに挑戦してみたい方でも大丈夫です。
(サイト主もXMを使用しています)
コメント