目次
概要
以下の記事で、RSIを使用した5分足の逆張り手法を作成した。
→RSIを使用した逆張り手法に平均足のフィルターを加える
長期なトレンドに逆らうことがないように、短期的な視点(5分足)で逆張りを狙うような手法となっている。
長期なトレンドの判定用のフィルターとして、1時間足と、日足の平均足を採用している。
フィルターが、1時間足と、日足の平均足の両方を採用するのが最適かどうか疑問に思い調査しました。
調査内容
以下のフィルターが有効か確認する。
(1)1時間足の平均足
(2)日足の平均足
(3)1時間足の移動平均線
※以下の検証では21期間の平均移動線の傾きが一定以上プラスであれば上昇トレンド、一定以下でマイナスであれば、下降トレンドと判断しています。
ソースコード
※以下のソースコードは、
『FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ)』(豊嶋久道)
で紹介されているライブラリーを使用しています。
そのため、コピペだと動きません。
それに加えて、平均足のインジケータが別途必要です。
豊嶋さんの本のp123で紹介されている「HeikinAshi」というインジケータをビルドして、「Indicators」フォルダ以下に配置してください。
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 |
// マイライブラリー #include <MyLib.mqh> // マジックナンバー #define MAGIC 20094060 #define COMMENT "平均足フィルター+RSI" // 外部パラメータ extern double Lots=0.1; extern int Slippage=3; extern int SLpips= 20; // 損切り値幅(pips) extern int TPpips= 40; // 利食い値幅(pips) extern int IsUseExit=true; datetime LatestTime; extern ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; extern int RSIPeriod=7; // RSIの期間 extern int HighRSI = 80; extern int LowRSI = 20; extern int HighRSIExit = 70; extern int LowRSIExit = 30; extern int ReverseRSI = 5; extern int MAPeriod = 21; extern ENUM_APPLIED_PRICE ma_applied_price=PRICE_OPEN; extern ENUM_MA_METHOD ma_method=MODE_SMA; extern double MinSlope=10; // 傾き最小値 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int EntrySignal(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); bool isPositiveBar_H1=IsPositiveBar(PERIOD_H1); bool isPositiveBar_D1=IsPositiveBar(PERIOD_D1); double MA_0=iMA(_Symbol,PERIOD_H1,MAPeriod,0,ma_method,ma_applied_price,0); double MA_1=iMA(_Symbol,PERIOD_H1,MAPeriod,0,ma_method,ma_applied_price,1); double MA_slope=(MA_0-MA_1)/Point; bool isMASlopeUp=MA_slope>MinSlope; bool isMASlopeDown=MA_slope<-MinSlope; bool isUpState=isMASlopeUp;//isPositiveBar_H1 && isPositiveBar_D1; bool isDownState=isMASlopeDown;//!isPositiveBar_H1 && !isPositiveBar_D1; double rsi_0=iRSI(NULL,0,RSIPeriod,applied_price,0); double isHighRSI=GetHighRSI()>HighRSI && rsi_0>HighRSIExit; double isReverseHighRSI=rsi_0<GetHighRSI()-ReverseRSI; double isLowRSI=GetLowRSI()<LowRSI && rsi_0<LowRSIExit; double isReverseLowRSI=rsi_0>GetLowRSI()+ReverseRSI; bool buySignal=isUpState && isLowRSI && isReverseLowRSI; bool sellSignal=isDownState && isHighRSI &&isReverseHighRSI; int ret=0; // 買いシグナル if(pos<=0 && buySignal) ret=1; // 売りシグナル if(pos>=0 && sellSignal) ret=-1; return(ret); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ExitPosition(int magic) { // オープンポジションの計算 double pos=MyCurrentOrders(MY_OPENPOS,magic); double rsi_0=iRSI(NULL,0,RSIPeriod,applied_price,0); double isHighRSIExit=rsi_0>HighRSI; double isLowRSIExit=rsi_0<LowRSI; bool buyExitSignal=isHighRSIExit; bool sellExitSignal=isLowRSIExit; int ret=0; //if(pos < 0 && 売りポジションの決済シグナル) ret = 1; if(pos<0 && sellExitSignal) ret=1; //if(pos > 0 && 買いポジションの決済シグナル) ret = -1; if(pos>0 && buyExitSignal) ret=-1; // オープンポジションの決済 if(ret!=0) MyOrderClose(Slippage,magic); } // スタート関数 int start() { /* if(Time[0] != LatestTime) { LatestTime = Time[0]; } else { return(0); } */ if(IsUseExit) { 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)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetHighRSI() { int maxRSI=0; int lastUpdateCount=0; int LimitNotUpdateCount=2; for(int i=0; i<Bars; i++) { double rsi_i=iRSI(NULL,0,RSIPeriod,PRICE_HIGH,i); if(rsi_i>maxRSI) { maxRSI=rsi_i; lastUpdateCount=0; } else { lastUpdateCount++; } if(lastUpdateCount>LimitNotUpdateCount) { break; } } return maxRSI; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetLowRSI() { int minRSI=100; int lastUpdateCount=0; int LimitNotUpdateCount=2; for(int i=0; i<Bars; i++) { double rsi_i=iRSI(NULL,0,RSIPeriod,PRICE_LOW,i); if(rsi_i<minRSI) { minRSI=rsi_i; lastUpdateCount=0; } else { lastUpdateCount++; } if(lastUpdateCount>LimitNotUpdateCount) { break; } } return minRSI; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsPositiveBar(ENUM_TIMEFRAMES timeframe) { double heikinAshi_Open = iCustom(NULL, timeframe, "HeikinAshi", 0, 0); double heikinAshi_Close = iCustom(NULL, timeframe, "HeikinAshi", 1, 0); return heikinAshi_Close>heikinAshi_Open; } //+------------------------------------------------------------------+ |
isUpStateとisDownStateの部分は(1)~(3)によって変えています。
(1)1時間足の平均足
1 2 |
bool isUpState=isPositiveBar_H1; bool isDownState=!isPositiveBar_H1; |
(2)日足の平均足
1 2 |
bool isUpState=isPositiveBar_D1; bool isDownState=!isPositiveBar_D1; |
(3)1時間足の移動平均線
1 2 |
bool isUpState=isMASlopeUp; bool isDownState=isMASlopeDown; |
結果
(1)1時間足の平均足
(2)日足の平均足
(3)1時間足の移動平均線
考察
プロフィットファクターの値は以下のようになった。
・1時間足の平均足→1.1
・日足の平均足→0.99
・1時間足の移動平均線→1.01
※1時間足の平均足と日足の平均足→1.28
フィルターとして最も機能しているのは、1時間足の平均足。
日足の平均足と1時間足の移動平均線は取引回数も多く、フィルターとしてあまり機能していないように見受けられた。
とはいえ、1時間足単独のフィルターより、1時間足の平均足と日足の平均足の両方を同時に採用した場合の方が成績がよい。
そのため、日足の平均足フィルターが無意味というわけではない。
関連記事
~FXを始めてみませんか?~
XMは、口座を開設するだけで、3000円のボーナスが無料でもらえます。
資金はないけど、FXを試しに挑戦してみたい方でも大丈夫です。
(サイト主もXMを使用しています)
コメント