MT4でボリンジャーバンドを利用したEAを作成してみました。
ボリンジャーバンドの幅が狭くなっている期間が続いた後に
大きな値動きがあるという仮定で売買ロジックを作成してみました。
早速MT4(MQL4)のソースです。
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 |
//+------------------------------------------------------------------+ //| BBBO.mq4 | //| Copyright (c) 2017, Ichizo FX | //| http://fx.ichizo.biz | //+------------------------------------------------------------------+ #property copyright "Copyright (c) 2017, Ichizo FX" #property link "http://fx.ichizo.biz" // マジックナンバー extern int Magic = 20170207; // 外部パラメータ extern double Lots = 0.01; extern int Slippage = 3; extern string Comments = "BBBO"; extern double Diff = 0.2; // ボリンジャーバンドが収まる範囲 extern double Term = 20; // 続く期間 extern double Profit = 0.4; // 利確ライン extern double Loss = 0.2; // 損切りライン extern double Limit = 0.05; // 指値を置く幅 extern datetime EffectiveTerm = 10; // 注文の有効期間 // エントリー関数 extern int BBPeriod = 20; // ボリンジャーバンドの期間 extern int BBDev = 2; // 標準偏差の倍率 int Calculated_Slippage = 0; int TicketB = 0; int TicketS = 0; int Adjust_Slippage = 0; datetime Bar_Time = 0; bool Closed = false; datetime Close_TimeB = 0; datetime Close_TimeS = 0; double posB = 0; double posS = 0; bool res; int AdjustSlippage(string Currency, int Slippage_Pips) { int Symbol_Digits = MarketInfo(Currency, MODE_DIGITS); if (Symbol_Digits == 2 | Symbol_Digits == 4) { Calculated_Slippage = Slippage_Pips; } else if (Symbol_Digits == 3 | Symbol_Digits == 5) { Calculated_Slippage = Slippage_Pips * 10; } return (Calculated_Slippage); } int init() { Adjust_Slippage = AdjustSlippage(Symbol(), Slippage); return(0); } // スタート関数 int start() { if (Bars < BBPeriod) { return(0); } if (Bar_Time == Time[0]) { return(0); } else if (Bar_Time != Time[0]) { Bar_Time = Time[0]; } // 買いポジションを持っているかの判定 if (OrderSelect(TicketB, SELECT_BY_TICKET)) { Close_TimeB = OrderCloseTime(); } // 売りポジションを持っているかの判定 if (OrderSelect(TicketS, SELECT_BY_TICKET)) { Close_TimeS = OrderCloseTime(); } // 買いポジションを持っている場合は売り注文を取り消し if (Close_TimeB != 0 && Close_TimeS == 0 && TicketS != 0) { res = OrderDelete(TicketS, Magenta); if (res) { TicketS = 0; } } // 売りポジションを持っている場合は買い注文を取り消し if (Close_TimeS != 0 && Close_TimeB == 0 && TicketB != 0) { res = OrderDelete(TicketB, Aqua); if (res) { TicketB = 0; } } // ボリンジャーバンドの計算 int order_flg = 0; double bbH[20]; double bbL[20]; double Max = 0.0; double Min = 10000.0; for (int i = 0; i < Term; i++) { bbH[i] = iBands(NULL, 0, BBPeriod, BBDev, 0, Close[i], MODE_UPPER, 0); bbL[i] = iBands(NULL, 0, BBPeriod, BBDev, 0, Close[i], MODE_LOWER, 0); if (bbH[i] - bbL[i] < Diff) { order_flg++; } if (Max < High[i]) { Max = High[i]; } if (Min > Low[i]) { Min = Low[i]; } } // 指値を置く if(OrdersTotal() == 0 && order_flg == Term) { double buyPrice = Max + Limit; double sellPrice = Min - Limit; // 最高値を超えたら逆指値買い TicketB = OrderSend(Symbol(), OP_BUYSTOP, Lots, buyPrice, Adjust_Slippage, buyPrice - Loss, buyPrice + Profit, Comments, Magic, EffectiveTerm, Magenta); // 最低値を下回ったら逆指値売り TicketS = OrderSend(Symbol(), OP_SELLSTOP, Lots, sellPrice, Adjust_Slippage, sellPrice + Loss, sellPrice - Profit, Comments, Magic, EffectiveTerm, Aqua); } return(0); } |
通貨はUSDJPY、5本足でのトレードを前提に実装しました。
USDJPYでボリンジャーバンドの±2σのラインが
0.20円以内に収まる期間が20本続く場合に
逆指値の買い注文と売り注文を同時に出します。
買い注文と売り注文を同時に出すのは
どちらに動くかが分からないからです。
20本の期間の最高値と最低値から
0.05円上下に広げた場所に
逆指値の買い・売り注文を入れておきます。
最高値の0.05円上に逆指値の買いを
最低値の0.05円下に逆指値の売りを入れておくということです。
ボリンジャーバンドが絞られた期間の
最高値を超えた場合はさらに値上がりするだろう、
最低値を下回った場合はさらに値下がりするだろうというロジックです。
買い・売りのどちらかの注文が約定したら
もう一方の注文は取り消します。
現在バックテスト中ですので、
結果は追って報告したいと思いますが、
これまでのところどうも逆の結果が出そうです。
11回注文が成立していますが、
勝ったのが1回、負けたのが10回です。
これだけを見ると、買いと売りを逆にした方がよいのでしょうか。
今回のバックテストの結果も踏まえて
また報告したいと思います。
追記
バックテストの結果がでました。
2016/12/01~2016/12/31の期間で、
USD/JPYの5分足でバックテストを行いました。
期間の中ほどで盛り返してきたのですが、
後半にかけて目に見えてパフォーマンスが落ちました。
総利益 79.39
総損失 -103.51
取引総数 83回
勝率 27.71%
という結果でした。