目次
概要
以下の記事で紹介した、ダブルトップ・ダブルボトムを捉えるEAがわりといい感じでした。
→ダブルボトム・ダブルトップ手法のEA(早期エントリーの廃止)
この記事では、最適化を行い損切と利確がどのくらいの値で最適になりそうか調べます。
トレードルール
ダブルトップ・ダブルボトムの形成を確認し、ネックラインを超えた方向にエントリーする
最適化
損切と利確の値幅を動かす。
損切:0~0.8の幅を0.2刻みで動かす。
利確:1.2~2.4の幅を0.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 175 176 177 178 179 180 181 182 183 184 185 186 187 |
// マイライブラリー #include <MyLib.mqh> // マジックナンバー #define MAGIC 20094021 #define COMMENT "ダブルボトム・ダブルトップ" // 外部パラメータ extern double Lots = 0.1; extern int Slippage = 3; extern double SL_Percent = 0.0; // 損切り値幅(pips) extern double TP_Percent = 2.0; // 利食い値幅(pips) //状態管理 enum ZigzagPos { Top = 0, Bottom = 1, Unknown = 2, }; ZigzagPos LatestZigzag = Unknown; double Zigzag_Top_0 = 0; double Zigzag_Top_1 = 0; double Zigzag_Bottom_0 = 0; double Zigzag_Bottom_1 = 0; double ZigzagMaxTop = 0; double ZigzagMinBottom = 0; double Width_M=0; double Width_W=0; datetime LatestTime; input int ZigzagDepth = 12; input int ZigzagDeviation = 5; input int ZigzagBackstep = 3; input int AllowableErrorPoint = 30; // Maximum distance between the twin tops/bottoms //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int EntrySignal(int magic) { // オープンポジションの計算 double pos = MyCurrentOrders(MY_OPENPOS, magic); bool sellSignal=false; bool buySignal=false; //ダブルトップが形成されているか確認する if(Zigzag_Top_0<Zigzag_Top_1+AllowableErrorPoint*Point &&Zigzag_Top_0>Zigzag_Top_1-AllowableErrorPoint*Point &&ZigzagMaxTop!=0 &&LatestZigzag==Top) { /* 以下の2つを同時に満たす場合、取引チャンスを逃す場合があると考え、当初はelse文を通るようにしていた。 ・Zigzagインジケータの最新の点が現在の足である ・W(M)字のネックラインを超えていない しかし、このelse文を追加してしまうと以下の条件を満たす時に余計なエントリーをする場合があり、最終的にいったん撤廃した。 ・ネックラインを超えた後、Zigzagインジケータの最新の点が更新されている ・W(M)字のネックラインを一度は超えたが、再度ネックラインまで下がった場合 */ //if(LatestZigzag==Top) //{ Width_M=ZigzagMaxTop-Zigzag_Bottom_0; //} //else //{ //Width_M=ZigzagMaxTop-Zigzag_Bottom_1; //} double nowPos=100*(ZigzagMaxTop-Close[0])/Width_M; if(nowPos>101&&nowPos<105) { sellSignal=true; } } //ダブルボトムが形成されているか確認する if(Zigzag_Bottom_0<Zigzag_Bottom_1+AllowableErrorPoint*Point &&Zigzag_Bottom_0>Zigzag_Bottom_1-AllowableErrorPoint*Point &&ZigzagMinBottom!=0 &&LatestZigzag==Bottom) { //if(LatestZigzag==Bottom) // { Width_W=Zigzag_Top_0-ZigzagMinBottom; //} //else //{ //Width_W=Zigzag_Top_1-ZigzagMinBottom; //} nowPos=100*(Close[0]-ZigzagMinBottom)/Width_W; if(nowPos>101&&nowPos<105) { buySignal=true; } } int ret = 0; // 買いシグナル if(pos <= 0 && buySignal) ret = 1; // 売りシグナル if(pos >= 0 && sellSignal) ret = -1; return(ret); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void UpdateZigZag() { double zigzagValue[4]; int zigzagValueCount=0; for(int i=1; i<iBars(Symbol(),0); i++) { double Zigzag=iCustom(Symbol(),0,"ZigZag",ZigzagDepth,ZigzagDeviation,ZigzagBackstep,0,i); if(Zigzag!=0) { zigzagValue[zigzagValueCount]=NormalizeDouble(Zigzag,Digits); zigzagValueCount++; } if(zigzagValueCount==4) { if(zigzagValue[0]>zigzagValue[1]) { LatestZigzag = Top; Zigzag_Top_0 = zigzagValue[0]; Zigzag_Bottom_0 = zigzagValue[1]; Zigzag_Top_1 = zigzagValue[2]; Zigzag_Bottom_1 = zigzagValue[3]; } else { LatestZigzag = Bottom; Zigzag_Bottom_0= zigzagValue[0]; Zigzag_Top_0= zigzagValue[1]; Zigzag_Bottom_1= zigzagValue[2]; Zigzag_Top_1= zigzagValue[3]; } ZigzagMinBottom=Zigzag_Bottom_0<Zigzag_Bottom_1? Zigzag_Bottom_0:Zigzag_Bottom_1; ZigzagMaxTop=Zigzag_Top_0>Zigzag_Top_1? Zigzag_Top_0:Zigzag_Top_1; break; } } } // スタート関数 int start() { if(Time[0] != LatestTime) { UpdateZigZag(); LatestTime = Time[0]; } // エントリーシグナル int sig_entry = EntrySignal(MAGIC); // 買い注文 if(sig_entry > 0) { MyOrderClose(Slippage, MAGIC); MyOrderSend(OP_BUY, Lots, Ask, Slippage, ZigzagMinBottom+(SL_Percent*Width_W), ZigzagMinBottom+(TP_Percent*Width_W), COMMENT, MAGIC); } // 売り注文 if(sig_entry < 0) { MyOrderClose(Slippage, MAGIC); MyOrderSend(OP_SELL, Lots, Bid, Slippage, ZigzagMaxTop-(SL_Percent*Width_M), ZigzagMaxTop-(TP_Percent*Width_M), COMMENT, MAGIC); } return(0); } //+------------------------------------------------------------------+ |
結果
考察
2年分のデータで最適化を行っています。
取引回数は約100回なので、取引頻度は1週間に1回程度でそんなに多くないないです。
プロフィットファクトの値が高かった上位3つのデータをみる限り、利確の最適なポイントは、縦幅の2倍かそれ以上になりそうです。
プロフィットファクトをよくするためには、損切幅は0.6と縦幅の半分程度が最適に近いように見えます。
ただし、期待利息をよくすることを考えるなら、損切は、ダブルトップ。ダブルボトムを形成するサポートラインまで下げるのがよさそうに思えます(上から7番目のデータ)。
関連記事
~FXを始めてみませんか?~
XMは、口座を開設するだけで、3000円のボーナスが無料でもらえます。
資金はないけど、FXを試しに挑戦してみたい方でも大丈夫です。
(サイト主もXMを使用しています)