MQL4 エラーコードリファレンス|GetLastError・取引エラー・リトライパターン完全ガイド

MQL4のエラーコードを体系的にまとめました。GetLastError()・ResetLastError()によるエラー検出、取引エラー(ERR_NO_ERROR〜ERR_TRADE_ERROR)、サーバーエラー(ERR_SERVER_BUSY〜ERR_NO_CONNECTION)、ランタイムエラー、カスタムエラーの全コード一覧、コンパイルエラーの対処法、リトライ付きエラーハンドリングパターンまで、MT4 EA開発に必要なエラー処理のすべてをコード付きで解説します。

目次

MQL4とMQL5のエラー処理の違い

機能MQL4MQL5
エラー取得GetLastError()GetLastError()
エラーリセットResetLastError()ResetLastError()
取引エラーERR_〇〇系定数TRADE_RETCODE_〇〇系定数
エラーコード体系0〜数千の連番カテゴリ別(4000番台、10000番台等)
取引結果OrderSendの戻り値(-1=失敗)MqlTradeResult.retcode

MQL4のエラーハンドリングはEAの安定稼働に直結する最重要機能です。エラーを無視するとポジションの二重発注、SL/TP未設定のまま放置、証拠金不足での連続失敗など、深刻な問題が発生します。すべてのOrderSend/OrderClose/OrderModifyの後には必ずエラーチェックを入れましょう。

MQL4のエラーハンドリングはEAの安定稼働に直結する最重要機能です。エラーを無視するとポジションの二重発注、SL/TP未設定のまま放置、証拠金不足での連続失敗など、深刻な問題が発生します。すべてのOrderSend/OrderClose/OrderModifyの後には必ずエラーチェックを入れましょう。

GetLastError / ResetLastError

int GetLastError();
// 最後に発生したエラーコードを返す。呼び出し後もエラーは保持される

void ResetLastError();
// エラーコードを0(ERR_NO_ERROR)にリセットする
void SafeOrderSend()
  {
   ResetLastError();  // エラーをクリア

   int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, 0, 0,
                            "Test", 12345, 0, clrBlue);

   if(ticket < 0)
     {
      int err = GetLastError();
      Print("注文失敗: エラーコード=", err, " (", ErrorDescription(err), ")");
     }
   else
     {
      Print("注文成功: ticket=", ticket);
     }
  }

取引エラーコード

コード定数説明対処法
0ERR_NO_ERRORエラーなし
1ERR_NO_RESULTエラーなしだが結果も不明OrderModifyで値が同じ場合に発生。無視可
2ERR_COMMON_ERROR一般エラーパラメータを確認
3ERR_INVALID_TRADE_PARAMETERS無効な取引パラメータロット/価格/SL/TPを確認
4ERR_SERVER_BUSYサーバービジー数秒待ってリトライ
5ERR_OLD_VERSIONMT4バージョンが古いMT4をアップデート
6ERR_NO_CONNECTIONサーバーに接続できない接続を確認してリトライ
7ERR_NOT_ENOUGH_RIGHTS権限不足口座の権限を確認
8ERR_TOO_FREQUENT_REQUESTSリクエスト過多リクエスト間隔を空ける
9ERR_MALFUNCTIONAL_TRADE取引操作が不正パラメータを確認
64ERR_ACCOUNT_DISABLED口座が無効ブローカーに連絡
65ERR_INVALID_ACCOUNT無効な口座番号口座番号を確認
128ERR_TRADE_TIMEOUT取引タイムアウト数秒待ってリトライ
129ERR_INVALID_PRICE無効な価格RefreshRates()して再取得
130ERR_INVALID_STOPS無効なSL/TPMODE_STOPLEVELを確認
131ERR_INVALID_TRADE_VOLUME無効なロット数MINLOT/MAXLOT/LOTSTEPを確認
132ERR_MARKET_CLOSED市場が閉じている取引時間を確認
133ERR_TRADE_DISABLED取引が無効自動売買を有効にする
134ERR_NOT_ENOUGH_MONEY証拠金不足ロットを減らすか入金
135ERR_PRICE_CHANGED価格が変更されたRefreshRates()してリトライ
136ERR_OFF_QUOTESオフクオート数秒待ってリトライ
137ERR_BROKER_BUSYブローカービジー数秒待ってリトライ
138ERR_REQUOTEリクオートRefreshRates()してリトライ
139ERR_ORDER_LOCKED注文がロックされているしばらく待つ
140ERR_LONG_POSITIONS_ONLY_ALLOWED買いのみ許可口座設定を確認
141ERR_TOO_MANY_REQUESTSリクエスト過多リクエスト間隔を空ける
145ERR_TRADE_MODIFY_DENIED変更拒否(価格が近すぎる)フリーズレベルを確認
146ERR_TRADE_CONTEXT_BUSY取引コンテキストがビジーIsTradeContextBusy()でチェック
147ERR_TRADE_EXPIRATION_DENIED有効期限が拒否されたexpirationを0にする
148ERR_TRADE_TOO_MANY_ORDERS注文数上限既存注文を整理

ランタイムエラーコード

コード定数説明
4000ERR_NO_MQLERRORMQLエラーなし
4001ERR_WRONG_FUNCTION_POINTER不正な関数ポインタ
4002ERR_ARRAY_INDEX_OUT_OF_RANGE配列インデックス範囲外
4003ERR_NO_MEMORY_FOR_CALL_STACKコールスタックメモリ不足
4004ERR_RECURSIVE_STACK_OVERFLOW再帰スタックオーバーフロー
4005ERR_NOT_ENOUGH_STACK_FOR_PARAMスタック不足
4006ERR_NO_MEMORY_FOR_PARAM_STRING文字列パラメータのメモリ不足
4007ERR_NO_MEMORY_FOR_TEMP_STRING一時文字列のメモリ不足
4008ERR_NOT_INITIALIZED_STRING未初期化文字列
4009ERR_NOT_INITIALIZED_ARRAYSTRING未初期化文字列配列
4010ERR_NO_MEMORY_FOR_ARRAYSTRING文字列配列のメモリ不足
4011ERR_TOO_LONG_STRING文字列が長すぎる
4012ERR_REMAINDER_FROM_ZERO_DIVIDEゼロ除算の余り
4013ERR_ZERO_DIVIDEゼロ除算
4014ERR_UNKNOWN_COMMAND不明なコマンド
4015ERR_WRONG_JUMP不正なジャンプ
4016ERR_NOT_INITIALIZED_ARRAY未初期化配列
4017ERR_DLL_CALLS_NOT_ALLOWEDDLL呼び出し不許可
4018ERR_CANNOT_LOAD_LIBRARYライブラリロード失敗
4019ERR_CANNOT_CALL_FUNCTION関数呼び出し失敗
4020ERR_EXTERNAL_CALLS_NOT_ALLOWED外部呼び出し不許可
4050ERR_INVALID_FUNCTION_PARAMSCNT関数パラメータ数が不正
4051ERR_INVALID_FUNCTION_PARAMVALUE関数パラメータ値が不正
4055ERR_CUSTOM_INDICATOR_ERRORカスタムインジケーターエラー
4062ERR_STRING_PARAMETER_EXPECTED文字列パラメータが必要
4063ERR_INTEGER_PARAMETER_EXPECTED整数パラメータが必要
4064ERR_DOUBLE_PARAMETER_EXPECTED浮動小数点パラメータが必要
4066ERR_ARRAY_AS_PARAMETER_EXPECTED配列パラメータが必要
4099ERR_END_OF_FILEファイル終端
4100ERR_SOME_FILE_ERRORファイルエラー
4101ERR_WRONG_FILE_NAMEファイル名が不正
4102ERR_TOO_MANY_OPENED_FILES開いているファイルが多すぎる
4103ERR_CANNOT_OPEN_FILEファイルを開けない
4104ERR_INCOMPATIBLE_FILEACCESSファイルアクセスモードが不適合
4105ERR_NO_ORDER_SELECTED注文が選択されていない
4106ERR_UNKNOWN_SYMBOL不明な通貨ペア
4107ERR_INVALID_PRICE_PARAM価格パラメータが不正
4108ERR_INVALID_TICKETチケット番号が不正
4109ERR_TRADE_NOT_ALLOWED取引不許可
4110ERR_LONGS_NOT_ALLOWED買い注文不許可
4111ERR_SHORTS_NOT_ALLOWED売り注文不許可

ErrorDescription関数

string ErrorDescription(int errorCode)
  {
   switch(errorCode)
     {
      case 0:   return "エラーなし";
      case 1:   return "結果なし(値変更なし)";
      case 2:   return "一般エラー";
      case 3:   return "無効な取引パラメータ";
      case 4:   return "サーバービジー";
      case 6:   return "サーバー接続なし";
      case 8:   return "リクエスト過多";
      case 64:  return "口座無効";
      case 128: return "取引タイムアウト";
      case 129: return "無効な価格";
      case 130: return "無効なSL/TP";
      case 131: return "無効なロット数";
      case 132: return "市場が閉じている";
      case 133: return "取引無効";
      case 134: return "証拠金不足";
      case 135: return "価格変更";
      case 136: return "オフクオート";
      case 137: return "ブローカービジー";
      case 138: return "リクオート";
      case 139: return "注文ロック中";
      case 145: return "変更拒否(フリーズレベル内)";
      case 146: return "取引コンテキストビジー";
      case 148: return "注文数上限";
      case 4013: return "ゼロ除算";
      case 4105: return "注文未選択";
      case 4108: return "無効なチケット";
      case 4109: return "取引不許可";
      default:  return "不明なエラー(" + IntegerToString(errorCode) + ")";
     }
  }

リトライ付きエラーハンドリング

int OrderSendRetry(int cmd, double lots, double price,
                    int slippage, double sl, double tp,
                    string comment, int magic, int maxRetry = 5)
  {
   int ticket = -1;

   for(int retry = 0; retry < maxRetry; retry++)
     {
      ResetLastError();

      // 最新レート取得
      RefreshRates();
      if(cmd == OP_BUY)
         price = Ask;
      else if(cmd == OP_SELL)
         price = Bid;

      ticket = OrderSend(Symbol(), cmd, lots, price, slippage,
                          sl, tp, comment, magic, 0, clrNONE);

      if(ticket >= 0)
         return ticket;  // 成功

      int err = GetLastError();
      Print("注文失敗(リトライ", retry + 1, "/", maxRetry, "): ",
            ErrorDescription(err));

      // リトライ可能なエラーか判定
      switch(err)
        {
         case ERR_SERVER_BUSY:          // 4
         case ERR_NO_CONNECTION:        // 6
         case ERR_TOO_FREQUENT_REQUESTS: // 8
         case ERR_TRADE_TIMEOUT:        // 128
         case ERR_PRICE_CHANGED:        // 135
         case ERR_OFF_QUOTES:           // 136
         case ERR_BROKER_BUSY:          // 137
         case ERR_REQUOTE:              // 138
         case ERR_TRADE_CONTEXT_BUSY:   // 146
            Sleep(1000 * (retry + 1));  // 段階的にウェイト増加
            break;

         default:
            // リトライ不可能なエラー
            Print("リトライ不可能なエラー: ", err);
            return -1;
        }
     }

   Print("最大リトライ回数超過");
   return -1;
  }
最も多い3つのエラーと対処法
  • ERR_INVALID_STOPS (130): SL/TPがStopLevel未満の距離に設定されている → MarketInfo(Symbol(), MODE_STOPLEVEL)を確認し、十分な距離を確保
  • ERR_INVALID_PRICE (129): 古い価格で注文している → RefreshRates()で最新価格を取得してから再送
  • ERR_NOT_ENOUGH_MONEY (134): 証拠金不足 → AccountFreeMarginCheck()で事前確認し、ロットを縮小
最も多い3つのエラーと対処法
  • ERR_INVALID_STOPS (130): SL/TPがStopLevel未満の距離に設定されている → MarketInfo(Symbol(), MODE_STOPLEVEL)を確認し、十分な距離を確保
  • ERR_INVALID_PRICE (129): 古い価格で注文している → RefreshRates()で最新価格を取得してから再送
  • ERR_NOT_ENOUGH_MONEY (134): 証拠金不足 → AccountFreeMarginCheck()で事前確認し、ロットを縮小

IsTradeContextBusy — 取引コンテキスト

bool WaitForTradeContext(int timeoutSeconds = 30)
  {
   datetime startTime = TimeCurrent();

   while(IsTradeContextBusy())
     {
      if(TimeCurrent() - startTime > timeoutSeconds)
        {
         Print("取引コンテキスト待機タイムアウト");
         return false;
        }
      Sleep(100);
     }

   return true;
  }

// 安全な発注パターン
int SafeOrderSend(int cmd, double lots, double sl, double tp, int magic)
  {
   // 取引許可チェック
   if(!IsTradeAllowed())
     {
      Print("自動売買が許可されていません");
      return -1;
     }

   // 取引コンテキスト待機
   if(!WaitForTradeContext())
      return -1;

   // 証拠金チェック
   double price = (cmd == OP_BUY) ? Ask : Bid;
   if(AccountFreeMarginCheck(Symbol(), cmd, lots) < 0)
     {
      Print("証拠金不足");
      return -1;
     }

   return OrderSendRetry(cmd, lots, price, 3, sl, tp, "", magic);
  }

ランタイムエラー(4000番台)はプログラム実行中に発生するエラーです。最も多いのはERR_ZERO_DIVIDE (4013)ERR_ARRAY_INDEX_OUT_OF_RANGE (4002)です。ゼロ除算は必ず分母のチェックを入れ、配列アクセスは必ず範囲チェックをしましょう。

ランタイムエラー(4000番台)はプログラム実行中に発生するエラーです。最も多いのはERR_ZERO_DIVIDE (4013)ERR_ARRAY_INDEX_OUT_OF_RANGE (4002)です。ゼロ除算は必ず分母のチェックを入れ、配列アクセスは必ず範囲チェックをしましょう。

よくあるコンパイルエラーと対処法

エラーメッセージ原因対処法
‘変数名’ – undeclared identifier未宣言の変数を使用変数を宣言するかスペルを確認
‘関数名’ – function not defined関数が定義されていない関数定義を追加するか#includeを確認
‘)’ – semicolon expectedセミコロンの欠落前の行の末尾にセミコロンを追加
‘return’ – ‘int’ type expected戻り値の型が不一致関数の戻り値の型を確認
implicit conversion暗黙の型変換明示的にキャスト
possible loss of data精度低下の警告(int)や(double)でキャスト
array out of range配列範囲外アクセスインデックスの範囲チェックを追加

エラー関連関数一覧(MQL5対応表)

MQL4関数/定数MQL5対応説明
GetLastError()GetLastError()最後のエラーコード
ResetLastError()ResetLastError()エラーコードリセット
IsTradeContextBusy()なし(不要)取引コンテキストビジー判定
IsTradeAllowed()TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)取引許可判定
IsConnected()TerminalInfoInteger(TERMINAL_CONNECTED)接続状態判定
ERR_INVALID_PRICE (129)TRADE_RETCODE_INVALID (10013)無効な価格
ERR_INVALID_STOPS (130)TRADE_RETCODE_INVALID_STOPS (10016)無効なSL/TP
ERR_NOT_ENOUGH_MONEY (134)TRADE_RETCODE_NO_MONEY (10019)証拠金不足
ERR_REQUOTE (138)TRADE_RETCODE_REQUOTE (10004)リクオート

まとめ

MQL4のエラーハンドリングは、EAの安定運用に不可欠です。重要なポイントは以下の通りです。

  • 取引関数の後は必ずエラーチェックする — OrderSend/OrderClose/OrderModifyの戻り値を確認
  • リトライ可能なエラーとそうでないエラーを区別する — サーバービジーやリクオートはリトライ、証拠金不足は即中止
  • RefreshRates()で最新レートを取得してからリトライ — 古い価格で再送するとまたエラーになる
  • IsTradeContextBusy()で取引コンテキストを確認 — 他のEAと同時に取引操作しない

次のステップとして、MQLリファレンス総合ガイドで取引関数とエラーハンドリングを組み合わせた堅牢なEA開発を学びましょう。

シストレ.COMで実績のあるEAが使い放題!/
無料会員登録はこちら
FX自動売買でEAを探すなら
シストレ.COM
実績あるEAが無料
厳格な審査を乗り越えた実績のあるEAが無料で使えます!
自由な口座選び
有料版を購入し柔軟な口座選びが可能!
フォワードテスト公開
全EAのフォワードテスト結果を公開中!
FX初心者も安心
初心者の方も安心して取引を始められます。
多様なEA選択肢
様々な種別のEAをご用意!自分の手法にあった取引が可能です。
信頼のFX会社と提携
人気のFX会社と提携中!様々なFX会社から選べます。
1分で登録完了!EA探すならシストレ.COM!/
無料会員登録はこちら
【FX自動売買】システムトレード完全ガイド|Forex Guide

この記事が気に入ったら
フォローしてね!

お役立ち情報をシェアする
  • URLをコピーしました!
目次