Contents
トレンドが発生するタイミングを察知してシグナルを発生させてみる
MT4でのFXシステムトレードプログラミングです。
今回は、5分足で3本分が連続して同じ方向に値動きをした場合に
買い・売りシグナルを出すというロジックを試してみました。
つまり、始値と終値の差を取り、円高方向なら
続けて3本円高方向に動いているか、
もしくは円安方向に3本連続して動いているかを
シグナルにするというものです。
さらに始値と終値の差が大きくなっている場合のみに
限ってシグナルを出すようにしてみました。
以下、プログラムソースです。
//+------------------------------------------------------------------+ //| Ichizo1.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 = 20170124; // 外部パラメータ extern double Lots = 0.01; extern int Slippage = 3; extern string Comments = "Ichizo1"; extern double Diff = 0.3; extern double Diff_S = 0.3; extern double LossDiff = 0.02; // エントリー関数 extern int DiffPeriod = 3; // 差分を取る期間 int Calculated_Slippage = 0; int Ticket = 0; int Adjust_Slippage = 0; datetime Bar_Time = 0; bool Closed = false; datetime Close_Time = 0; double pos = 0; int Order_Type = 0; int LossCut = Diff_S; 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 isOrder() { int diff_no = 0; int diff_f[3]; for (int i = 0; i < DiffPeriod; i++) { diff_f[i] = Close[i] - Open[i]; if (diff_f[i] > 0) { if (i > 0) { if (diff_f[i] > diff_f[i-1]) { diff_no++; } } else { diff_no++; } } else if (diff_f[i] < 0) { if (i > 0) { if (diff_f[i] < diff_f[i - 1]) { diff_no--; } } else { diff_no--; } } } int order_type = 0; if (diff_no == DiffPeriod) { // 買いシグナル order_type = 1; } else if (diff_no == -1 * DiffPeriod) { // 売りシグナル order_type = -1; } return order_type; } // スタート関数 int start() { if (Bars < DiffPeriod) { return(0); } if (Bar_Time == Time[0]) { return(0); } else if (Bar_Time != Time[0]) { Bar_Time = Time[0]; } // ポジションを持っているかの判定 if (OrderSelect(Ticket, SELECT_BY_TICKET)) { Close_Time = OrderCloseTime(); // 未決済の場合 if (Close_Time == 0) { // オープンポジションの計算 pos = OrderOpenPrice(); Order_Type = OrderType(); } } // ロングポジションのクローズ if (Ticket > 0 && Order_Type == OP_BUY && (Bid - Diff > pos || Bid + LossCut < pos)) { Closed = OrderClose(Ticket, Lots, Bid, Adjust_Slippage, Magenta); if (Closed == true) { Ticket = 0; } // ショートポジションのクローズ } else if (Ticket > 0 && Order_Type == OP_SELL && (Ask + Diff > pos || Ask - LossCut < pos)) { Closed = OrderClose(Ticket, Lots, Ask, Adjust_Slippage, Aqua); if (Closed == true) { Ticket = 0; } } int order_type = isOrder(); // 買いシグナル if(OrdersTotal() == 0 && order_type == 1) { Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Adjust_Slippage, 0, 0, Comments, Magic, 0, Magenta); LossCut = Diff_S; } // 売りシグナル else if(OrdersTotal() == 0 && order_type == -1) { Ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Adjust_Slippage, 0, 0, Comments, Magic, 0, Aqua); LossCut = Diff_S; } else { LossCut = LossCut - LossDiff; } return(0); }
上記のソースでバックテストを行いました。
期間は2016/12/01~2017/01/25で
5分足でのシミュレーションです。
結果は
売買なし・・・
1カ月の間に条件を満たすことがなかったんですね。
現在値から3本前の5分足から見て
始値と終値の差が全て同じ方向で
かつその差が段々大きくなるという条件が厳しかったようです。
特に差が大きくなっていくという条件が
厳しかったのかなと思います。
次はこの条件を外してみて
3本連続して同じ方向に値動きするか
という条件でシグナルを出すようにして
バックテストを行ってみます。