MQL5 OrderSend結果ログを実コードで解説|MqlTradeRequest・MqlTradeResult・TRADE_RETCODE確認

EAファンクラブ

MQL5 EAで注文を出す時、よく使われるのがOrderSendです。

しかし、EAの不具合調査では「OrderSendを呼んだかどうか」だけでは不十分です。重要なのは、どのようなMqlTradeRequestを作り、サーバーからどのようなMqlTradeResultが返り、TRADE_RETCODEとして何が記録されたかです。

EAがエントリーしない、注文が通らない、ロットが拒否される、ストップレベルで失敗する、AutoTradingをONにしているのに注文できない。こうした問題は、OrderSendの戻り値だけでなく、request、result、retcode、GetLastErrorを分けて確認すると切り分けやすくなります。

この記事では、MQL5のOrderSend結果ログを、学習用に一般化したコード断片で解説します。完成EAソース全文、外部シート制御、認証、endpoint、token、URL、実運用set値、中核エントリー条件は公開しません。

扱うのは、MqlTradeRequestの構造、MqlTradeResultの確認、TRADE_RETCODEの分類、発注前チェック、注文失敗ログ、retry対象と即停止対象の切り分けです。

この記事で扱う範囲

項目この記事で扱う内容扱わない内容
目的OrderSendの結果をログで追えるようにする設計利益を狙う売買ロジック、具体的なエントリー条件
主な構造MqlTradeRequest、MqlTradeResult、retcode、GetLastError完成EAソース全文、実運用コード全文
設計対象発注前チェック、注文結果ログ、失敗理由分類外部制御、認証、実運用set値
コード例学習用に簡略化した短いコード断片中核エントリー条件、独自優位性のある判定式
確認対象ORDER_SEND_OK、ORDER_SEND_FAIL、retcode、deal、order、comment推奨ロット、推奨銘柄、売買判断

OrderSendとは

OrderSendは、MQL5で注文リクエストをサーバーへ送るための関数です。

ただし、OrderSendは単に「BUYする」「SELLする」という関数ではありません。MqlTradeRequestに注文内容を詰め、MqlTradeResultで結果を受け取り、その結果を確認する構造です。

基本的な流れは次の通りです。

  1. 発注前にEA内部の状態を確認する
  2. MqlTradeRequestを初期化する
  3. action、symbol、type、volume、price、deviation、magicなどを設定する
  4. OrderSendを呼ぶ
  5. MqlTradeResultを確認する
  6. retcode、deal、order、commentをログへ残す
  7. 成功、失敗、再試行候補、即停止候補を分類する

この流れを分けずにOnTick内へ直接書くと、注文できなかった原因を追いにくくなります。

MqlTradeRequestで確認する項目

MqlTradeRequestは、注文内容を入れる構造体です。OrderSendで失敗した時は、requestに何を入れていたかを確認する必要があります。

項目意味確認ポイント
action注文種別TRADE_ACTION_DEAL、TRADE_ACTION_SLTPなどの意図が正しいか
symbol対象銘柄チャート銘柄と一致しているか、suffix違いがないか
typeBUY / SELLなど方向が意図と一致しているか
volumeロット最小ロット、ロット刻み、最大ロットに合っているか
price注文価格BUYならAsk、SELLならBidを使っているか
sl / tp損切り・利確価格stop level、freeze level、価格方向が正しいか
deviation許容スリッページ値が小さすぎないか、銘柄仕様と合っているか
magicEA識別番号ロジックやEAごとに識別できているか
comment注文コメント長すぎないか、機密情報を含んでいないか

requestには、認証情報、token、endpoint、URL、個人情報などを入れてはいけません。注文コメントにも機密情報を入れないようにします。

MqlTradeResultで確認する項目

MqlTradeResultは、OrderSend後に返ってくる結果情報です。

項目意味確認ポイント
retcodeサーバー側の結果コード注文成功、拒否、価格変更、無効なリクエストなどを確認する
deal約定番号実際に約定した場合の確認に使う
order注文番号注文登録や約定前状態の確認に使う
volume結果側の数量部分約定や約定数量の確認に使う
price結果側の価格約定価格や応答価格の確認に使う
commentサーバーコメント失敗理由の補助情報として確認する

OrderSendの戻り値がtrueでも、retcodeの確認は必要です。逆に、戻り値だけを見て成功・失敗を判断すると、ログ上の追跡が不十分になります。

TRADE_RETCODEを分類する理由

TRADE_RETCODEは、注文結果を確認するうえで重要です。

たとえば、注文失敗といっても、原因はさまざまです。

  • 一時的な価格変動
  • 無効なロット
  • 無効な価格
  • ストップレベル違反
  • 取引停止
  • 市場クローズ
  • AutoTradingや権限の問題
  • 証拠金不足
  • サーバー側拒否

これらをすべて「OrderSend失敗」とだけ出すと、原因調査ができません。retcodeを分類し、retry対象なのか、設定修正が必要なのか、取引環境確認が必要なのかを分けます。

OrderSend前に確認すること

OrderSendを呼ぶ前には、少なくとも次の項目を確認します。

確認項目理由
runtime readyEAが初期化済みか確認する
AutoTrading自動売買が許可されているか確認する
symbol対象銘柄が取引可能か確認する
spread取引前条件を満たしているか確認する
volume最小ロット、ロット刻み、最大ロットに合っているか確認する
priceBUY / SELL方向に合った価格か確認する
SL / TP価格方向とstop levelを確認する
duplicate gate同一バー・同一tick・同一方向の重複発注を避ける
riskロジック別・EA全体の上限を超えていないか確認する

この記事では、具体的なエントリー条件やリスク計算式は扱いません。重要なのは、OrderSend前の確認とOrderSend結果の確認を分けることです。

実コード断片1:retcodeを文字列化する

以下は、OrderSend結果のretcodeをログで読みやすくするための学習用コード例です。完成EAのソース全文ではありません。

// 学習用に一般化したretcode文字列化例です。
// 実運用EAの完成ソースではありません。

string TradeRetcodeToText(uint retcode)
{
   switch(retcode)
   {
      case TRADE_RETCODE_DONE:
         return "DONE";

      case TRADE_RETCODE_PLACED:
         return "PLACED";

      case TRADE_RETCODE_REQUOTE:
         return "REQUOTE";

      case TRADE_RETCODE_REJECT:
         return "REJECT";

      case TRADE_RETCODE_CANCEL:
         return "CANCEL";

      case TRADE_RETCODE_INVALID:
         return "INVALID";

      case TRADE_RETCODE_INVALID_VOLUME:
         return "INVALID_VOLUME";

      case TRADE_RETCODE_INVALID_PRICE:
         return "INVALID_PRICE";

      case TRADE_RETCODE_INVALID_STOPS:
         return "INVALID_STOPS";

      case TRADE_RETCODE_NO_MONEY:
         return "NO_MONEY";

      case TRADE_RETCODE_MARKET_CLOSED:
         return "MARKET_CLOSED";

      case TRADE_RETCODE_TRADE_DISABLED:
         return "TRADE_DISABLED";

      default:
         return "OTHER_RETCODE";
   }
}

この例では、代表的なretcodeだけを文字列化しています。実運用EAでは、必要なretcodeを増やし、ログやサポート用の分類へ接続します。

このコードの役割

処理役割
TradeRetcodeToTextretcodeを読みやすい文字列へ変換する
DONE / PLACED成功または注文登録として扱いやすい結果
REQUOTE / INVALID_PRICE価格変動や価格指定の問題を示す結果
INVALID_VOLUMEロット設定の問題を示す結果
INVALID_STOPSSL / TPやstop levelの問題を示す結果
NO_MONEY証拠金不足などの資金条件を示す結果

実コード断片2:注文requestを監査する

以下は、OrderSend前にrequestの主要項目をログへ出す学習用コード例です。発注条件や中核Entry判定は含めていません。

// 学習用に一般化したrequest監査例です。
// 実運用EAの完成ソースではありません。

void PrintTradeRequestAudit(const MqlTradeRequest &request,
                            string routeName)
{
   Print("DIAG/ORDER_REQUEST: event=AUDIT",
         " route=", routeName,
         " symbol=", request.symbol,
         " action=", (int)request.action,
         " type=", (int)request.type,
         " volume=", DoubleToString(request.volume, 2),
         " price=", DoubleToString(request.price, _Digits),
         " sl=", DoubleToString(request.sl, _Digits),
         " tp=", DoubleToString(request.tp, _Digits),
         " deviation=", request.deviation,
         " magic=", request.magic);
}

request監査ログでは、token、endpoint、URL、認証情報、口座番号などは出しません。注文に必要な技術項目だけを残します。

このコードの役割

処理役割
PrintTradeRequestAuditOrderSend前のrequest内容を確認する
routeNameどの処理経路から来た注文かを示す
symbol / type対象銘柄とBUY / SELL方向を確認する
volume注文数量を確認する
sl / tp価格方向やstop level確認の手がかりにする
magicEAやロジック単位の識別に使う

OrderSend前にrequest監査を残すことで、失敗時に「どの内容で注文を送ろうとしたか」を確認できます。

実コード断片3:OrderSend結果をログに残す

以下は、OrderSendを呼び出し、MqlTradeResultをログへ残す学習用コード例です。中核エントリー条件は含めていません。

// 学習用に一般化したOrderSend結果ログ例です。
// 実運用EAの完成ソースではありません。

bool SendOrderWithResultLog(MqlTradeRequest &request,
                            string routeName)
{
   MqlTradeResult result;
   ZeroMemory(result);

   PrintTradeRequestAudit(request, routeName);

   ResetLastError();

   bool ok = OrderSend(request, result);
   int lastError = GetLastError();

   string retcodeText = TradeRetcodeToText(result.retcode);

   Print("DIAG/ORDER_RESULT: event=SEND_DONE",
         " route=", routeName,
         " order_send_ok=", ok,
         " retcode=", result.retcode,
         " retcode_text=", retcodeText,
         " deal=", result.deal,
         " order=", result.order,
         " volume=", DoubleToString(result.volume, 2),
         " price=", DoubleToString(result.price, _Digits),
         " last_error=", lastError,
         " comment=", result.comment);

   if(!ok)
   {
      Print("DIAG/ORDER_RESULT: event=SEND_FAIL",
            " reason=ORDERSEND_FALSE",
            " retcode_text=", retcodeText,
            " last_error=", lastError);
      return false;
   }

   if(result.retcode != TRADE_RETCODE_DONE &&
      result.retcode != TRADE_RETCODE_PLACED)
   {
      Print("DIAG/ORDER_RESULT: event=RETCODE_NOT_SUCCESS",
            " retcode_text=", retcodeText,
            " retcode=", result.retcode);
      return false;
   }

   Print("DIAG/ORDER_RESULT: event=SUCCESS",
         " retcode_text=", retcodeText,
         " deal=", result.deal,
         " order=", result.order);

   return true;
}

この例では、OrderSendの戻り値、retcode、deal、order、last_error、commentを分けてログに出しています。

このコードの役割

処理役割
ZeroMemory(result)結果構造体を初期化する
PrintTradeRequestAuditOrderSend前のrequest内容を記録する
OrderSend注文リクエストを送信する
GetLastErrorMQL5側の直近エラーを取得する
retcode確認サーバー側の注文結果を確認する
SEND_FAILOrderSend自体がfalseだった場合を示す
RETCODE_NOT_SUCCESSOrderSend後のretcodeが成功系ではないことを示す
SUCCESS注文成功または注文登録を確認できる状態

OrderSendの戻り値だけでなく、result.retcodeを必ず確認することが重要です。

実コード断片4:retcodeを分類する

以下は、retcodeを大まかに分類し、retry対象か、設定修正対象か、環境確認対象かを分ける学習用コード例です。

// 学習用に一般化したretcode分類例です。
// 実運用EAの完成ソースではありません。

string ClassifyRetcode(uint retcode)
{
   switch(retcode)
   {
      case TRADE_RETCODE_DONE:
      case TRADE_RETCODE_PLACED:
         return "SUCCESS";

      case TRADE_RETCODE_REQUOTE:
      case TRADE_RETCODE_INVALID_PRICE:
         return "PRICE_RECHECK";

      case TRADE_RETCODE_INVALID_VOLUME:
         return "VOLUME_SETTING_CHECK";

      case TRADE_RETCODE_INVALID_STOPS:
         return "STOPS_SETTING_CHECK";

      case TRADE_RETCODE_NO_MONEY:
         return "ACCOUNT_MARGIN_CHECK";

      case TRADE_RETCODE_MARKET_CLOSED:
      case TRADE_RETCODE_TRADE_DISABLED:
         return "TRADE_ENV_CHECK";

      case TRADE_RETCODE_REJECT:
      case TRADE_RETCODE_INVALID:
         return "REQUEST_REVIEW";

      default:
         return "UNKNOWN_REVIEW";
   }
}

bool IsRetryCandidate(uint retcode)
{
   string cls = ClassifyRetcode(retcode);

   return (cls == "PRICE_RECHECK");
}

retcode分類は、EAが次にどう扱うかを決めるための補助です。retryするかどうかは、注文種別、環境、リスク、重複制御と合わせて慎重に判断します。

このコードの役割

分類意味
SUCCESS成功または注文登録として扱える候補
PRICE_RECHECK価格再取得や再評価が必要な候補
VOLUME_SETTING_CHECKロット設定の見直しが必要な候補
STOPS_SETTING_CHECKSL / TPやstop levelの見直しが必要な候補
ACCOUNT_MARGIN_CHECK証拠金や口座条件の確認が必要な候補
TRADE_ENV_CHECK市場時間や取引許可の確認が必要な候補
REQUEST_REVIEWrequest構造の見直しが必要な候補

分類名を固定すると、ログ検索やサポート時の切り分けがしやすくなります。

実コード断片5:発注前precheckを分ける

以下は、OrderSendを呼ぶ前に最低限の確認を行い、失敗理由をログに残す学習用コード例です。実際の売買条件や中核Entry判定は含めていません。

// 学習用に一般化した発注前precheck例です。
// 実運用EAの完成ソースではありません。

bool ValidateRequestBeforeSend(const MqlTradeRequest &request,
                               string routeName)
{
   if(request.symbol == "")
   {
      Print("DIAG/ORDER_PRECHECK: event=BLOCK",
            " route=", routeName,
            " reason=EMPTY_SYMBOL");
      return false;
   }

   if(request.volume <= 0.0)
   {
      Print("DIAG/ORDER_PRECHECK: event=BLOCK",
            " route=", routeName,
            " reason=INVALID_VOLUME_ZERO");
      return false;
   }

   if(request.magic <= 0)
   {
      Print("DIAG/ORDER_PRECHECK: event=BLOCK",
            " route=", routeName,
            " reason=INVALID_MAGIC");
      return false;
   }

   if(request.type != ORDER_TYPE_BUY &&
      request.type != ORDER_TYPE_SELL)
   {
      Print("DIAG/ORDER_PRECHECK: event=BLOCK",
            " route=", routeName,
            " reason=UNSUPPORTED_ORDER_TYPE");
      return false;
   }

   Print("DIAG/ORDER_PRECHECK: event=OK",
         " route=", routeName);

   return true;
}

この例は、最低限の構造チェックです。実際のEAでは、spread、保有上限、duplicate gate、risk、stop level、取引時間なども別helperで確認します。

このコードの役割

処理役割
EMPTY_SYMBOL対象銘柄が空の注文を止める
INVALID_VOLUME_ZERO数量が0以下の注文を止める
INVALID_MAGIC識別不能な注文を止める
UNSUPPORTED_ORDER_TYPE想定外の注文種別を止める
ORDER_PRECHECK OKOrderSend前の構造確認を通過したことを示す

発注前precheckとOrderSend結果ログを分けることで、「送る前に止めた」のか、「送ったが拒否された」のかを切り分けられます。

成功ログだけでは不十分な理由

注文処理では、成功ログだけでなく、失敗ログが特に重要です。

成功時だけ「OrderSend OK」と出しているEAでは、注文できなかった時に次のことが分かりません。

  • requestが作られたのか
  • precheckで止まったのか
  • OrderSendを呼んだのか
  • OrderSendがfalseだったのか
  • retcodeが成功系ではなかったのか
  • GetLastErrorは何だったのか
  • retry対象なのか、設定修正対象なのか

注文ログでは、成功よりも失敗時の情報を整理しておく方が、不具合調査では役立ちます。

retry対象と即停止対象を分ける

注文失敗時に、何でも自動再試行する設計は危険です。

たとえば、価格変動による一時的な失敗と、ロット不正や証拠金不足は扱いが違います。

分類扱いの例
PRICE_RECHECK価格を再取得し、条件を再評価してから検討
VOLUME_SETTING_CHECKロット計算や銘柄仕様を確認する。自動retryしない
STOPS_SETTING_CHECKSL / TP、stop level、freeze levelを確認する
ACCOUNT_MARGIN_CHECK証拠金や口座条件の確認が必要。自動retryしない
TRADE_ENV_CHECK市場時間、取引許可、銘柄状態を確認する
REQUEST_REVIEWrequest構造やEA設定の確認が必要

retryは便利ですが、無制限に行うと重複発注やログ過多につながります。retryする場合でも、回数、間隔、同一バー制御、同一tick制御を分けて設計する必要があります。

ログで確認するポイント

OrderSend周りの問題を確認する時は、Expertsログで次の情報を見ます。

ログ見るポイント
ORDER_PRECHECK OK / BLOCKOrderSend前に止まったのか、通過したのか
ORDER_REQUEST AUDITどのrequestで注文を送ろうとしたか
ORDER_RESULT SEND_DONEOrderSendの戻り値、retcode、deal、orderが確認できるか
SEND_FAILOrderSend自体がfalseだったか
RETCODE_NOT_SUCCESSretcodeが成功系ではなかったか
SUCCESS注文成功または注文登録を確認できるか
retcode_text数値だけでなく分類名で追えるか
last_errorGetLastErrorの値が残っているか

ログ確認の基本は、次のページも参考にしてください。

MT5のログ確認方法|Experts・Journalの見方

開発依頼前に整理する情報

EAの注文処理を開発・改修する場合、次の情報を先に整理しておくと原因調査や仕様確認がしやすくなります。

  • 注文種別
  • 成行注文か、指値・逆指値を使うか
  • BUY / SELLの扱い
  • ロット計算の責務
  • SL / TPを同時に入れるか、後からmodifyするか
  • マジックナンバーの割り当て
  • OrderSend前のprecheck項目
  • retcodeログの粒度
  • retry対象とretryしない対象
  • 注文失敗時に通知するか
  • 注文失敗ログをサポート時に提出するか

仕様書、setファイル、ログ、スクリーンショットを整理する場合は、次のページも確認してください。

MT5開発依頼前に用意する資料まとめ|仕様書・setファイル・ログ・スクリーンショット

公開しない情報

この記事では、MQL5のOrderSend結果ログを学ぶために、公開可能な範囲だけを一般化して解説しています。以下は公開しません。

  • 完成EAソース全文
  • 外部シート参照による動作制御ロジック
  • 外部シートCSV取得、解析、時間枠、方向制御ロジック
  • 認証、口座許可判定、購入者管理ロジック
  • endpoint、token、URL、Google Sheet ID、Webhook URL、GAS URL
  • APIキー、認証トークン、口座番号、サーバー名
  • 実運用set値
  • 中核エントリー条件
  • 中核Trail / Nanpin判定
  • 独自優位性のある売買判定式
  • 利益保証、勝率保証、推奨ロット、推奨銘柄、推奨エントリー

本記事は、投資判断や売買指示ではなく、MQL5開発におけるOrderSend、MqlTradeRequest、MqlTradeResult、TRADE_RETCODE確認を理解するための技術解説です。

FAQ

OrderSendの戻り値がtrueなら注文成功ですか?

戻り値だけで判断せず、MqlTradeResult.retcodeを確認してください。OrderSend後は、retcode、deal、order、commentなどを確認して、成功系かどうかを判断します。

MqlTradeRequestには何を入れますか?

action、symbol、type、volume、price、sl、tp、deviation、magic、commentなどを設定します。認証情報、token、URL、口座番号などの機密情報は入れません。

注文失敗時は何を確認すればよいですか?

ORDER_PRECHECKで止まったのか、OrderSendを呼んだ後に失敗したのかを分けて確認します。そのうえで、retcode、GetLastError、request内容、server commentを確認します。

TRADE_RETCODEはなぜ重要ですか?

注文失敗の理由を分類するためです。価格問題、ロット問題、SL / TP問題、証拠金不足、取引停止、市場クローズなどを分けて確認できます。

注文失敗時は自動retryすべきですか?

すべてをretryするのは危険です。価格変動のような一時的な失敗と、ロット不正や証拠金不足のような設定・環境問題は分けて扱います。

GetLastErrorとretcodeはどちらを見ればよいですか?

両方確認します。retcodeは取引サーバー側の結果確認に重要で、GetLastErrorはMQL5側の直近エラー確認に使います。どちらか一方だけでは不足する場合があります。

このコードは完成EAとして使えますか?

いいえ。この記事のコード例は、OrderSend結果ログの考え方を理解するために簡略化した学習用コードです。完成EAとしてそのまま使うことは想定していません。

実際のEAソース全文は公開されていますか?

公開していません。完成EAソース全文、外部シート制御、認証、endpoint、token、URL、実運用set値、中核エントリー条件は公開対象外です。

関連ページ

ページ確認できること
MQL5ログファースト設計を実コードで解説OrderSend失敗時のevent、reason、detail管理
MQL5 EAの基本イベント構造を実コードで解説OnTickからexecutionへ進む前の責務分離
MQL5 Multi-Logic EA設計を実コードで解説ロジック別のマジックナンバーと注文識別
MT5のログ確認方法|Experts・Journalの見方ExpertsログとJournalログの基本確認
MT5開発依頼前に用意する資料まとめ|仕様書・setファイル・ログ・スクリーンショット開発相談前に整理する資料
不具合報告・調査依頼について不具合相談前に送る情報
免責事項投資判断、損益、利用上の注意に関する確認
投資助言を行わない方針売買助言ではなく技術支援として扱う方針

まとめ

MQL5でOrderSendを扱う時は、注文を送る処理だけでなく、注文前のprecheck、request監査、result確認、retcode分類、失敗ログまで含めて設計することが重要です。

特に、次の4点を分けておくと、注文失敗の原因を切り分けやすくなります。

  • MqlTradeRequest:どの内容で注文を送ろうとしたか
  • MqlTradeResult:サーバーからどの結果が返ったか
  • TRADE_RETCODE:成功・拒否・価格問題・設定問題をどう分類するか
  • GetLastError:MQL5側の直近エラーをどう確認するか

OrderSendの戻り値だけを見て成功・失敗を判断すると、原因調査が不十分になります。precheckで止まったのか、OrderSend自体がfalseだったのか、retcodeが成功系ではなかったのかを、Expertsログで分けて確認できる設計が必要です。

完成EAの中核エントリー条件を公開しなくても、OrderSend、MqlTradeRequest、MqlTradeResult、TRADE_RETCODEの確認構造を理解しておくことで、注文エラー、不発注、誤決済、サポート時のログ確認がしやすくなります。

ABOUT ME
記事URLをコピーしました