開発実務ノート

MQL5ログファースト設計を実コードで解説|event・side・reason・detailで追跡するEA開発

MQL5のログファースト設計を実コードで解説し、event・side・reason・detailでEAの動作を追跡する方法を表したアイキャッチ画像
EAファンクラブ

MQL5でEAを開発する時、不具合の原因を後から追えるかどうかは、ロジックそのものと同じくらい重要です。

EAがエントリーしない、注文に失敗する、チャート表示が残る、時間足変更後に挙動が変わる、長時間稼働でログが増えすぎる。こうした問題は、発生時点の状態をExpertsログで追えないと、後から再現条件を整理することが難しくなります。

この記事では、MQL5 EA開発におけるログファースト設計を、学習用に一般化したコード断片を使って解説します。売買判断や収益性を示す記事ではなく、EAを安全に検証・保守するためのログ設計を整理する記事です。

完成EAソース全文、外部シート参照の動作制御ロジック、認証、endpoint、token、URL、実運用set値、中核エントリー条件は公開しません。この記事で扱うのは、ログ設計の考え方と、公開可能な範囲に一般化した短いコード例だけです。

この記事で扱う範囲

項目この記事で扱う内容扱わない内容
目的ExpertsログでEAの状態、見送り理由、失敗理由を追える設計利益を狙う売買ロジック、エントリー条件の公開
コード学習用に簡略化したログ関数、ログ抑制、出力例完成EAソース全文、実運用コード全文
ログevent、side、reason、detailに分けた構造化ログ認証情報、token、URL、口座情報を含むログ
確認対象INIT、ENTRY_SKIP、ORDER_FAIL、OBJECT_AUDITなどの考え方外部制御値の詳細、実運用set値、中核判定条件
読者MQL5開発者、EA利用者、開発依頼前にログを整理したい人売買判断や推奨設定を知りたい人

ログファースト開発とは

ログファースト開発とは、EAが正常に動いた時だけでなく、動かなかった理由、見送った理由、失敗した理由、保護処理が継続している理由を、最初からログで追えるように設計する考え方です。

MQL5では、Print()を使えばExpertsログへ文字を出せます。しかし、単にPrintを増やすだけでは、実運用や長時間検証で必要な情報を追えません。

重要なのは、ログを次のように分解して出すことです。

要素意味例
layerどの機能層のログかINIT、ORDER、ENTRY、OBJECT_AUDIT、RISK
sideBUY側かSELL側か、方向なしのログかBUY、SELL、NONE
event何が起きたかSTART、SKIP、SEND_FAIL、STARTUP_FOUND
reasonなぜ起きたかSPREAD_LIMIT、NO_POSITION、INVALID_HANDLE
detail確認に必要な補足情報symbol、timeframe、retcode、object_kindなど

このように分けると、ログを見た時に「どの処理で」「どちら側で」「何が起きて」「なぜそうなったか」を追いやすくなります。

Printをただ増やすだけでは不十分な理由

EA開発では、不具合が出るたびにPrintを追加したくなります。しかし、Printを場当たり的に追加すると、次の問題が起きます。

よくある状態問題点改善方針
同じログが毎tick出るExpertsログが埋まり、重要な失敗ログが流れる状態変化時だけ出す、またはthrottleする
日本語文章だけのログ検索、比較、機械的な抽出がしにくいevent、reason、detailを固定キーにする
成功ログだけ多い見送り理由や失敗理由が追えないSKIP、BLOCK、FAILを理由付きで出す
売買判定とログ出力が混ざるログ修正が売買挙動へ影響する可能性がある判定helperとログhelperを分離する
機密情報がそのまま出る問い合わせ時にURL、token、口座情報が漏れるログ出力前にマスク・除外する

ログファースト設計では、Printを増やすこと自体が目的ではありません。検証、保守、問い合わせ対応で使える形に整理して出すことが目的です。

event / side / reason / detail の考え方

構造化ログでは、ログの文章を長くするよりも、固定された項目で揃えることを優先します。

たとえば、次のようなログ形式にすると、後から検索しやすくなります。

DIAG/ORDER: side=BUY event=SEND_FAIL reason=RETCODE_REJECT detail=symbol=XXX retcode=10000
DIAG/ENTRY: side=SELL event=SKIP reason=SPREAD_LIMIT detail=spread=high
DIAG/OBJECT_AUDIT: side=NONE event=STARTUP_FOUND reason=VISUAL_ONLY detail=kind=AVG_LINE

この形式では、ログの前半だけで大まかな種類を把握できます。

  • DIAG/ORDER:注文・発注結果に関するログ
  • side=BUY:BUY側の処理
  • event=SEND_FAIL:注文送信に失敗
  • reason=RETCODE_REJECT:失敗理由の分類
  • detail=…:調査時に必要な補足

このようにログを分けると、同じEAでも、初期化、エントリー見送り、注文失敗、決済失敗、Object監査、リスク制御などを別々に確認できます。

ログを出す主な場面

EAでログを出す場面は、成功時だけではありません。むしろ、見送りや失敗の理由を残すことが重要です。

ログ種別目的確認すること
INITEA起動時の準備状態を確認するバージョン、銘柄、時間足、主要設定、初期化結果
ENTRY_SKIP新規エントリーを見送った理由を確認するspread、時間、リスク、同一バー制御、権限制御など
ORDER_FAIL注文送信や変更に失敗した理由を確認するretcode、GetLastError、lot、symbol、action
OBJECT_AUDITチャート上の残存Objectや表示状態を確認する表示専用、実ロジック参照除外、削除対象、無視対象
RUNTIME稼働中の状態変化を確認する許可状態、停止状態、ガード状態、保護処理の継続
DEINITEA終了時の安全性を確認する異常終了の有無、終了時に売買処理が走っていないか

INITログで確認すること

INITログは、EAをチャートへセットした直後の確認に使います。ここで重要なのは、すべての内部情報を出すことではなく、起動状態を判断できる最小限の情報を出すことです。

INITログに入れてよい情報の例です。

  • EA名、バージョン
  • symbol、timeframe
  • 主要機能のON/OFF状態
  • ログモード
  • Object監査の実行有無
  • 初期化成功または安全停止の状態

一方で、次の情報はINITログに出してはいけません。

  • 認証token
  • endpoint
  • Webhook URL
  • Google Sheet ID
  • 口座番号
  • 購入者管理情報
  • 実運用set値の詳細

ENTRY_SKIPログで確認すること

EAがエントリーしない時、最初に必要なのは「なぜ見送ったか」です。

よくある失敗は、エントリー条件が成立していないのか、成立したが執行前のガードで止まったのかをログで分けていないことです。

状態ログで分けるべき理由
シグナル不成立ENTRY対象ではない。signal側の確認が必要
スプレッド超過signalは候補だが、broker条件で見送り
同一バー重複防止再送防止による見送り
保有上限リスク・ポジション管理による見送り
外部許可NG新規Entryだけ停止。既存ポジション管理とは分けて確認

公開記事では、外部制御の詳細や中核エントリー条件は扱いません。ただし、ログ設計上は「見送り理由をreasonとして残す」ことが重要です。

ORDER_FAILログで確認すること

注文失敗ログではGetLastError()だけでなく、送信したrequestとMqlTradeResult.retcodeを同じ処理単位で追えるようにします。GetLastError()は読み出しても自動でリセットされないため、必要に応じて対象処理の直前でResetLastError()を使い、古いエラー値との混同を避けます。

注文失敗時は、MQL5側の戻り値だけでなく、注文種別、方向、symbol、lot、retcode、GetLastErrorを分けて残します。

注文に失敗した場合、単に「注文失敗」と出すだけでは、次の調査ができません。

  • lotが不正だったのか
  • AutoTradingがOFFだったのか
  • 価格が変わったのか
  • サーバー側で拒否されたのか
  • 一時的な失敗でretry対象なのか
  • そもそも注文対象のsymbolが違うのか

注文結果ログでは、少なくとも「何を送ろうとして」「何が返ってきたか」を追えるようにします。

OBJECT_AUDITログで確認すること

チャート上に描画するEAでは、Objectの残存や再セット時の誤参照が問題になることがあります。

たとえば、平均価格ライン、TPライン、Trailライン、仮想ライン、ラベル、パネル部品などが残っている場合、それを実ロジックへ使うのか、表示専用として無視するのかを分ける必要があります。

Object監査ログでは、次のような観点を残します。

監査項目確認内容
STARTUP_FOUND起動時に既存Objectを検出した
VISUAL_ONLY表示専用として扱い、実ロジックへ使わない
IGNORE_FOR_LOGIC残存Objectを判定ロジックから除外する
CLEANUP_PLAN削除候補だが、条件を確認してから処理する
CLEANUP_SUMMARY監査や整理の結果を要約する

EA削除時にすべてのObjectを無理に消すより、再セット時に監査して、実ロジックへ誤採用しない構造にする方が安全な場合があります。

状態変化時だけログを出す理由

リアルタイムで動くEAでは、OnTickが何度も呼ばれます。条件不成立や待機状態を毎tickログに出すと、Expertsログがすぐに埋まります。

ログ過多になると、重要な失敗ログを見落としやすくなります。そのため、ログは次のように分けると実用的です。

ログ種別出力方針
注文成功・注文失敗重要なので原則出す
決済成功・決済失敗重要なので原則出す
設定不正状態変化時、または一定間隔で出す
待機中毎tickではなく抑制する
同じ見送り理由一定秒数以内は抑制する
起動時チェックリスト起動時に1回だけ出す

INIT・SELFCHECK・SNAPを分ける

ログでは、起動情報、前提条件確認、現在状態の記録を同じeventへまとめないことが重要です。

INITにはEA名、バージョン、銘柄、時間足、主要設定を記録します。SELFCHECKには自動売買許可、銘柄仕様、ロット条件、WebRequestなどの前提条件を記録します。SNAPにはポジション数、状態フラグ、counterなど、その時点のruntime状態を記録します。

この3種類を分けることで、初期化失敗、前提条件による停止、稼働中の状態変化を原因を確認しやすくなります。

実コード断片1:構造化ログhelper

以下は、実際のEAで使う考え方を学習用に簡略化したコード例です。完成EAのソース全文ではなく、構造を理解するための抜粋です。

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

bool CanWriteDiagLog()
{
   return true; // 実際はinputやruntime設定でON/OFFを分けます。
}

string SafeText(string value, string fallback)
{
   if(value == "")
      return fallback;

   // 公開用の考え方:機密情報に該当するdetailは出さない。
   if(StringFind(value, "token") >= 0)
      return "masked";

   return value;
}

void WriteDiagLog(string layer, string side, string eventName, string reason, string detail)
{
   if(!CanWriteDiagLog())
      return;

   string safeLayer  = SafeText(layer, "GENERAL");
   string safeSide   = SafeText(side, "NONE");
   string safeEvent  = SafeText(eventName, "UNKNOWN");
   string safeReason = SafeText(reason, "NO_REASON");
   string safeDetail = SafeText(detail, "no detail");

   Print("DIAG/", safeLayer,
         ": side=", safeSide,
         " event=", safeEvent,
         " reason=", safeReason,
         " detail=", safeDetail);
}

実際のEAでは、認証、外部制御、口座条件、エラー処理、ログ出力などを分けて設計します。この記事では、公開できる範囲の構造だけを取り上げています。

このコードの役割

行・処理役割
CanWriteDiagLogログ出力をON/OFFする入口です。開発版、検証版、配布版でログ粒度を変える時に使います。
SafeText空文字や機密情報をそのまま出さないための補助です。
WriteDiagLoglayer、side、event、reason、detailを固定形式で出力します。
PrintExpertsログへ1行で出します。ログ形式を揃えることで、後から検索しやすくなります。

ここで重要なのは、ログ出力を各処理に直接書き散らさず、helperへ集約することです。helperへ集約すると、ログ形式、マスク処理、出力ON/OFF、ログ抑制を後から調整しやすくなります。

実コード断片2:同じログを出しすぎない抑制例

以下は、同一キーのログを一定秒数だけ抑制する学習用コード例です。完成EAのソース全文ではなく、ログ過多を防ぐ考え方を示すための簡略例です。

// 学習用の簡易throttle例です。
// 実際のEAでは、ログ種類ごとに抑制秒数を分けます。

string g_lastLogKey = "";
datetime g_lastLogTime = 0;

bool ShouldSkipSameLog(string key, int throttleSeconds)
{
   datetime nowTime = TimeCurrent();

   if(key == g_lastLogKey)
   {
      if((nowTime - g_lastLogTime) < throttleSeconds)
         return true;
   }

   g_lastLogKey = key;
   g_lastLogTime = nowTime;
   return false;
}

void WriteDiagLogThrottled(string layer, string side, string eventName, string reason, string detail)
{
   string key = layer + "|" + side + "|" + eventName + "|" + reason;

   if(ShouldSkipSameLog(key, 300))
      return;

   WriteDiagLog(layer, side, eventName, reason, detail);
}

実際のEAでは、注文失敗や決済失敗のように必ず残したいログと、待機状態のように抑制したいログを分けます。すべてのログを同じ抑制にすると、重要な失敗履歴が欠落する可能性があるためです。

ログ抑制で注意すること

  • 注文失敗、決済失敗、初期化失敗は抑制しすぎない
  • 待機中、同じ見送り理由、同じ警告は抑制してよい
  • 抑制キーにはlayer、side、event、reasonを含める
  • detailまでキーに入れると抑制が効きにくい場合がある
  • 検証時だけ詳細ログをONにできるようにする

実コード断片3:理由付きログ出力の使い分け

以下は、INIT、ENTRY_SKIP、ORDER_FAIL、OBJECT_AUDITを、同じログhelperで出し分ける学習用コード例です。売買判断や中核エントリー条件は含めていません。

// 学習用の使用例です。
// エントリー条件や外部制御ロジックは含めていません。

void LogInitExample()
{
   WriteDiagLog("INIT", "NONE", "START",
                "EA_LOADED",
                "symbol=" + _Symbol + " tf=" + EnumToString(_Period));
}

void LogEntrySkipExample(bool isBuy, string reason)
{
   string side = (isBuy ? "BUY" : "SELL");

   WriteDiagLogThrottled("ENTRY", side, "SKIP",
                         reason,
                         "scope=new_entry_only");
}

void LogOrderFailExample(bool isBuy, MqlTradeResult &result)
{
   string side = (isBuy ? "BUY" : "SELL");

   WriteDiagLog("ORDER", side, "SEND_FAIL",
                "ORDER_RETCODE",
                "retcode=" + IntegerToString((int)result.retcode));
}

void LogObjectAuditExample(string objectKind)
{
   WriteDiagLog("OBJECT_AUDIT", "NONE", "STARTUP_FOUND",
                "VISUAL_ONLY",
                "kind=" + objectKind);
}

実際のEAでは、認証、外部制御、口座条件、エラー処理、ログ出力などを分けて設計します。この記事では、公開できる範囲の構造だけを取り上げています。

この例で分かること

  • INIT、ENTRY、ORDER、OBJECT_AUDITを同じ形式で出せる
  • BUY / SELL / NONEをsideとして分けられる
  • SKIP、SEND_FAIL、STARTUP_FOUNDなどのeventを固定できる
  • reasonを分けることで、同じSKIPでも理由を追える
  • detailは調査に必要な補足だけに絞れる

注文要求と実行結果を構造化ログへ残す

以下のコード例は、個別の処理と確認項目を読むためのものです。複数の例をそのまま一つのEAへ連結する前提ではありません。初期化、値の取得、状態更新、終了処理をそれぞれの例で区別して確認してください。

OrderSend結果ログは注文処理の最終確認に使う

EAの発注処理では、シグナルが成立した後に、スプレッド、ロット、証拠金、SL / TP距離、取引許可、ポジション数、Magic Numberなどを確認し、最後にOrderSendで注文リクエストを送ります。

この時、OrderSendの直前までの条件がすべて正常でも、サーバー側で注文が拒否されることがあります。価格変動、取引時間外、ロット不正、証拠金不足、StopLevel違反、Filling Mode不一致、銘柄取引停止、通信状態などが関係するためです。

そのため、OrderSend結果ログでは、EA側が送ったリクエストと、サーバー側から返った結果を分けて残します。これにより、EAの判定ミスなのか、リクエスト構築ミスなのか、サーバー側の拒否なのか、口座・銘柄仕様の問題なのかを追いやすくなります。

確認層確認する内容主なログ
SIGNALBUY / SELLの候補が出たかSIGNAL_OK / SIGNAL_NG
GATE稼働時間、許可状態、最大ポジション数などGATE_PASS / GATE_BLOCK
SPECIAL FILTERSスプレッド、指標、外部停止、ボラティリティなどFILTER_PASS / FILTER_BLOCK
ORDER PRECHECKロット、証拠金、SL / TP距離、OrderCheckORDER_CHECK / PRECHECK_NG
ORDER SENDMqlTradeRequestを送信した結果ORDER_SEND_OK / ORDER_SEND_NG
ORDER RESULTretcode、deal、order、commentの確認TRADE_RESULT / RETCODE
FOLLOW-UPポジション反映、履歴、Magic Number確認POSITION_SYNC / HISTORY_CHECK

OrderSend前後でログを見る順番

OrderSend結果ログは、1行だけを見るのではなく、発注前の条件、送信したrequest、返ってきたresult、反映確認の順番で追うと原因を確認やすくなります。特に、注文が出ない時は「OrderSendまで到達していない」のか、「OrderSendは実行されたがサーバー側で拒否された」のかを最初に分けてください。

実務では、SIGNALやFILTERのログで止まっている場合と、OrderSend後のretcodeで止まっている場合では、見るべき箇所が変わります。前者はEA内部条件、後者はrequest内容、銘柄仕様、口座条件、サーバー応答を確認する流れになります。

確認順見るログ分けて確認すること
1SIGNAL / FILTER / GATE注文処理へ進む条件を満たしたか
2ORDER_CHECK_BEFORE送信予定のsymbol、type、volume、price、sl、tpが妥当か
3ORDER_CHECK_RESULTmargin、margin_free、retcode、commentで事前確認の結果を見る
4ORDER_SEND_BEFORE最終的にOrderSendへ渡したMqlTradeRequestを確認する
5ORDER_SEND_AFTERsend_ok、retcode、deal、order、comment、last_errorを分けて確認する
6POSITION / HISTORY約定、未約定注文、ポジション反映、履歴を確認する

MqlTradeRequestで送信前の条件を記録する

MqlTradeRequestは、OrderSendに渡す注文リクエスト構造体です。注文方向、銘柄、ロット、価格、SL、TP、Magic Number、コメント、Filling Modeなど、EAがサーバーへ送ろうとした内容が入ります。

注文エラー調査では、MqlTradeRequestの値が想定どおりかを確認します。EA側のロット正規化が漏れていないか、SL / TP価格が銘柄のStopLevelに合っているか、注文タイプと価格が一致しているか、Magic Numberが正しいかを確認してください。

request項目確認する内容よくある問題
actionTRADE_ACTION_DEAL、TRADE_ACTION_PENDINGなど成行注文と指値注文のaction不一致
symbol対象銘柄名suffix付き銘柄、GOLD / XAUUSD表記差
volume発注ロットvolume min / step / maxに合っていない
typeORDER_TYPE_BUY、ORDER_TYPE_SELLなどBUY / SELL方向の取り違え
price発注価格BUYでBid、SELLでAskを使うなどの方向ミス
sl損切り価格StopLevel違反、価格方向の誤り
tp利確価格StopLevel違反、価格方向の誤り
deviation許容スリッページ値が小さすぎて価格変更に弱い
magicMagic Number複数EAや手動取引との識別ができない
type_fillingFilling Mode銘柄仕様と不一致で注文拒否
comment注文コメントログ上で注文意図を追えない

MqlTradeResultで送信後の結果を記録する

MqlTradeResultは、OrderSend実行後にサーバー側から返る結果を受け取る構造体です。ここには、retcode、deal、order、volume、price、bid、ask、commentなどが入ります。

OrderSendの戻り値がtrueでも、result.retcodeを確認しなければ、どのような取引結果になったかを判断できません。OrderSendの戻り値、result.retcode、result.comment、GetLastErrorを混同しないようにしてください。

result項目確認する内容用途
retcodeTRADE_RETCODE系の結果コード注文結果の中心確認
deal約定deal番号約定済み取引の追跡
order注文番号未約定注文や注文履歴の追跡
volume結果側の数量部分約定や数量確認
price結果側の価格約定価格または処理価格の確認
bid / askサーバー側価格価格変更やスプレッド確認
commentサーバー側コメントretcodeの補足確認
request_idリクエスト識別非同期処理や追跡に使う場合がある
retcode_external外部システム由来のコードブローカー・取引所系の補足確認

OrderSendの戻り値とretcodeを分ける

OrderSendの戻り値は、取引リクエスト送信処理の成否を示します。一方、MqlTradeResultのretcodeは、取引サーバー側がそのリクエストをどのように処理したかを示します。

この2つを混同すると、「OrderSendがtrueだから注文成功」と誤解する可能性があります。注文処理では、OrderSendの戻り値、result.retcode、result.comment、GetLastErrorを必ず分けてログ化してください。

確認対象意味確認上の注意
OrderSend戻り値リクエスト送信処理の成否trueでも約定成功とは限らない
result.retcodeサーバー側の取引結果コードTRADE_RETCODE_DONEなどを確認する
result.commentサーバー側コメント拒否理由や補足が出る場合がある
GetLastError端末側・関数呼び出し側のエラーretcodeとは別に確認する
deal / order約定・注文番号成功時の追跡に使う
price / bid / ask処理価格・サーバー価格価格変更やスリッページ確認に使う

TRADE_RETCODEは分類して見る

TRADE_RETCODEは、注文結果の確認で最も重要な情報です。すべてのコードを暗記する必要はありませんが、成功系、価格系、証拠金系、ロット系、SL / TP系、取引許可系、通信・サーバー系に分類して見ると原因確認がしやすくなります。

分類代表的な状態確認すること
成功系DONE、PLACED、DONE_PARTIALdeal、order、volume、priceを確認する
価格系REQUOTE、PRICE_CHANGED、PRICE_OFFBid / Ask、deviation、約定方式を確認する
ロット系INVALID_VOLUMEvolume min / step / max、ロット正規化を確認する
SL / TP系INVALID_STOPSStopLevel、FreezeLevel、価格方向を確認する
証拠金系NO_MONEYOrderCalcMargin、margin_free、ロットを確認する
取引許可系TRADE_DISABLED、MARKET_CLOSED銘柄trade mode、取引時間、自動売買許可を確認する
Filling系INVALID_FILLSYMBOL_FILLING_MODEとrequest.type_fillingを確認する
通信・混雑系CONNECTION、TOO_MANY_REQUESTS通信状態、連続発注、リトライ制御を確認する
変更・凍結系ORDER_CHANGED、FROZEN注文変更、FreezeLevel、保留注文状態を確認する

retcodeを文字列化してログを読みやすくする

retcodeは数値で出すだけでも確認できますが、ログ確認やサポート時には、簡単な文字列化関数を用意しておくと原因確認が速くなります。

string TradeRetcodeToText(const uint retcode)
{
   switch(retcode)
   {
      case TRADE_RETCODE_REQUOTE:          return "REQUOTE";
      case TRADE_RETCODE_REJECT:           return "REJECT";
      case TRADE_RETCODE_CANCEL:           return "CANCEL";
      case TRADE_RETCODE_PLACED:           return "PLACED";
      case TRADE_RETCODE_DONE:             return "DONE";
      case TRADE_RETCODE_DONE_PARTIAL:     return "DONE_PARTIAL";
      case TRADE_RETCODE_ERROR:            return "ERROR";
      case TRADE_RETCODE_TIMEOUT:          return "TIMEOUT";
      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_TRADE_DISABLED:   return "TRADE_DISABLED";
      case TRADE_RETCODE_MARKET_CLOSED:    return "MARKET_CLOSED";
      case TRADE_RETCODE_NO_MONEY:         return "NO_MONEY";
      case TRADE_RETCODE_PRICE_CHANGED:    return "PRICE_CHANGED";
      case TRADE_RETCODE_PRICE_OFF:        return "PRICE_OFF";
      case TRADE_RETCODE_INVALID_EXPIRATION:return "INVALID_EXPIRATION";
      case TRADE_RETCODE_ORDER_CHANGED:    return "ORDER_CHANGED";
      case TRADE_RETCODE_TOO_MANY_REQUESTS:return "TOO_MANY_REQUESTS";
      case TRADE_RETCODE_NO_CHANGES:       return "NO_CHANGES";
      case TRADE_RETCODE_SERVER_DISABLES_AT:return "SERVER_DISABLES_AT";
      case TRADE_RETCODE_CLIENT_DISABLES_AT:return "CLIENT_DISABLES_AT";
      case TRADE_RETCODE_LOCKED:           return "LOCKED";
      case TRADE_RETCODE_FROZEN:           return "FROZEN";
      case TRADE_RETCODE_INVALID_FILL:     return "INVALID_FILL";
      case TRADE_RETCODE_CONNECTION:       return "CONNECTION";
      case TRADE_RETCODE_ONLY_REAL:        return "ONLY_REAL";
      case TRADE_RETCODE_LIMIT_ORDERS:     return "LIMIT_ORDERS";
      case TRADE_RETCODE_LIMIT_VOLUME:     return "LIMIT_VOLUME";
      default:                             return "UNKNOWN_RETCODE";
   }
}

この関数は、retcodeの分類を読みやすくするための補助です。実際の実装では、使用しているMT5ビルドやブローカーの返却内容に応じて、必要なコードを追加してください。

MqlTradeRequestをログに出す

OrderSend前には、MqlTradeRequestの中身をログに出します。これにより、EAが実際にどの条件で注文しようとしたのかを確認できます。

void LogTradeRequest(const string stage,
                     const MqlTradeRequest &request)
{
   PrintFormat("[%s_REQUEST] action=%d symbol=%s type=%d volume=%.2f price=%.5f sl=%.5f tp=%.5f deviation=%d magic=%I64d type_filling=%d comment=%s",
               stage,
               request.action,
               request.symbol,
               request.type,
               request.volume,
               request.price,
               request.sl,
               request.tp,
               request.deviation,
               request.magic,
               request.type_filling,
               request.comment);
}

stageには、ORDER_SEND_BEFORE、RETRY_BEFORE、CLOSE_BEFOREなど、どの段階のリクエストか分かる名前を入れると確認しやすくなります。

MqlTradeResultをログに出す

OrderSend後には、MqlTradeResultをログに出します。retcode、retcodeの文字列、deal、order、price、bid、ask、comment、GetLastErrorを同時に残すと、原因確認が進めやすくなります。

void LogTradeResult(const string stage,
                    const bool send_ok,
                    const MqlTradeResult &result,
                    const int last_error)
{
   PrintFormat("[%s_RESULT] send_ok=%s retcode=%u retcode_text=%s deal=%I64u order=%I64u volume=%.2f price=%.5f bid=%.5f ask=%.5f comment=%s last_error=%d",
               stage,
               (send_ok ? "true" : "false"),
               result.retcode,
               TradeRetcodeToText(result.retcode),
               result.deal,
               result.order,
               result.volume,
               result.price,
               result.bid,
               result.ask,
               result.comment,
               last_error);
}

OrderSendがfalseの場合でも、MqlTradeResultに情報が入ることがあります。send_okだけで分岐してログを省略せず、可能な限りresult全体を出してください。

OrderSend前後をまとめてログ化する例

次の例では、OrderSend前にrequestをログ化し、OrderSend後にresultとGetLastErrorをログ化します。実務では、この前段にスプレッド、ロット、証拠金、StopLevel、OrderCheckなどの確認を入れます。

bool SendTradeRequestWithResultLog(MqlTradeRequest &request,
                                   MqlTradeResult &result)
{
   ResetLastError();

   LogTradeRequest("ORDER_SEND_BEFORE", request);

   bool send_ok = OrderSend(request, result);
   int last_error = GetLastError();

   LogTradeResult("ORDER_SEND_AFTER", send_ok, result, last_error);

   if(!send_ok)
   {
      PrintFormat("[ORDER_SEND_NG] reason=function_false retcode=%u retcode_text=%s last_error=%d comment=%s",
                  result.retcode,
                  TradeRetcodeToText(result.retcode),
                  last_error,
                  result.comment);
      return false;
   }

   if(result.retcode != TRADE_RETCODE_DONE &&
      result.retcode != TRADE_RETCODE_PLACED &&
      result.retcode != TRADE_RETCODE_DONE_PARTIAL)
   {
      PrintFormat("[ORDER_SEND_NG] reason=retcode_not_success retcode=%u retcode_text=%s comment=%s",
                  result.retcode,
                  TradeRetcodeToText(result.retcode),
                  result.comment);
      return false;
   }

   PrintFormat("[ORDER_SEND_OK] retcode=%u retcode_text=%s deal=%I64u order=%I64u price=%.5f volume=%.2f",
               result.retcode,
               TradeRetcodeToText(result.retcode),
               result.deal,
               result.order,
               result.price,
               result.volume);

   return true;
}

失敗時はretcode、last_error、requestをセットで読む

OrderSendが失敗した時は、retcodeだけ、GetLastErrorだけ、commentだけを単独で見ないようにします。retcodeは取引サーバー側の結果、last_errorは端末側や関数呼び出し側の情報、requestはEAが実際に送った条件です。3つを並べることで、EA側の入力ミスなのか、銘柄仕様や口座条件なのか、通信やサーバー応答なのかを分けやすくなります。

確認例

ログ上の症状最初に確認すること次に見る情報
send_ok=falseGetLastErrorとrequest内容symbol、type、volume、price、sl、tp、filling
send_ok=trueだがretcodeが成功系でないresult.retcodeとcomment価格変更、証拠金、StopLevel、Filling Mode
INVALID_VOLUMEvolume min / step / maxロット正規化後の値、口座タイプ、銘柄仕様
INVALID_STOPSSL / TP方向とStopLevelFreezeLevel、point、digits、現在価格との距離
NO_MONEYOrderCalcMarginとmargin_freeロット、レバレッジ、口座通貨、銘柄条件
INVALID_FILLSYMBOL_FILLING_MODErequest.type_filling、銘柄ごとの約定方式
MARKET_CLOSED / TRADE_DISABLED取引時間とtrade modeサーバー時間、祝日、銘柄の取引停止状態

この確認は、売買判断を行うためではなく、EAの注文処理がどの段階で止まったかを確認するためのものです。ログを見てすぐにロットを上げる、条件を緩める、といった判断に直結させず、まずは原因の分類を行ってください。

この例では、OrderSendの戻り値がtrueでも、成功系retcodeでなければNGとして扱っています。実際の運用では、注文種別、約定方式、保留注文、部分約定、リトライ方針に合わせて成功判定を調整してください。

OrderCheckとOrderSend結果ログを分ける

OrderCheckは、MqlTradeRequestをサーバーへ送る前に確認する関数です。一方、OrderSendは実際に取引リクエストを送信する関数です。OrderCheckが成功しても、OrderSendが成功するとは限りません。

価格変動、取引時間、通信状態、Filling Mode、サーバー側の混雑、銘柄の取引状態などにより、OrderCheck後にOrderSendが失敗する場合があります。そのため、OrderCheckログとOrderSend結果ログは必ず分けてください。

段階確認する内容ログ例
OrderCheck前requestの内容が妥当かORDER_CHECK_BEFORE_REQUEST
OrderCheck後retcode、comment、margin、margin_freeORDER_CHECK_RESULT
OrderSend前最終的に送るrequestの内容ORDER_SEND_BEFORE_REQUEST
OrderSend後send_ok、retcode、deal、order、commentORDER_SEND_AFTER_RESULT
反映確認ポジション・履歴・Magic NumberPOSITION_SYNC / HISTORY_CHECK

OrderCheckの詳細は、MQL5 OrderCheckの使い方も確認してください。

OrderCalcMargin / OrderCalcProfitとの接続

OrderSend結果ログだけでは、注文前に必要証拠金や想定損益をどのように見積もったかは分かりません。発注前チェックでは、OrderCalcMarginで必要証拠金、OrderCalcProfitでSL / TP到達時の想定損益を確認し、その後にOrderCheck、OrderSendへ進む流れが分かりやすくなります。

確認項目使用する関数ログに残す内容
必要証拠金OrderCalcMarginsymbol、type、volume、price、margin
SL到達時の想定損失OrderCalcProfitentry、sl、volume、profit、loss_abs
TP到達時の想定利益OrderCalcProfitentry、tp、volume、profit
注文リクエスト事前確認OrderCheckretcode、comment、margin、margin_free
注文送信結果OrderSendsend_ok、retcode、deal、order、comment

必要証拠金と想定損益の確認は、MQL5 OrderCalcMargin / OrderCalcProfitの使い方で整理しています。

SymbolInfo系で銘柄仕様を確認する

OrderSend結果ログでINVALID_VOLUME、INVALID_STOPS、INVALID_FILLなどが出る場合、銘柄仕様の確認が必要になります。SymbolInfoDouble / SymbolInfoIntegerで、volume min、volume step、stops level、freeze level、filling mode、trade modeなどを確認してください。

retcode・症状確認する銘柄仕様代表的な確認
INVALID_VOLUMESYMBOL_VOLUME_MIN / STEP / MAXロット正規化
INVALID_STOPSSYMBOL_TRADE_STOPS_LEVELSL / TP距離
FROZENSYMBOL_TRADE_FREEZE_LEVEL注文変更・決済制限
INVALID_FILLSYMBOL_FILLING_MODEtype_fillingの対応
TRADE_DISABLEDSYMBOL_TRADE_MODE銘柄取引可否
価格差の違和感SYMBOL_POINT / DIGITS / TICK_VALUEpoint、digits、損益換算
スプレッド超過SYMBOL_SPREAD、Bid / Ask発注見送り理由

銘柄仕様の確認は、MQL5 SymbolInfoDouble / SymbolInfoIntegerの使い方を確認してください。

CTradeを使う場合も結果ログを省略しない

CTradeクラスを使う場合でも、注文結果ログは必要です。CTradeのBuy、Sell、PositionCloseなどは便利ですが、内部でどのようなリクエストが作られ、どのretcodeが返ったかを確認しないと、注文エラーの原因を追いにくくなります。

CTradeでは、ResultRetcode、ResultRetcodeDescription、ResultDeal、ResultOrder、ResultPrice、ResultVolumeなどをログに出すと確認しやすくなります。

CTradeで見る項目確認する内容用途
ResultRetcode取引結果コードOrderSend結果と同じく中心確認
ResultRetcodeDescriptionretcodeの説明ログを読みやすくする
ResultDealdeal番号約定確認
ResultOrderorder番号注文履歴確認
ResultPrice処理価格約定価格やサーバー価格確認
ResultVolume処理数量部分約定や数量確認
CheckResultRetcodeOrderCheck相当の確認発注前確認との接続

CTradeとMqlTradeRequestの違いは、MQL5 CTradeとMqlTradeRequestの違いも参考になります。

バックテストでOrderSend結果ログを見る

バックテストで注文が出ない場合、まずシグナルが出ているか、発注前チェックを通過しているか、OrderSendまで到達しているかを確認します。OrderSendログがない場合、どこで止まったかを判断しにくくなります。

症状見るログ確認する内容
注文が出ないSIGNAL / GATE / ORDER_SENDOrderSendまで到達しているか
OrderSendに到達しないFILTER / PRECHECKスプレッド、ロット、時間条件、ポジション制限
OrderSendがfalseORDER_SEND_AFTER_RESULTlast_error、retcode、comment
retcodeが成功系でないTRADE_RETCODE分類価格、証拠金、SL / TP、Filling Mode
取引履歴に出ないdeal / order / history約定・注文番号の確認
バックテストだけ動かないTesterログ / Expertsログモデル、データ不足、初期化失敗

バックテスト結果の見方は、MT5でバックテスト結果を相談する前に整理することとも接続して確認してください。

デモ口座・リアル口座で結果が違う時の確認

デモ口座とリアル口座では、スプレッド、約定、取引時間、最小ロット、Filling Mode、銘柄名、手数料、約定拒否の扱いが異なる場合があります。同じEA、同じsetファイルでも、OrderSend結果が変わることがあります。

差が出る項目確認する内容ログで見る場所
スプレッドデモとリアルのBid / Ask差request.price、result.bid、result.ask
約定方式Filling Modeや約定拒否type_filling、retcode
取引時間サーバー時間・休場時間MARKET_CLOSED、trade mode
最小ロットvolume min / steprequest.volume、INVALID_VOLUME
証拠金条件レバレッジ、必要証拠金OrderCalcMargin、NO_MONEY
銘柄名suffix、銘柄仕様差request.symbol、SymbolInfoログ
通信状態接続断、サーバー応答CONNECTION、TIMEOUT、last_error

OrderSend結果ログの出力例

以下はログ出力の例です。実際の数値は、銘柄、口座、価格、ロット、ブローカー、相場環境によって変わります。

[ORDER_SEND_BEFORE_REQUEST] action=1 symbol=GOLD type=0 volume=0.10 price=2350.45000 sl=2345.45000 tp=2358.45000 deviation=20 magic=20260603 type_filling=1 comment=EAFC_ENTRY_BUY
[ORDER_SEND_AFTER_RESULT] send_ok=true retcode=10009 retcode_text=DONE deal=123456789 order=987654321 volume=0.10 price=2350.46000 bid=2350.43000 ask=2350.46000 comment=Done last_error=0
[ORDER_SEND_OK] retcode=10009 retcode_text=DONE deal=123456789 order=987654321 price=2350.46000 volume=0.10

ログを見る時は、OrderSend前のrequest.priceと、OrderSend後のresult.price、result.bid、result.askを比較します。価格差、スプレッド、deviation、retcodeを合わせて見ると、約定まわりの原因を確認しやすくなります。

ログ設計と責務分離

ログファースト設計では、ログ出力そのものも責務分離します。

責務役割ログでの確認例
signal判定候補を作るSIGNAL、CANDIDATE、NO_SIGNAL
execution注文・決済を実行するORDER、CLOSE、SEND_FAIL、CLOSE_FAIL
riskロット、損失、上限、保護条件を扱うRISK_BLOCK、LOT_INVALID、LIMIT_REACHED
exit建値、トレール、決済条件を扱うTRAIL、BE、EXIT_SKIP、EXIT_DONE
auth利用許可や認証状態を扱う公開記事では詳細を扱わない。ログにも機密を出さない
external control外部設定による動作制御を扱う公開記事では詳細を扱わない。新規Entry停止と保護継続は分ける
UI / Objectチャート表示、パネル、ラインを扱うOBJECT_AUDIT、DISPLAY_SKIP、CLEANUP_SUMMARY

特に重要なのは、判定不成立と執行見送りを混同しないことです。

シグナルが成立していない場合と、シグナル候補はあるがスプレッドや保有上限などで見送った場合では、確認すべき場所が違います。ログでは、この違いをreasonとして残す必要があります。

開発版と配布版でログ粒度を分ける

開発・検証向け構成や開発検証版では、原因調査に必要な詳細ログを出します。一方、購入者向けの利用者向け配布版版では、通常利用に必要な状態、停止理由、エラーを中心にし、過剰な内部情報や大量ログを抑えます。

ログ量を変える場合でも、event名とreason名は可能な限り共通化します。これにより、開発版と配布版のログを比較しやすくなります。URL、token、APIキー、Webhook、口座情報などの実値は、どちらの版でも出力しません。

ログに出してよい情報・出してはいけない情報

ログは問い合わせや検証に使うため、必要な情報を残す一方で、機密情報を出してはいけません。

分類ログに出してよい例ログに出してはいけない例
環境symbol、timeframe、digits、point口座番号、サーバー名、個人情報
注文結果retcode、action、side、lotの分類実運用set値の詳細、推奨ロット表現
外部連携接続成功/失敗の分類、masked表示endpoint、token、Webhook URL、GAS URL、Sheet ID
認証OK / NG / masked summary認証ロジック、購入者管理情報、許可判定の詳細
Entry見送り理由の分類中核エントリー条件、独自優位性のある判定式
Objectkind、event、visual-only、ignore他EAや手動Objectを巻き込む詳細削除方針

問い合わせ時にログを共有する場合も、URL、token、口座情報、個人情報が含まれていないか確認してください。

よくある失敗例

失敗1:成功ログしか出していない

注文成功や初期化成功だけをログに出していると、EAが動かない時に原因を追えません。見送り、block、failも理由付きで残す必要があります。

失敗2:毎tick同じログを出している

OnTickで毎回同じPrintを出すと、短時間でログが大量になります。待機状態や同じ見送り理由は、状態変化時または一定間隔で出す方が実用的です。

失敗3:ログ文言が毎回違う

「注文できませんでした」「発注失敗」「Order error」のように表記が揺れると、検索や比較が難しくなります。eventやreasonは固定名にします。

失敗4:ログに機密情報を出している

外部連携や認証を使うEAでは、URL、token、Sheet ID、Webhook URLなどをログに出してはいけません。ログは共有される前提で設計します。

失敗5:ログ出力が売買ロジックへ影響している

ログ出力のON/OFFを変更しただけで売買判定や決済挙動が変わる構造は危険です。判定helper、執行helper、ログhelperは分けて設計します。

Expertsログで確認するポイント

EAの状態を確認する時は、Expertsログの中で次の順に見ます。

  1. INITログでEAが正しく起動しているか確認する
  2. RUNTIMEまたはCHECKログで主要状態が安全側になっていないか確認する
  3. ENTRY_SKIPログで新規エントリー見送り理由を確認する
  4. ORDERログで注文送信結果を確認する
  5. CLOSE、EXIT、TRAILなどの管理決済ログを確認する
  6. OBJECT_AUDITログで表示Objectの残存や無視処理を確認する
  7. DEINIT周辺で異常終了や終了時の余計な売買処理がないか確認する

MT5のExpertsログとJournalログの見方は、基本確認ページも参考にしてください。

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

問い合わせ前に送るログ

EAの不具合確認や開発相談を行う場合は、次の情報を整理すると原因を確認やすくなります。

送る情報内容注意点
EA名・バージョン対象ファイル名とバージョン旧版と混在していないか確認する
発生時刻問題が起きた日時PC時刻、サーバー時刻の違いに注意する
symbol・timeframe対象銘柄と時間足チャートとsetの対象を一致させる
ExpertsログINIT、ENTRY_SKIP、ORDER_FAIL、OBJECT_AUDITなど発生前後を含める
Journalログ端末側エラーや接続状態Expertsだけで不足する時に確認する
setファイル使用した設定URL、token、口座情報は削除またはマスクする
スクリーンショットチャート、パネル、ログ画面口座番号などが映っていないか確認する

不具合相談前の整理は、次のページも参考にしてください。

不具合報告・調査依頼について

注文ログの失敗例と共有前の確認

よくある失敗パターン

失敗パターン問題点対策
OrderSendの戻り値だけ見るretcodeを見落として原因が分からないresult.retcodeとcommentを必ず出す
GetLastErrorだけ見るサーバー側retcodeを見落とすretcodeとlast_errorを分ける
requestをログに出さない何を送ったか分からないOrderSend前にrequest全体を出す
resultを成功時だけ出す失敗時の原因が追えない成功・失敗に関係なくresultを出す
ロット正規化前の値を送るINVALID_VOLUMEになりやすいvolume stepで正規化後に送る
SL / TP距離を確認しないINVALID_STOPSになりやすいStopLevelと価格方向を確認する
Filling Modeを固定する銘柄仕様と合わない場合があるSYMBOL_FILLING_MODEを確認する
CTradeでログを省略する内部結果を追えないCTradeのResult系を出す
リトライを無制限にするTOO_MANY_REQUESTSや過剰注文になる回数と理由を制限する

注文エラー調査で提出するとよい情報

OrderSend結果を相談する場合は、結果ログだけでなく、発注前の条件と再現情報をセットで整理してください。

整理する情報確認内容
EA名・バージョン対象EA、更新日、検証版か通常版か
対象銘柄symbol、suffix、GOLD / XAUUSD表記
時間足・稼働条件チャート時間足、内部参照時間足、稼働時間
setファイルロット、SL / TP、Magic Number、発注条件
OrderCheckログretcode、comment、margin、margin_free
OrderSend前requestログaction、symbol、type、volume、price、sl、tp、filling
OrderSend後resultログsend_ok、retcode、deal、order、comment、last_error
SymbolInfoログpoint、digits、volume step、stops level、trade mode
Expertsログ・Journalログ発生時刻前後のログ
再現条件バックテスト、デモ口座、リアル口座のどこで発生したか

ログを共有する時に伏せる情報

調査依頼や問い合わせでログを共有する場合は、原因確認に必要な情報と、公開・共有すべきではない情報を分けます。OrderSendの原因調査では、retcode、comment、symbol、volume、price、sl、tp、filling、margin、timeなどは役立ちますが、口座番号、氏名、メールアドレス、パスワード、APIキー、Webhook URLなどは伏せてください。

分類共有してよい情報の例伏せる情報の例
注文条件symbol、type、volume、price、sl、tp、deviation口座番号、氏名、メールアドレス
結果ログsend_ok、retcode、comment、deal/orderの一部マスク完全な注文番号や個人を特定できる情報
EA設定検証に必要なパラメータ、Magic Numberの一部ライセンスキー、認証情報、Webhook URL
環境情報バックテスト、デモ、リアルの区分、銘柄、時間帯サーバー接続情報やログイン情報

OrderSend結果ログの実務チェック表

  • OrderSend前にMqlTradeRequestをログ出力している
  • OrderSend後にMqlTradeResultをログ出力している
  • OrderSendの戻り値とresult.retcodeを分けて確認している
  • result.commentとGetLastErrorを両方出している
  • deal、order、price、volumeを成功時に確認している
  • retcodeを文字列化してログを読みやすくしている
  • OrderCheckログとOrderSendログを分けている
  • OrderCalcMarginで必要証拠金を確認している
  • SymbolInfo系でvolume step、StopLevel、Filling Modeを確認している
  • CTrade利用時もResultRetcodeなどを確認している
  • バックテスト、デモ口座、リアル口座の差を分けて確認している
  • 口座番号、パスワード、APIキー、Webhook URLなどをログ共有時に伏せている

ログファースト設計を開発依頼に活かす

EA開発を依頼する時も、ログ仕様を最初に決めておくと、完成後の確認がしやすくなります。

開発依頼前には、次のようなログ方針を整理しておくと実務上有効です。

  • 起動時に何を確認したいか
  • エントリー見送り理由をどこまで出したいか
  • 注文失敗時にretcodeを出すか
  • 決済失敗や変更失敗をどの粒度で出すか
  • チャートObjectの残存や再セットを監査するか
  • 長時間稼働時にログ過多を防ぐか
  • 問い合わせ時に送るログ項目を決めるか

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

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

公開しない情報

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

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

本記事は、投資判断や売買指示ではなく、MQL5開発におけるログ設計と検証手順を理解するための技術解説です。

よくある質問

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

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

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

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

EAが動かない時は、どのログを見ればよいですか?

まずINITログで起動状態を確認し、次にENTRY_SKIP、ORDER、CLOSE、OBJECT_AUDITなどを確認します。見送りなのか、注文失敗なのか、表示Objectの問題なのかを分けて見ることが重要です。

ENTRY_SKIPログが出ている場合は、エントリー条件が悪いという意味ですか?

必ずしもそうではありません。ENTRY_SKIPは、新規エントリー候補があっても、スプレッド、保有上限、同一バー制御、リスク制御などで見送る場合にも出ます。reasonを確認してください。

ORDER_FAILログが出た場合は何を確認しますか?

retcode、GetLastError、symbol、lot、注文種別、AutoTradingの状態、証拠金、ブローカー側の制約などを確認します。単に「注文失敗」と見るのではなく、戻り値と理由を分けて確認します。

ログは多いほどよいですか?

いいえ。重要な失敗ログは残すべきですが、同じ待機ログや同じ見送り理由を毎tick出すと、確認しにくくなります。状態変化時だけ出す、または一定間隔で抑制する設計が有効です。

問い合わせ時にログをそのまま送ってよいですか?

送る前に、URL、token、Webhook URL、GAS URL、Google Sheet ID、口座番号、個人情報が含まれていないか確認してください。必要に応じてマスクしたうえで共有してください。

この記事は売買判断や推奨設定を示すものですか?

いいえ。この記事はMQL5開発におけるログ設計の技術解説です。売買判断、推奨ロット、推奨銘柄、利益保証、勝率保証を行うものではありません。

OrderSendがtrueなら注文成功ですか?

必ずしもそうとは限りません。OrderSendの戻り値は送信処理の成否を示します。注文結果はMqlTradeResultのretcode、deal、order、commentを確認してください。

GetLastErrorだけ見れば原因は分かりますか?

GetLastErrorは端末側・関数呼び出し側のエラー確認に使いますが、取引サーバー側の結果はresult.retcodeとresult.commentを見る必要があります。両方をログに出してください。

CTradeを使っている場合もMqlTradeResultを見る必要がありますか?

必要です。CTradeを使う場合も、ResultRetcode、ResultRetcodeDescription、ResultDeal、ResultOrder、ResultPriceなどを確認してください。ラッパーを使っていても、注文結果の確認は省略しない方が安全です。

INVALID_STOPSが出る時は何を確認しますか?

SL / TP価格の方向、StopLevel、FreezeLevel、point、digits、現在価格との距離を確認します。SymbolInfoIntegerやSymbolInfoDoubleで銘柄仕様を取得し、ログに残してください。

NO_MONEYが出る時は何を確認しますか?

ロット、必要証拠金、余剰証拠金、レバレッジ、口座通貨、銘柄仕様を確認します。OrderCalcMarginとOrderCheckのmargin、margin_freeを合わせて見ると確認しやすくなります。

バックテストでは成功するのにリアル口座で失敗することはありますか?

あります。リアル口座では、スプレッド、約定、取引時間、Filling Mode、通信、銘柄仕様、ブローカー制限などが影響します。バックテスト、デモ、リアルでログを分けて確認してください。

ログを問い合わせで共有する時に注意することはありますか?

あります。retcode、comment、requestの主要項目、発生時刻、銘柄、バックテスト・デモ・リアルの区分は原因確認に役立ちます。一方で、口座番号、氏名、メールアドレス、パスワード、APIキー、Webhook URL、ライセンスキーなどは伏せてください。

関連する確認ページ

確認したい内容に応じて、次のページを参照してください。本文中ですでに案内したページは、ここでは重ねて掲載していません。

確認分野関連ページ
技術講座MQL5デバッグ・ログファースト開発完全ガイド|Print・Expertsログ・再現条件の整理
技術講座MQL5ロット・証拠金・銘柄仕様完全ガイド|volume step・tick value・stops levelの確認
技術辞典MQL5ファイル操作関数辞典|FileOpen・FileRead・FileWrite・CSV出力の基本
開発実務ノート自動売買EAを自作する前に確認すること|ロジック・バックテスト・ログ設計

あわせて確認したいページ

今回の確認内容に関連する補足ページです。必要な項目だけ確認してください。

確認目的関連ページ
読後の任意の手続き・一覧入口。本文解決や購入の必須前提にしないMT4/MT5 技術講座
「MQL5 ログ設計 実装例」の読後に「MQL5エラーコード辞典」を補足確認MQL5エラーコード辞典
「MQL5 ログ設計 実装例」の読後に「MQL5 Multi-Logic EA設計を実コードで解説」を補足確認MQL5 Multi-Logic EA設計を実コードで解説

まとめ

MQL5 EAのログ設計では、Printを増やすことよりも、後から追える形でログを設計することが重要です。

特に、次の4点を分けておくと、不具合確認や保守がしやすくなります。

  • event:何が起きたか
  • side:BUY、SELL、NONEのどれか
  • reason:なぜ起きたか
  • detail:確認に必要な補足情報

EAが動かない時に重要なのは、単に「動かない」と判断することではなく、起動、判定、見送り、発注、決済、表示、終了処理のどこで止まっているかを分けて確認することです。

ログファースト設計は、開発者だけでなく、EAを使う側、検証する側、サポートを受ける側にも役立ちます。完成EAの中核ロジックを公開しなくても、ログ設計の考え方を理解しておくことで、問題発生時の確認がしやすくなります。

お問い合わせはEAFC公式LINEへ

EAFCサイト内の記事、商品、導入前確認、設定確認、ログ確認、開発依頼前のご相談など、各種お問い合わせはEAFC公式LINEより受け付けています。

※投資助言、売買指示、利益保証、推奨ロット、推奨銘柄の案内は行っておりません。

口座番号、認証情報、Webhook URL、GAS URL、APIキーなどの機密情報は送信しないでください。

利用条件・相談窓口

確認内容案内ページ
MT5 開発依頼・作成代行|EA・インジケーター新規開発・MT4/MT5既存改修開発・改修の相談ページを見る
よくある質問|EA・インジケーター・開発依頼・サポートFAQよくある質問
購入前確認事項ご購入前の確認事項
免責事項・リスク説明免責事項
投資助言を行わない方針投資助言を行わない方針
ABOUT ME
記事URLをコピーしました