FX自動売買(EA)の作り方MQL4

【コピペ可】MT4のEAで取引時間制限、時間指定の強制決済機能を追加する方法

※アフィリエイト広告を利用しています

広告

EAを使用していると、稼働時間を制限しないフル稼働ではなく、時間帯で新規エントリーを制限したいと考えることもあると思います。

例えば、

ヨーロッパ・アメリカ時間に比べて東京時間はボラティリティが低くリスクが少ないため、その時間帯だけナンピンマーチンEAを稼働させる。

などです。

この記事の内容をコピペしていけば、今お使いの自作EAに時間制限機能を追加することが可能です。

初心者向けになるべくコードの意味まで丁寧に解説するように心がけていますので、初心者の方も是非EA作成にチャレンジしてみてください。
    広告

    EAのベースモデル

    ここでは、以下の記事で作成したEAを「ベースモデル」と呼んで、機能追加を行なっていきます。

    最も単純なナンピンマーチンEAをゼロから作成する記事になっていますので、是非ご一緒にご確認ください。

    Inputの設定

    ベースモデルでは、以下のインプット項目を設定していました。

    input double first_lot = 0.01;//初期ロット
    input double nanpin_range = 200;//ナンピン幅
    input double profit_target = 143;//利益目標
    input int magic_number = 10001; //マジックナンバー
    static int ticket_number;//チケットナンバー
    double slippage = 10;//スリッページ

    ここにさらに、時間制限用のインプット項目を追加しておきます。

    input bool time_limit = false;//エントリー時間制限(true:あり、false:なし)
    input string start_time = "02:00";//エントリー開始時間
    input string end_time = "10:00";//エントリー終了時間
    input bool forced_close = false;//強制クローズ(true:あり、false:なし)

    エントリー時間制限(time_limit)

    エントリー時間制限を機能として追加しますが、機能オフにすれば、これまでと変わらないロジックも実現出来るように、最初にエントリー時間制限機能をオンにするかオフにするかというインプット項目を作ります。

    bool型というのは、trueかfalseの2つの値のどちらかをとるデータ型です。

    trueの場合は時間制限あり、falseの場合は時間制限なし、という設定のつもりで次に進みます。

    エントリー開始時間(start_time)

    エントリー開始時間の設定です。ここではstring型ですので、”02:00″というような文字列で入力することを想定しています。また、ここでの時間は、XMのキプロス時間で入力します。

    XMTradingのゴールド(XAU/USD)の取引時間は、
    キプロス時間では、1:05~23:55(金曜日のみ23:50閉場)です。
    日本時間(夏時間)では、7:05~翌日5:55(金曜日のみ翌日5:50)です。
    日本時間(冬時間)では、8:05~翌日6:55(金曜日のみ翌日6:50)です。

    エントリー終了時間(end_time)

    エントリー終了時間の設定です。ここも、XMのキプロス時間で入力します。

    エントリー開始時間からエントリー終了時間までの間は、新規エントリー注文を行いますが、それ以外の時間は新規エントリー注文を行わない、という想定で進めていきます。

    強制クローズ(forced_close)

    エントリ終了時間のタイミングで、強制クローズを行うかどうかを設定します。

    trueの場合は強制クローズあり、falseの場合は強制クローズなし、という設定です。

    強制クローズありの場合、エントリー終了時間の時点で、持っている全てのポジションをクローズするロジックにする想定です。

    オリジナル関数の追加

    エントリー時間制限機能追加のためにオリジナル関数を2つ追加しておきます。

    entryTime関数

    エントリー時間帯かどうかをチェックする関数として、entryTime関数を定義します。

    //+----エントリー時間帯チェック-----------------------------------------------+
    
    bool entryTime(string stime,string etime){
       string startDate=TimeToStr(TimeCurrent(),TIME_DATE); //現在の年月日
       datetime startTime=StrToTime(startDate+" "+stime); //年月日+開始時間
       datetime endTime=StrToTime(startDate+" "+etime); //年月日+終了時間
       if(startTime<endTime){
          if(startTime<=TimeCurrent() && TimeCurrent()<endTime)return(true);
          else return(false); //現在時刻がエントリー時間内の場合、true
       }else{
          if(endTime<=TimeCurrent() && TimeCurrent()<startTime)return(false);
          else return(true); //現在時刻がエントリー時間外の場合、false
       }
       return(false);
    }
    
    //+-----------------------------------------------------------------------+

    この関数の概要は以下の通りです。

    • TimeCurrent関数で現在時刻を取得、TimeToStr関数で年月日部分を取り出します。
    • 次に、StrToTime関数で、年月日+開始時間と年月日+終了時間をdatetime型に変換します。
    • そして、現在時刻、エントリー開始時刻、エントリー終了時刻の3つのdatetime型を比較して、エントリー時間内かどうかを判定して、trueまたはfalseを返します。
    ここで取得可能な現在時刻というのは、取引サーバーの時刻です。したがって、XMTradingであれば、XMが採用しているキプロス時間が基準になります。その他のサーバーであれば、それに合わせた対応が必要かもしれませんので、各サーバーの時間を確認するようにしてください。

    allClose関数

    ベースモデルでは、buyClose関数をbuyポジションをクローズする関数、sellClose関数をsellポジションをクローズする関数としてそれぞれ定義しましたが、buyとsellどちらも全てのポジションをクローズする関数として、allClose関数を定義します。

    //+----全てのポジションを決済する関数----------------------------------------------------+
    
    void allClose(color clr)
    {
       int i;
       for(i=OrdersTotal()-1;i>=0;i--)
       {
          if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
             continue;
          if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=magic_number)
             continue;
          if(OrderType()==OP_BUY)
             OrderClose(OrderTicket(),OrderLots(),Bid,NormalizeDouble(slippage,0),clr);
          if(OrderType()==OP_SELL)
             OrderClose(OrderTicket(),OrderLots(),Ask,NormalizeDouble(slippage,0),clr);
       }
    }
    
    //+---------------------------------------------------------------------------------+

    関数自体はとてもシンプルで、buyClose関数にsellポジションを決済する部分を追加しただけです。

    ループ処理

    事前に必要は追加処理が終わり、ここからループ処理の中の機能追加に入ります。

    void OnTick()

    void OnTick()
     {

    これ以降は、void OnTick()の中に追加記載していく内容になります。

    変数の定義

    ベースモデルでは、以下の変数を定義していました。

    int cnt;
    int current_buy_position;//最新のbuyポジション
    int current_sell_position;//最新のsellポジション
    int buy_position;//buyポジション数
    int sell_position;//sellポジション数
    double buy_profit;//buyポジションの含み損益
    double sell_profit;//sellポジションの含み損益

    ここに、以下の2つの定義を追加します。

    bool entry_flag;//エントリーフラグ
    bool close_flag;//クローズフラグ

    エントリーフラグ(entry_flag)

    エントリーフラグは、新規エントリーを行うかどうかに使用します。

    trueであれば、新規エントリーを行い、falseであれば、新規エントリーは行いません。

    クローズフラグ(close_flag)

    クローズフラグは、強制クローズを行うかどうかに使用します。

    trueであれば、強制クローズを行い、falseであれば、強制クローズは行いません。

    エントリー時間帯の確認

    次に、エントリー時間帯の確認という処理を追加します。場所は、ポジションを確認する処理の手前くらいでOKです。

    //+----エントリー時間帯の確認---------------------------------------------+
    
       entry_flag=false; //エントリーフラグの初期化
       close_flag=false; //クローズフラグの初期化
    
       if(!time_limit){ //エントリー時間制限なし(false)の場合
          entry_flag=true;
       }else
       if(entryTime(start_time,end_time)){ //エントリー時間内(true)の場合
          entry_flag=true;
       }else
       if(forced_close){ //強制クローズあり(true)の場合
          allClose(GreenYellow);
       }
    
    //+------------------------------------------------------------------+

    まず、エントリー時間制限をtrueにしていない場合、エントリーフラグはtrueになります。つまり、時間制限なしでエントリーする設定です。

    次に、エントリー時間制限をtrueにしていて、エントリー時間内の場合、エントリーフラグはtrueになります。制限時間内であればエントリーする設定です。

    最後に、エントリー時間制限がtrueで、エントリー時間外の場合は、エントリーフラグは初期化したfalseのままです。また、そこで強制クローズ(forced_close)をtrueにしていた場合、allClose関数を実行します。

    新規エントリー注文

    続いて、新規エントリー注文のエントリー条件にエントリーフラグの条件を追加して、「ポジションを持っていなかったら、かつ、エントリーフラグがtrueだったら」という条件に変更します。

    条件部分だけ抜粋しますと、以下の通りポジションのみのシンプルな条件だったところを、

    if(buy_position==0)//buyポジションを持っていない場合
    
    if(sell_position==0)//sellポジションを持っていない場合

    以下の通り、エントリーフラグを追加します。

    if(buy_position==0&&entry_flag)//buyポジションを持っていない、かつエントリーフラグ=trueの場合
    
    if(sell_position==0&&entry_flag)//sellポジションを持っていない、かつエントリーフラグ=trueの場合

    entry_flagはbool型ですので、単純に&&entry_flagとするだけで、「entry_flag=trueの場合」という条件を意味します。

    追加エントリー(ナンピン)注文

    ナンピン注文部分は、特に追記等行いません。これは、今回追加している機能は、エントリー時間に制限を設けているのみで、ナンピンについてはエントリー時間外であっても継続するロジックを想定しているからです。

    エントリー時間外でもポジションを持っている限りナンピンについては続けて行い、一度でもポジションをクローズしたら、その後はエントリー開始時間まで新規エントリーは行いません。

    ポジションクローズ注文

    ポジションクローズ注文部分についても、特に変更は必要ありません。

    ポジションクローズに関しては、強制クローズのロジックを追加していますが、これは「エントリー時間帯の確認」の部分で設定済みだからです。

    まとめ

    以上で、ナンピンマーチンEAのベースモデルにエントリー時間制限の機能追加は完了です。

    EAの動かし方、パラメーター設定等

    EAを実際に動かす方法、パラメーター設定等は以下の記事を参考にしてください。

    その他のEA作成解説記事

    ココモ法の導入、マーチン倍率の変更など

    利確パターンの変更機能を追加

    Pythonで作るFX自動売買ツール(bot)

    PythonでFX自動売買ツール(bot)を作成する方法もご紹介しています。

    タイトルとURLをコピーしました