MQL5 OrderSend結果ログを実コードで解説|MqlTradeRequest・MqlTradeResult・TRADE_RETCODE確認
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で結果を受け取り、その結果を確認する構造です。
基本的な流れは次の通りです。
- 発注前にEA内部の状態を確認する
- MqlTradeRequestを初期化する
- action、symbol、type、volume、price、deviation、magicなどを設定する
- OrderSendを呼ぶ
- MqlTradeResultを確認する
- retcode、deal、order、commentをログへ残す
- 成功、失敗、再試行候補、即停止候補を分類する
この流れを分けずにOnTick内へ直接書くと、注文できなかった原因を追いにくくなります。
MqlTradeRequestで確認する項目
MqlTradeRequestは、注文内容を入れる構造体です。OrderSendで失敗した時は、requestに何を入れていたかを確認する必要があります。
| 項目 | 意味 | 確認ポイント |
|---|---|---|
| action | 注文種別 | TRADE_ACTION_DEAL、TRADE_ACTION_SLTPなどの意図が正しいか |
| symbol | 対象銘柄 | チャート銘柄と一致しているか、suffix違いがないか |
| type | BUY / SELLなど | 方向が意図と一致しているか |
| volume | ロット | 最小ロット、ロット刻み、最大ロットに合っているか |
| price | 注文価格 | BUYならAsk、SELLならBidを使っているか |
| sl / tp | 損切り・利確価格 | stop level、freeze level、価格方向が正しいか |
| deviation | 許容スリッページ | 値が小さすぎないか、銘柄仕様と合っているか |
| magic | EA識別番号 | ロジックや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 ready | EAが初期化済みか確認する |
| AutoTrading | 自動売買が許可されているか確認する |
| symbol | 対象銘柄が取引可能か確認する |
| spread | 取引前条件を満たしているか確認する |
| volume | 最小ロット、ロット刻み、最大ロットに合っているか確認する |
| price | BUY / 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を増やし、ログやサポート用の分類へ接続します。
このコードの役割
| 処理 | 役割 |
|---|---|
| TradeRetcodeToText | retcodeを読みやすい文字列へ変換する |
| DONE / PLACED | 成功または注文登録として扱いやすい結果 |
| REQUOTE / INVALID_PRICE | 価格変動や価格指定の問題を示す結果 |
| INVALID_VOLUME | ロット設定の問題を示す結果 |
| INVALID_STOPS | SL / 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、認証情報、口座番号などは出しません。注文に必要な技術項目だけを残します。
このコードの役割
| 処理 | 役割 |
|---|---|
| PrintTradeRequestAudit | OrderSend前のrequest内容を確認する |
| routeName | どの処理経路から来た注文かを示す |
| symbol / type | 対象銘柄とBUY / SELL方向を確認する |
| volume | 注文数量を確認する |
| sl / tp | 価格方向やstop level確認の手がかりにする |
| magic | EAやロジック単位の識別に使う |
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) | 結果構造体を初期化する |
| PrintTradeRequestAudit | OrderSend前のrequest内容を記録する |
| OrderSend | 注文リクエストを送信する |
| GetLastError | MQL5側の直近エラーを取得する |
| retcode確認 | サーバー側の注文結果を確認する |
| SEND_FAIL | OrderSend自体がfalseだった場合を示す |
| RETCODE_NOT_SUCCESS | OrderSend後の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_CHECK | SL / TPやstop levelの見直しが必要な候補 |
| ACCOUNT_MARGIN_CHECK | 証拠金や口座条件の確認が必要な候補 |
| TRADE_ENV_CHECK | 市場時間や取引許可の確認が必要な候補 |
| REQUEST_REVIEW | request構造の見直しが必要な候補 |
分類名を固定すると、ログ検索やサポート時の切り分けがしやすくなります。
実コード断片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 OK | OrderSend前の構造確認を通過したことを示す |
発注前precheckとOrderSend結果ログを分けることで、「送る前に止めた」のか、「送ったが拒否された」のかを切り分けられます。
成功ログだけでは不十分な理由
注文処理では、成功ログだけでなく、失敗ログが特に重要です。
成功時だけ「OrderSend OK」と出しているEAでは、注文できなかった時に次のことが分かりません。
- requestが作られたのか
- precheckで止まったのか
- OrderSendを呼んだのか
- OrderSendがfalseだったのか
- retcodeが成功系ではなかったのか
- GetLastErrorは何だったのか
- retry対象なのか、設定修正対象なのか
注文ログでは、成功よりも失敗時の情報を整理しておく方が、不具合調査では役立ちます。
retry対象と即停止対象を分ける
注文失敗時に、何でも自動再試行する設計は危険です。
たとえば、価格変動による一時的な失敗と、ロット不正や証拠金不足は扱いが違います。
| 分類 | 扱いの例 |
|---|---|
| PRICE_RECHECK | 価格を再取得し、条件を再評価してから検討 |
| VOLUME_SETTING_CHECK | ロット計算や銘柄仕様を確認する。自動retryしない |
| STOPS_SETTING_CHECK | SL / TP、stop level、freeze levelを確認する |
| ACCOUNT_MARGIN_CHECK | 証拠金や口座条件の確認が必要。自動retryしない |
| TRADE_ENV_CHECK | 市場時間、取引許可、銘柄状態を確認する |
| REQUEST_REVIEW | request構造やEA設定の確認が必要 |
retryは便利ですが、無制限に行うと重複発注やログ過多につながります。retryする場合でも、回数、間隔、同一バー制御、同一tick制御を分けて設計する必要があります。
ログで確認するポイント
OrderSend周りの問題を確認する時は、Expertsログで次の情報を見ます。
| ログ | 見るポイント |
|---|---|
| ORDER_PRECHECK OK / BLOCK | OrderSend前に止まったのか、通過したのか |
| ORDER_REQUEST AUDIT | どのrequestで注文を送ろうとしたか |
| ORDER_RESULT SEND_DONE | OrderSendの戻り値、retcode、deal、orderが確認できるか |
| SEND_FAIL | OrderSend自体がfalseだったか |
| RETCODE_NOT_SUCCESS | retcodeが成功系ではなかったか |
| SUCCESS | 注文成功または注文登録を確認できるか |
| retcode_text | 数値だけでなく分類名で追えるか |
| last_error | GetLastErrorの値が残っているか |
ログ確認の基本は、次のページも参考にしてください。
開発依頼前に整理する情報
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の確認構造を理解しておくことで、注文エラー、不発注、誤決済、サポート時のログ確認がしやすくなります。

