ブログタイトルを「FX自動売買システム開発部」から「autoFX」に変更しました!

信頼できる仕切り注文関数

本記事で公開しているライブラリーは公開当時のままで、古くなっております。最新版のライブラリーはメルマガ登録いただくことでダウンロードできます。

仕切り注文が失敗したら泣くに泣けないじゃない?

仕切り注文を出す、MQL4の標準関数にOrderClose()があります。

注文が必ず通るのであれば、OrderClose()を使えば良いわけですが、実際はそうでもありません。

…この流れデジャヴですね。OrderSend()と一緒です。

というわけで、OrderClose()の注文が失敗した時を考慮した仕切り注文関数を紹介します。

//+------------------------------------------------------------------+
//|【関数】信頼できる仕切り注文                                      |
//|                                                                  |
//|【引数】 IN OUT  引数名             説明                          |
//|        --------------------------------------------------------- |
//|         ○      aTicket            チケット番号                  |
//|         ○      aLots              ロット数                      |
//|         ○      aPrice             仕切り価格                    |
//|         ○      aSlippage          スリッページ(ポイント)      |
//|         △      aArrow_color       チャート上の矢印の色          |
//|                                                                  |
//|【戻値】true :正常終了                                           |
//|        false:異常終了                                           |
//|                                                                  |
//|【備考】△:初期値あり                                            |
//+------------------------------------------------------------------+
bool orderCloseReliable(int aTicket, double aLots, double aPrice, int aSlippage, color aArrow_color = CLR_NONE)
{
  bool result = false;

  int startTime = GetTickCount();

  Print("Attempted orderCloseReliable(#" + aTicket + ", " + aLots + "lots, " + aPrice + ", Slippage:" + aSlippage + ", ArrowColor:" + aArrow_color + ")");

  bool selected = OrderSelect(aTicket, SELECT_BY_TICKET, MODE_TRADES);

  string symbol = OrderSymbol();
  int    type   = OrderType();

  double digits = MarketInfo(symbol, MODE_DIGITS);

  while(true){
    if(IsStopped()){
      Print("Trading is stopped!");
      return(-1);
    }

    if(GetTickCount() - startTime > MAX_RETRY_TIME * MILLISEC_2_SEC){
      Print("Retry attempts maxed at " + MAX_RETRY_TIME + "sec");
      return(-1);
    }

    // MarketInfo関数でレートを取得しており、定義済変数であるAskとBidは未使用のため、不要のはずだけど、念のため
    RefreshRates();

    if(type == OP_BUY){
      aPrice = MarketInfo(symbol, MODE_BID);
    }else if(type == OP_SELL){
      aPrice = MarketInfo(symbol, MODE_ASK);
    }

    aPrice = NormalizeDouble(aPrice, digits);

    if(IsTradeContextBusy()){
      Print("Must wait for trade context");
    }else{
      result = OrderClose(aTicket, aLots, aPrice, aSlippage, aArrow_color);

      if(result){
        Print("Successful close of Ticket #" + aTicket);
        return(result);
      }

      int err = GetLastError();

      // 一時的エラーの場合はリトライするが、恒常的エラーの場合は処理中断(リトライしてもエラーになるため)
      if(err == ERR_NO_ERROR || 
         err == ERR_COMMON_ERROR ||
         err == ERR_SERVER_BUSY ||
         err == ERR_NO_CONNECTION ||
         err == ERR_TOO_FREQUENT_REQUESTS ||
         err == ERR_TRADE_TIMEOUT ||
         err == ERR_INVALID_PRICE ||
         err == ERR_TRADE_DISABLED ||
         err == ERR_PRICE_CHANGED ||
         err == ERR_OFF_QUOTES ||
         err == ERR_BROKER_BUSY ||
         err == ERR_REQUOTE ||
         err == ERR_TOO_MANY_REQUESTS ||
         err == ERR_TRADE_CONTEXT_BUSY){
        Print("Temporary Error: " + err + " " + ErrorDescription(err) + ". waiting");
      }else{
        Print("Permanent Error: " + err + " " + ErrorDescription(err) + ". giving up");
        return(result);
      }

      // 最適化とバックテスト時はリトライは不要
      if(IsOptimization() || IsTesting()){
        return(result);
      }
    }

    Sleep(SLEEP_TIME * MILLISEC_2_SEC);
  }

  return(result);
}

関数のベースはorderSendReliable()です。注意事項としては、ロングの仕掛けにはBid、ショートの仕掛けにはAskの価格を使うことです。

一時的エラーの種類がorderSendReliable()よりも若干増えていますが、これは7bit氏の「common_function.mqh」及びMatthew Kennel氏らの「LibOrderReliable.mq4」を足して2で割ったような形にしたためです。公式サイトのエラーコードの説明文を読んでも、内容が貧弱過ぎてよく分からないのです。例えば、ERR_COMMON_ERRORの説明は「Common error」。説明になってないですから。こんなわけなので、一時的エラーの選定は正直手探り状態です。

サンプルEA

関数だけではイメージが沸きづらいと思いますので、サンプルEAを載せておきます。

「信頼できる仕切り注文関数」のSample.mq4
サイズ: 4.0KB
バージョン: 1.0
公開:2019年10月17日

MQL4プログラミングの最新記事8件

>完全放ったらかしEA 「AutoEndlessCatchRange」

完全放ったらかしEA 「AutoEndlessCatchRange」

「本業が忙しい!」「でも資産運用したい!」そんなあなたに最適なEAです。兼業トレーダーの方はチャートを毎日みて分析してトレードする時間はなかなか確保できないものです。トレードは本EAに任せて、本業やプライベートの時間をもっと増やしませんか?元々は自分自身のために開発したEAですので、手抜き無しのガチものです。

CTR IMG