技術辞典

MQL5 OrderCheckで証拠金・ロット・StopLevelを確認する方法

EAファンクラブ

OrderCheckは、MQL5で注文リクエストを送信する前に、証拠金、ロット、価格、SL/TP距離、注文条件などを確認するための重要な関数です。

ただし、OrderCheckを呼び出すだけで、EAの発注前チェックがすべて安全になるわけではありません。実際のEAでは、OrderCheckの前に銘柄仕様、最小ロット、最大ロット、volume step、StopLevel、FreezeLevel、BUY / SELL価格、証拠金、スプレッド、取引可否を確認し、OrderCheckの後にはOrderSendやCTradeの結果も別に確認する必要があります。

特に、EA開発でよく起きる「ロット不正」「証拠金不足」「invalid stops」「SL/TPの距離不足」「FreezeLevelによる変更失敗」「OrderCheckは通ったのにOrderSendで失敗する」といった問題は、OrderCheck単体ではなく、発注前チェック全体として整理すると切り分けやすくなります。

このページでは、MQL5のOrderCheckを使って、証拠金、ロット、volume step、StopLevel、FreezeLevel、invalid stops、OrderCalcMargin、SymbolInfo、MqlTradeRequest、MqlTradeCheckResult、retcode、ログ確認を整理します。

なお、このページはMT5 / MQL5のEA開発、発注前チェック、注文失敗の切り分けを目的とした技術記事です。売買判断、推奨エントリー、推奨ロット、推奨銘柄、利益保証、損失回避保証を行うものではありません。

OrderCheckとは何か

OrderCheckは、MqlTradeRequestで作成した注文リクエストをサーバーへ送信する前に、注文条件として問題がないかを確認するための関数です。

OrderCheckを使うと、発注前にMqlTradeCheckResultを受け取り、retcode、必要証拠金、余剰証拠金、コメントなどを確認できます。これにより、OrderSendを実行する前に、明らかな条件不備をログへ残しやすくなります。

項目役割確認する内容
MqlTradeRequest注文リクエストsymbol、volume、price、SL、TP、type、type_filling、magicなど
OrderCheck()注文前チェックリクエスト内容が発注条件として妥当か
MqlTradeCheckResultチェック結果retcode、margin、margin_free、commentなど
OrderSend()実際の発注注文送信後のretcode、order、deal、commentなど

OrderCheckは、発注前の確認に役立ちますが、実際の約定を保証するものではありません。OrderCheckが通っても、価格変動、スプレッド拡大、約定方式、type_filling、FreezeLevel、サーバー側制約などにより、OrderSendで失敗する場合があります。

OrderCheckを発注前チェックのどこに置くか

OrderCheckは、発注前チェックの最後に近い位置で使うのが基本です。

なぜなら、ロット、価格、SL/TP、deviation、type_filling、magic、commentなどをMqlTradeRequestへ入れた後でないと、注文リクエスト全体の妥当性を確認できないためです。

工程主な確認内容代表ログ
シグナル判定BUY / SELL候補があるかSIGNAL
フィルター確認スプレッド、時間帯、最大ポジション数、外部停止などFILTER_CHECK
銘柄仕様確認digits、point、tick size、volume min / max / stepSYMBOL_SPEC
ロット確認最小ロット、最大ロット、volume stepへの丸めLOT_CHECK
価格確認BUYはAsk、SELLはBid、現在価格、丸めPRICE_CHECK
SL/TP確認StopLevel、FreezeLevel、SL/TP方向、距離STOPS_CHECK
証拠金確認OrderCalcMargin、余剰証拠金、必要証拠金MARGIN_CHECK
リクエスト作成MqlTradeRequestへ値を設定REQUEST_BUILD
OrderCheck注文リクエスト全体の事前確認ORDER_CHECK
OrderSend / CTrade実際の注文送信と結果確認ORDER_SEND

OrderCheckを最初に呼び出すのではなく、EA側で整えられる条件を先に整え、その結果として作成したMqlTradeRequestをOrderCheckへ渡す流れにすると、ログの意味が分かりやすくなります。

OrderCalcMarginとOrderCheckの使い分け

証拠金だけを確認したい場合は、OrderCalcMarginが使いやすい場面があります。

OrderCalcMarginは、指定した銘柄、注文方向、ロット、価格に対して必要証拠金を計算します。一方、OrderCheckは、MqlTradeRequest全体を対象に、証拠金やリクエスト内容をまとめて確認します。

確認方法主な役割確認できる内容
SymbolInfoDouble() / SymbolInfoInteger()銘柄仕様を取得するvolume step、point、digits、StopLevel、FreezeLevelなど
OrderCalcMargin()必要証拠金を計算する指定ロットで必要な証拠金
OrderCheck()注文リクエスト全体を事前確認するretcode、margin、margin_free、commentなど
OrderSend() / CTrade実際の注文結果を確認するretcode、order、deal、commentなど

実務では、OrderCalcMarginで概算の必要証拠金を確認し、ロットやSL/TPを整えた後、OrderCheckでリクエスト全体を確認する流れが扱いやすいです。どちらか一方だけに寄せるのではなく、役割を分けて使うと、証拠金不足なのか、リクエスト内容の不備なのかを切り分けやすくなります。

OrderCalcMarginで必要証拠金を確認する例

OrderCalcMarginを使うと、注文方向、銘柄、ロット、価格に対して必要証拠金を確認できます。

bool CheckRequiredMargin(const string symbol,
                         const ENUM_ORDER_TYPE order_type,
                         const double volume)
{
   double price = 0.0;

   if(order_type == ORDER_TYPE_BUY)
      price = SymbolInfoDouble(symbol, SYMBOL_ASK);
   else if(order_type == ORDER_TYPE_SELL)
      price = SymbolInfoDouble(symbol, SYMBOL_BID);
   else
      return false;

   double margin = 0.0;

   ResetLastError();

   bool ok = OrderCalcMargin(order_type, symbol, volume, price, margin);
   int last_error = GetLastError();

   double free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);

   Print("MARGIN_CHECK",
         " symbol=", symbol,
         " type=", order_type,
         " volume=", DoubleToString(volume, 2),
         " price=", DoubleToString(price, (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS)),
         " ok=", ok ? "Y" : "N",
         " required=", DoubleToString(margin, 2),
         " free=", DoubleToString(free_margin, 2),
         " last_error=", last_error);

   if(!ok)
      return false;

   return (free_margin > margin);
}

この例では、OrderCalcMarginで必要証拠金を確認し、口座の余剰証拠金と比較しています。実際のEAでは、現在のポジション数、追加エントリー予定、ナンピン余力、最大ロット、リスク制限も合わせて確認することがあります。

OrderCalcMarginは便利ですが、SL/TPの距離、type_filling、取引許可、StopLevelなどをすべて確認する関数ではありません。そのため、証拠金確認だけで発注可否を確定せず、OrderCheckやOrderSend結果も別に確認してください。

volume min / max / stepを確認する

EAの発注前チェックでは、ロットが銘柄仕様に合っているかを確認します。

MT5では、銘柄ごとに最小ロット、最大ロット、ロット刻みが設定されています。たとえば、最小ロットが0.01、volume stepが0.01の銘柄もあれば、最小ロットやstepが異なる銘柄もあります。

項目MQL5定数確認内容
最小ロットSYMBOL_VOLUME_MINこの値未満のロットは不正になる
最大ロットSYMBOL_VOLUME_MAXこの値を超えるロットは不正になる
ロット刻みSYMBOL_VOLUME_STEP指定ロットをstepに合わせて丸める必要がある
ロット上限SYMBOL_VOLUME_LIMIT同一方向の合計ロット制限を確認する場合がある

ロット不正は、OrderCheckやOrderSendの失敗原因になりやすい項目です。固定ロット、複利ロット、分割エントリー、ナンピン、コピーEAのロット倍率を使う場合は、最終的に発注するロットがvolume stepに合っているかを確認してください。

ロットをvolume stepへ丸める例

ロットを計算した後は、銘柄のvolume stepに合わせて丸めます。

double NormalizeVolumeByStep(const string symbol, const double raw_volume)
{
   double min_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
   double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
   double step       = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);

   if(step <= 0.0)
      return 0.0;

   double volume = raw_volume;

   if(volume < min_volume)
      volume = min_volume;

   if(volume > max_volume)
      volume = max_volume;

   volume = MathFloor(volume / step) * step;

   int digits = 2;
   if(step < 0.01)
      digits = 3;
   if(step < 0.001)
      digits = 4;

   volume = NormalizeDouble(volume, digits);

   Print("LOT_CHECK",
         " symbol=", symbol,
         " raw=", DoubleToString(raw_volume, 4),
         " normalized=", DoubleToString(volume, digits),
         " min=", DoubleToString(min_volume, digits),
         " max=", DoubleToString(max_volume, digits),
         " step=", DoubleToString(step, digits));

   return volume;
}

この例では、最小ロットと最大ロットの範囲に収めたうえで、volume stepに合わせてロットを丸めています。実際には、丸め方法を切り捨てにするのか、四捨五入にするのか、最小ロット未満を発注しないのかは、EAの仕様として決めておく必要があります。

BUY / SELL価格の基準を確認する

OrderCheckやOrderCalcMarginへ渡す価格は、注文方向に合わせて確認します。

一般的に、BUY注文ではAsk、SELL注文ではBidを基準にします。価格の取り違えは、発注前チェックやSL/TP距離確認の結果に影響します。

注文方向基準価格主な確認内容
BUYSYMBOL_ASK買い注文の発注価格、SLは下側、TPは上側
SELLSYMBOL_BID売り注文の発注価格、SLは上側、TPは下側

EA内では、価格取得、digits、point、tick size、NormalizeDoubleを組み合わせて、発注価格とSL/TP価格を整えます。小数桁やtick sizeの扱いが不十分だと、見た目には正しそうでもサーバー側で不正価格として扱われる場合があります。

価格とdigitsを確認する例

double GetOrderPrice(const string symbol, const ENUM_ORDER_TYPE order_type)
{
   double price = 0.0;

   if(order_type == ORDER_TYPE_BUY)
      price = SymbolInfoDouble(symbol, SYMBOL_ASK);
   else if(order_type == ORDER_TYPE_SELL)
      price = SymbolInfoDouble(symbol, SYMBOL_BID);

   int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);

   price = NormalizeDouble(price, digits);

   Print("PRICE_CHECK",
         " symbol=", symbol,
         " type=", order_type,
         " price=", DoubleToString(price, digits),
         " digits=", digits);

   return price;
}

このように、価格とdigitsをログに出しておくと、OrderCheckやOrderSendで価格関連の失敗が起きた時に原因を追いやすくなります。

StopLevelとFreezeLevelを分けて確認する

StopLevelとFreezeLevelは混同しやすい項目です。

StopLevelは、現在価格からSL / TP / pending order価格までに必要な最小距離に関係します。FreezeLevelは、現在価格に近い注文やポジションの変更が制限される範囲に関係します。

項目MQL5定数主な意味
StopLevelSYMBOL_TRADE_STOPS_LEVELSL / TPや指値・逆指値注文に必要な最小距離
FreezeLevelSYMBOL_TRADE_FREEZE_LEVEL現在価格に近い注文やポジション変更が制限される範囲
PointSYMBOL_POINT価格単位を距離へ換算するために使う
DigitsSYMBOL_DIGITS価格の小数桁を整えるために使う

invalid stopsが出る場合は、SL / TPの方向が間違っているのか、距離が不足しているのか、価格丸めが不適切なのか、StopLevelが足りないのか、FreezeLevelにかかっているのかを分けて確認します。

StopLevelを確認する例

bool CheckStopsDistance(const string symbol,
                        const ENUM_ORDER_TYPE order_type,
                        const double entry_price,
                        const double sl,
                        const double tp)
{
   double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int stops_level = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);

   double min_distance = stops_level * point;

   bool ok = true;

   if(order_type == ORDER_TYPE_BUY)
   {
      if(sl > 0.0 && (entry_price - sl) < min_distance)
         ok = false;

      if(tp > 0.0 && (tp - entry_price) < min_distance)
         ok = false;
   }
   else if(order_type == ORDER_TYPE_SELL)
   {
      if(sl > 0.0 && (sl - entry_price) < min_distance)
         ok = false;

      if(tp > 0.0 && (entry_price - tp) < min_distance)
         ok = false;
   }

   Print("STOPS_CHECK",
         " symbol=", symbol,
         " type=", order_type,
         " entry=", DoubleToString(entry_price, digits),
         " sl=", DoubleToString(sl, digits),
         " tp=", DoubleToString(tp, digits),
         " stops_level=", stops_level,
         " min_distance=", DoubleToString(min_distance, digits),
         " ok=", ok ? "Y" : "N");

   return ok;
}

StopLevel確認では、BUYとSELLでSL / TPの方向が逆になります。BUYのSLはentryより下、TPは上です。SELLのSLはentryより上、TPは下です。この方向を間違えると、距離以前に注文条件として不正になります。

FreezeLevelを確認する場面

FreezeLevelは、新規注文よりも、注文変更、SL / TP変更、決済、指値・逆指値注文の変更で問題になることがあります。

たとえば、ポジションに対してSLを後から設定するEA、トレーリングストップ、建値移動、分割決済、pending orderの価格変更を行うEAでは、FreezeLevelを確認しておく必要があります。

処理FreezeLevelの影響確認ログ
SL / TP変更現在価格に近すぎると変更できない場合があるFREEZE_CHECK
トレーリングストップ価格が近い状態で頻繁に変更しようとして失敗するTRAIL_MODIFY_SKIP
建値移動変更先SLが制限範囲に入る場合があるBE_MODIFY_CHECK
pending order変更注文価格やSL/TP変更が拒否される場合があるPENDING_MODIFY_CHECK

FreezeLevelによる失敗は、OrderCheckの段階だけではなく、ポジション保有後の変更処理で表面化することがあります。そのため、発注前チェックと保有後の変更チェックを分けてログ化してください。

MqlTradeRequestへ入れる値を確認する

OrderCheckは、MqlTradeRequestの内容を確認します。そのため、OrderCheck前にrequestへ入れる値が正しいかを確認する必要があります。

request項目確認内容注意点
actionTRADE_ACTION_DEALなど成行注文か、pending orderか、変更かを分ける
symbol対象銘柄チャート銘柄と発注銘柄が一致しているか
volume発注ロットvolume min / max / stepへ合わせる
typeORDER_TYPE_BUY / ORDER_TYPE_SELLなど価格、SL、TP方向と一致させる
price発注価格BUYはAsk、SELLはBidを基準にする
sl損切り価格方向、StopLevel、FreezeLevelを確認する
tp利確価格方向、StopLevel、FreezeLevelを確認する
deviation許容スリッページ銘柄や戦略に合わせて設定する
magicMagic NumberEA・ロジック・コピー対象の識別に使う
comment注文コメント履歴確認用の補助情報として使う
type_filling約定方式銘柄やブローカーで許可される方式を確認する

requestを作ったら、OrderCheckの前にログへ出すと、注文失敗時の切り分けがしやすくなります。特に、volume、price、sl、tp、magic、type_fillingは確認対象として重要です。

OrderCheckの基本コード例

bool CheckTradeRequest(MqlTradeRequest &request)
{
   MqlTradeCheckResult check;
   ZeroMemory(check);

   ResetLastError();

   bool ok = OrderCheck(request, check);
   int last_error = GetLastError();

   Print("ORDER_CHECK",
         " ok=", ok ? "Y" : "N",
         " retcode=", check.retcode,
         " balance=", DoubleToString(check.balance, 2),
         " equity=", DoubleToString(check.equity, 2),
         " margin=", DoubleToString(check.margin, 2),
         " margin_free=", DoubleToString(check.margin_free, 2),
         " margin_level=", DoubleToString(check.margin_level, 2),
         " comment=", check.comment,
         " last_error=", last_error);

   if(!ok)
      return false;

   if(check.retcode != TRADE_RETCODE_DONE &&
      check.retcode != TRADE_RETCODE_PLACED)
   {
      Print("ORDER_CHECK_BLOCK",
            " retcode=", check.retcode,
            " comment=", check.comment);
      return false;
   }

   return true;
}

OrderCheckの戻り値とMqlTradeCheckResultのretcodeは、どちらも確認します。関数呼び出し自体の成否と、取引チェック結果は分けて考えると、ログの意味が整理しやすくなります。

MqlTradeCheckResultで見る項目

MqlTradeCheckResultには、注文前チェックの結果が入ります。特に確認したいのは、retcode、margin、margin_free、margin_level、commentです。

項目意味確認目的
retcodeチェック結果コード注文前チェックの結果を判定する
balance残高口座状態の確認
equity有効証拠金含み損益込みの状態を確認
margin必要証拠金発注後に必要な証拠金を確認
margin_free余剰証拠金発注後の余力を確認
margin_level証拠金維持率発注後の余力確認
commentサーバー側コメント拒否理由や補足情報を確認

retcodeだけでなく、commentもログに出してください。retcodeだけでは原因が分かりにくい場合でも、commentとrequest内容を合わせて見ると、ロット、証拠金、価格、StopLevel、取引制限のどれが原因か判断しやすくなります。

retcodeをログで分類する

OrderCheckやOrderSendの結果をログで見る時は、retcodeを単なる数値として出すだけでなく、分類しておくと確認しやすくなります。

分類見方確認すること
成功系注文可能または注文受付OrderSendへ進むか、結果を確認する
証拠金系資金不足、必要証拠金不足ロット、余剰証拠金、追加ポジション余力を確認する
ロット系volume不正、範囲外、step不一致SYMBOL_VOLUME_MIN / MAX / STEPを確認する
価格系価格不正、requote、価格変動Bid / Ask、digits、deviation、tickを確認する
Stop系invalid stops、距離不足StopLevel、FreezeLevel、SL / TP方向を確認する
取引制限系市場クローズ、取引不可、銘柄制限取引時間、SYMBOL_TRADE_MODE、セッションを確認する

retcodeの意味を本文やログで分類しておくと、注文失敗時に「何を直すべきか」が分かりやすくなります。たとえば、証拠金不足ならロットや余剰証拠金、invalid stopsならSL/TP距離、価格系ならBid / Askやdeviationを確認します。

OrderCheckが通ってもOrderSendが失敗する理由

OrderCheckが通った場合でも、OrderSendやCTradeの注文が必ず成功するわけではありません。

OrderCheckからOrderSendまでの間に価格が変わることがあります。また、サーバー側の約定方式、type_filling、スプレッド拡大、取引時間、FreezeLevel、通信状態、ブローカー側制約により、実際の注文が失敗する場合があります。

原因起きること確認方法
価格変動OrderCheck時の価格とOrderSend時の価格が変わるcheck_price、send_price、Bid / Askをログに残す
スプレッド拡大発注直前に条件が悪化するspreadをOrderCheck前後で確認する
type_filling不一致銘柄が許可しない約定方式を指定するSYMBOL_FILLING_MODEとrequest.type_fillingを確認する
StopLevel変化SL/TP距離が足りなくなるStopLevelと現在価格を再確認する
取引時間外チェック時点と送信時点で取引可否が変わるセッション、サーバー時間、銘柄取引状態を確認する
通信・サーバー応答OrderSend自体が失敗するGetLastError、result.retcode、commentを確認する

そのため、OrderCheckの結果だけで完了扱いにせず、OrderSendまたはCTradeの結果も必ずログに残します。発注前チェックログと発注結果ログを分けておくことで、どの段階で失敗したのかを判断できます。

OrderSend後の結果も確認する

OrderCheck後にOrderSendを実行した場合は、MqlTradeResultの内容を確認します。

bool SendCheckedOrder(MqlTradeRequest &request)
{
   if(!CheckTradeRequest(request))
      return false;

   MqlTradeResult result;
   ZeroMemory(result);

   ResetLastError();

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

   Print("ORDER_SEND",
         " sent=", sent ? "Y" : "N",
         " retcode=", result.retcode,
         " order=", result.order,
         " deal=", result.deal,
         " volume=", DoubleToString(result.volume, 2),
         " price=", DoubleToString(result.price, (int)SymbolInfoInteger(request.symbol, SYMBOL_DIGITS)),
         " comment=", result.comment,
         " last_error=", last_error);

   if(!sent)
      return false;

   return true;
}

OrderCheckとOrderSendは、別の段階としてログに出します。OrderCheckで止まったのか、OrderSendで止まったのか、OrderSendは成功したが約定内容が想定と違うのかを分けることが重要です。

invalid stopsが出る時の確認順序

invalid stopsが出る時は、SL/TPの距離だけでなく、方向、価格、丸め、StopLevel、FreezeLevelを順番に確認します。

順番確認項目確認内容
1注文方向BUYかSELLかを確認する
2基準価格BUYはAsk、SELLはBidを使っているか
3SL / TP方向BUYのSLは下、TPは上。SELLのSLは上、TPは下
4StopLevel現在価格から必要距離を満たしているか
5FreezeLevel変更処理時に制限範囲へ入っていないか
6digits / tick size価格丸めが銘柄仕様に合っているか
7ログentry、sl、tp、distance、min_distanceを確認する

invalid stopsは、SL/TPの距離だけを広げれば解決するとは限りません。価格の基準や方向を間違えている場合、距離を広げても解決しないことがあります。

よくある不具合と確認順序

症状主な原因候補確認するログ
ロット不正volume min / max / stepに合っていないLOT_CHECK
証拠金不足必要証拠金が余剰証拠金を超えているMARGIN_CHECK / ORDER_CHECK
invalid stopsSL/TP方向、StopLevel、価格丸めの不備STOPS_CHECK
OrderCheck失敗request内容や取引条件の不備ORDER_CHECK
OrderSend失敗価格変動、type_filling、取引制限、通信状態ORDER_SEND
CTradeで失敗CTradeのResultRetcode確認不足CTRADE_RESULT
Magicが違うrequest.magicやCTradeのMagic設定漏れMAGIC_SET

発注失敗の調査では、いきなりOrderSendのretcodeだけを見るのではなく、ロット、価格、SL/TP、証拠金、OrderCheck、OrderSendの順にログを確認すると、原因を絞り込みやすくなります。

CTradeを使う場合の注意点

CTradeを使う場合でも、OrderCheck相当の発注前チェックは必要です。

CTradeは注文処理を簡潔に書ける一方で、内部で作られるリクエスト内容を十分に意識しないまま使うと、ロット、SL/TP、Magic Number、deviation、type_fillingの確認が不足する場合があります。

CTradeで確認する項目確認方法注意点
Magic NumberSetExpertMagicNumber()発注前に意図したMagicを設定する
deviationSetDeviationInPoints()価格変動許容範囲を確認する
type_filling銘柄仕様に合わせる約定方式不一致に注意する
ResultRetcodeResultRetcode()注文結果を必ず確認する
ResultCommentResultComment()失敗理由の確認に使う

CTradeを使う場合も、発注前にSymbolInfo、ロット、StopLevel、証拠金を確認し、発注後にResultRetcode、ResultOrder、ResultDeal、ResultCommentを確認してください。

ログ設計の基本

OrderCheck関連のログは、発注失敗の原因を切り分けるために重要です。

ログを出す時は、単に「OrderCheck failed」とだけ出すのではなく、どの値で、どの段階で、どの理由で止まったのかを分けて記録します。

ログ名主な内容目的
SYMBOL_SPECdigits、point、volume min / max / step、StopLevel銘柄仕様の確認
LOT_CHECKraw lot、normalized lot、min、max、stepロット不正の切り分け
PRICE_CHECKBid、Ask、entry price、digits価格基準の確認
STOPS_CHECKentry、SL、TP、distance、StopLevelinvalid stopsの切り分け
MARGIN_CHECKrequired margin、free margin、volume証拠金不足の確認
REQUEST_BUILDrequestへ入れた値OrderCheck前の内容確認
ORDER_CHECKcheck.retcode、margin、comment発注前チェック結果の確認
ORDER_SENDresult.retcode、order、deal、comment実際の注文結果の確認

ログ名を固定しておくと、Expertsログから検索しやすくなります。たとえば、invalid stopsを調べる場合はSTOPS_CHECK、証拠金不足を調べる場合はMARGIN_CHECK、OrderSendの失敗を調べる場合はORDER_SENDを確認します。

発注前チェックを関数化する時の考え方

OrderCheck周辺の処理は、1つの大きな関数にまとめすぎると保守しにくくなります。

実務では、銘柄仕様確認、ロット補正、価格取得、SL/TP確認、証拠金確認、request作成、OrderCheck、OrderSendを分けておくと、後からログや条件を追加しやすくなります。

責務関数例戻り値の考え方
銘柄仕様取得LoadSymbolSpec()取得成功 / 失敗、spec構造体
ロット補正NormalizeVolumeByStep()補正済みロット、不正時は0
価格取得GetOrderPrice()BUY / SELLに応じた価格
SL/TP確認CheckStopsDistance()距離OK / NG、理由ログ
証拠金確認CheckRequiredMargin()余力OK / NG、必要証拠金ログ
request作成BuildTradeRequest()MqlTradeRequestへ値を設定
OrderCheckCheckTradeRequest()発注前チェックOK / NG
OrderSendSendCheckedOrder()送信結果OK / NG

責務を分けると、OrderCheckで止まったのか、ロット補正で止まったのか、StopLevelで止まったのかをログから判断しやすくなります。また、将来CTrade版、MqlTradeRequest版、コピーEA版、ナンピンEA版へ展開する時も、部品を再利用しやすくなります。

バックテストで確認すること

OrderCheck関連の実装は、バックテストでも確認できます。ただし、Strategy Testerの条件や銘柄仕様によって、実運用と完全に同じ結果になるとは限りません。

バックテストでは、OrderCheckの成否だけでなく、ロット、証拠金、StopLevel、スプレッド、OrderSend結果をログで確認します。

確認項目見る内容確認場所
銘柄仕様volume min / max / step、StopLevel、digitsExpertsログ
ロット補正計算ロットと発注ロットの差LOT_CHECK
証拠金必要証拠金、余剰証拠金MARGIN_CHECK / ORDER_CHECK
SL/TP距離entry、SL、TP、StopLevelSTOPS_CHECK
OrderCheckretcode、margin、commentORDER_CHECK
OrderSendresult.retcode、order、dealORDER_SEND
検証条件銘柄、時間足、期間、スプレッド、setファイルテスト条件メモ

バックテストでOrderCheck関連ログを確認する時は、成功時ログを出しすぎるとログが膨大になります。必要に応じて、初回のみ、失敗時のみ、一定間隔のみ、またはsummary形式で出力するなど、検証目的に合わせて調整してください。

開発依頼前に整理したい情報

EAの発注前チェックやOrderCheck周辺の改修を相談する場合は、事前に必要な情報を整理しておくと、仕様の確認がスムーズになります。

整理項目記入例確認理由
対象EA通常EA、ナンピンEA、コピーEA、半裁量EA発注前チェックの範囲が変わるため
対象銘柄USDJPY、EURUSD、XAUUSDなどvolume stepやStopLevelが銘柄ごとに異なるため
ロット計算方式固定ロット、複利、倍率、コピー倍率ロット補正の仕様が変わるため
SL / TP設定固定pips、ATR、内部決済、SLなしなどStopLevel確認の必要範囲が変わるため
OrderCheckの扱い発注前に必ず確認、失敗時は発注停止安全側の停止条件を決めるため
OrderCalcMarginの扱い必要証拠金を事前ログ化証拠金不足の切り分けに使うため
ログ項目LOT_CHECK、STOPS_CHECK、ORDER_CHECKなど問い合わせ時に原因を追うため
OrderSend後の確認retcode、order、deal、comment実際の発注結果を確認するため

注文失敗の調査では、EA設定、setファイル、銘柄、時間足、発注方向、ロット、SL/TP、Expertsログ、OrderCheckログ、OrderSendログを合わせて確認してください。口座番号、認証情報、個人情報、APIキーなどは共有しないようにしてください。

実務チェックリスト

  • OrderCheckを呼ぶ前に、SymbolInfoで銘柄仕様を確認した
  • 最小ロット、最大ロット、volume stepを確認した
  • 計算ロットをvolume stepへ丸めた
  • BUYはAsk、SELLはBidを基準に価格を設定した
  • digits、point、tick sizeを考慮して価格を整えた
  • StopLevelを確認し、SL / TP距離が不足していないか確認した
  • FreezeLevelが関係する変更処理では、制限範囲を確認した
  • OrderCalcMarginで必要証拠金を確認した
  • MqlTradeRequestへ入れるvolume、price、sl、tp、magic、commentを確認した
  • OrderCheckのretcode、margin、margin_free、commentをログに出した
  • OrderCheckが通った後も、OrderSendまたはCTradeの結果を確認した
  • OrderSend結果のretcode、order、deal、commentをログに出した
  • invalid stopsが出る時は、方向、距離、価格丸め、StopLevelを順番に確認した
  • バックテストでは、最終損益だけでなくExpertsログも確認した

よくある質問

OrderCheckだけで証拠金不足を完全に防げますか?

OrderCheckは発注前チェックに有効ですが、実際の注文成功を保証するものではありません。価格変動、スプレッド拡大、取引制限、サーバー応答などにより、OrderCheck後のOrderSendで失敗する場合があります。証拠金確認ではOrderCalcMargin、OrderCheck、OrderSend結果を分けて確認してください。

OrderCalcMarginとOrderCheckはどちらを使えばよいですか?

証拠金だけを事前に見たい場合はOrderCalcMarginが扱いやすいです。MqlTradeRequest全体を確認したい場合はOrderCheckを使います。実務では、OrderCalcMarginで必要証拠金を確認し、ロットやSL/TPを整えた後にOrderCheckを行う流れが分かりやすいです。

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

SL/TPの方向、BUY / SELLの基準価格、StopLevel、FreezeLevel、digits、point、tick size、価格丸めを確認します。単にSL/TP幅を広げるだけではなく、BUYのSLは下側、SELLのSLは上側という方向が正しいかも確認してください。

ロット不正はどこで確認しますか?

SymbolInfoDoubleでSYMBOL_VOLUME_MIN、SYMBOL_VOLUME_MAX、SYMBOL_VOLUME_STEPを取得し、発注ロットが範囲内でstepに合っているか確認します。固定ロット、複利ロット、コピー倍率、ナンピン倍率を使う場合は、最終的に発注するロットをログに出してください。

OrderCheckが通ったのにOrderSendで失敗するのはなぜですか?

OrderCheckからOrderSendまでの間に価格やスプレッドが変化することがあります。また、type_filling、取引時間、サーバー側制約、FreezeLevel、通信状態などで失敗する場合もあります。OrderCheckログとOrderSendログを分けて確認してください。

関連ページ

関連テーマ確認ページ確認できること
OrderCheckの基本MQL5 OrderCheckの使い方OrderCheckの基本構文とMqlTradeCheckResultの確認
注文構造MQL5注文関数・取引構造体辞典OrderSend、MqlTradeRequest、MqlTradeResultの整理
ロット・証拠金MQL5ロット・証拠金・銘柄仕様完全ガイドロット、証拠金、銘柄仕様、volume stepの確認
CTradeMQL5標準ライブラリ・CTrade完全ガイドCTradeでの注文、決済、ResultRetcode確認
注文・ポジション・履歴MQL5注文・ポジション・履歴管理完全ガイド注文、ポジション、約定履歴の確認
ログ設計MQL5デバッグ・ログファースト開発完全ガイド発注失敗やretcode確認のためのログ設計
バックテストMT5ストラテジーテスター・最適化完全ガイドStrategy Testerでの検証条件とログ確認
EA自作前確認自動売買EAを自作する前に確認することEA開発前に整理する仕様と検証項目
ログ確認EAのログを問い合わせ前に確認する方法問い合わせ前にExpertsログで確認する項目
開発・改修相談開発・改修の相談ページOrderCheckや発注前チェックを含むEA開発相談前の整理

まとめ

OrderCheckは、MQL5でEAの注文リクエストを送信する前に、証拠金やリクエスト内容を確認するための重要な関数です。

ただし、OrderCheckだけで発注前チェックが完了するわけではありません。実務では、SymbolInfoによる銘柄仕様確認、volume min / max / stepによるロット確認、BUY / SELL価格の確認、StopLevelとFreezeLevelの確認、OrderCalcMarginによる証拠金確認、MqlTradeRequestの内容確認、OrderCheck、OrderSend結果確認を分けて整理します。

ロット不正、証拠金不足、invalid stops、type_filling不一致、価格変動、OrderSend失敗は、それぞれ確認する場所が異なります。ログでは、LOT_CHECK、MARGIN_CHECK、STOPS_CHECK、REQUEST_BUILD、ORDER_CHECK、ORDER_SENDのように段階を分けると、原因を追いやすくなります。

EA開発や改修では、OrderCheckを単独の関数として扱うのではなく、発注前チェック全体の中に組み込み、OrderSendやCTradeの結果まで含めて確認してください。これにより、発注失敗時の原因調査、バックテスト確認、問い合わせ対応を整理しやすくなります。

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