MQL5 OrderCheckの使い方|注文前チェック・retcode・証拠金確認
MQL5でEAから注文を送る前には、OrderSendやCTradeだけを見るのではなく、注文リクエストが通る可能性があるかを事前に確認することが重要です。ロット、証拠金、SL/TP距離、銘柄仕様、取引可能状態などに問題があると、シグナルが出ていても注文は失敗します。
OrderCheckは、MqlTradeRequestで作成した注文リクエストについて、注文前に証拠金やリクエスト内容を確認するための関数です。OrderSendを実行する前にOrderCheckを挟むことで、証拠金不足、ロット不正、SL/TP距離不正、銘柄仕様との不一致などを早い段階で原因を確認しやすくなります。
この記事では、MQL5のOrderCheckの役割、MqlTradeRequestとMqlTradeCheckResultの見方、OrderSend前に確認すべき項目、StopLevel、FreezeLevel、VolumeStep、証拠金、retcode、ログ設計、EA開発時の発注前チェック構造を整理します。
なお、この記事はMT5 / MQL5の注文前チェック、EA開発、ログ確認、発注失敗の原因確認を目的とした技術記事です。特定の売買判断、利益、勝率、損失回避、推奨ロット、推奨銘柄を案内するものではありません。
- この記事で確認すること
- OrderCheckとは
- OrderCheckとOrderSendの違い
- MqlTradeRequestで確認する項目
- MqlTradeCheckResultで確認する項目
- OrderCheckの基本コード例
- OrderCheck前にロットを確認する
- StopLevelとFreezeLevelを確認する
- 証拠金を確認する
- retcodeとcommentをログに残す
- OrderCheck後にOrderSendを実行する時の注意
- よくあるOrderCheck失敗の原因
- SymbolInfoと組み合わせて確認する
- 発注前チェックを関数化する
- EAが注文できない時の原因確認
- バックテストでOrderCheckを確認する
- OrderCheck利用時の実務チェック表
- OrderCheckをどこに置くか
- OrderCheckのログ設計
- OrderCheckで確認しきれないこと
- CTradeを使う場合のOrderCheckの考え方
- OrderCalcMarginとの使い分け
- よくあるretcodeの原因確認
- OrderCheck記事としての役割分担
- よくある質問
- 関連ページ
- あわせて確認したいページ
- まとめ
- お問い合わせはEAFC公式LINEへ
この記事で確認すること
- OrderCheckの役割
- OrderCheckとOrderSendの違い
- MqlTradeRequestで確認する項目
- MqlTradeCheckResultで確認する項目
- ロット、証拠金、SL/TP距離、StopLevel、FreezeLevelの確認
- VolumeStep、最小ロット、最大ロットの確認
- retcodeとcommentの読み方
- OrderCheck後にOrderSendを実行する時の注意点
- 注文前チェックのログ設計
- EAが注文できない時の原因確認
OrderCheckとは
OrderCheckは、MqlTradeRequestで作成した注文リクエストを、実際にOrderSendで送信する前に確認するための関数です。注文が成立することを保証する関数ではありませんが、証拠金やリクエスト内容に明らかな問題がないかを事前に確認できます。
EA開発では、シグナルが出たらすぐにOrderSendを実行するのではなく、発注前チェックを挟む設計が重要です。OrderCheckを使うことで、注文失敗時の原因を「シグナル不成立」「フィルター停止」「注文前チェックNG」「OrderSend失敗」に分けやすくなります。
ただし、OrderCheckが問題なしでも、その後の価格変動、スプレッド変化、サーバー状態、約定方式、取引時間の変化によってOrderSendが失敗することはあります。OrderCheckは、OrderSendの代わりではなく、OrderSend前の確認工程として扱います。
| 項目 | 内容 | 注意点 |
|---|---|---|
| OrderCheck | 注文リクエストを事前確認する関数です。 | 注文成功を保証するものではありません。 |
| OrderSend | 実際に注文リクエストを送信する関数です。 | retcodeやGetLastErrorで結果を確認します。 |
| MqlTradeRequest | 注文方向、銘柄、ロット、価格、SL/TPなどの要求内容です。 | OrderCheckとOrderSendの両方で重要です。 |
| MqlTradeCheckResult | OrderCheckの確認結果を受け取る構造体です。 | retcode、margin、commentなどを確認します。 |
| MqlTradeResult | OrderSendの送信結果を受け取る構造体です。 | OrderCheck結果とは別に確認します。 |
OrderCheckとOrderSendの違い
OrderCheckとOrderSendは、どちらも注文処理に関係しますが、役割が異なります。OrderCheckは注文前の確認であり、OrderSendは実際の注文送信です。OrderCheckで問題がない場合でも、OrderSend時点で価格や環境が変われば、注文が拒否されることがあります。
EAが注文できない時に、OrderSendの結果だけを見ると、注文前の条件不備と注文送信後の失敗を混同しやすくなります。OrderCheckを使うと、発注前にどの条件で問題が出ているのかを確認しやすくなります。
| 処理 | 役割 | 見るべき結果 |
|---|---|---|
| シグナル判定 | BUY / SELL候補を判断します。 | signal、条件値、判定足、見送り理由。 |
| フィルター | スプレッド、時間帯、最大ポジション数などを確認します。 | filter_block、現在値、許容値。 |
| OrderCheck | 注文リクエストと証拠金状態を事前確認します。 | check.retcode、margin、comment。 |
| OrderSend | 注文リクエストを取引サーバーへ送信します。 | result.retcode、order、deal、comment。 |
| 取引イベント確認 | 注文、約定、履歴、ポジション変化を確認します。 | OnTradeTransaction、History、Position。 |
MqlTradeRequestで確認する項目
OrderCheckを使うには、まずMqlTradeRequestに注文要求を設定します。ここに入れる値が不正であれば、OrderCheckの時点で失敗したり、OrderSend時点で拒否されたりします。
特に確認すべきなのは、action、symbol、volume、type、price、sl、tp、deviation、magic、type_fillingです。これらの値は銘柄仕様、口座仕様、ブローカー仕様に影響されます。
| フィールド | 内容 | 確認ポイント |
|---|---|---|
action | 取引アクションです。 | 成行、指値、決済など目的に合っているか確認します。 |
symbol | 注文対象の銘柄です。 | チャート銘柄と対象銘柄が一致しているか確認します。 |
volume | 注文ロットです。 | 最小ロット、最大ロット、VolumeStepに合っているか確認します。 |
type | BUY、SELLなどの注文種別です。 | シグナル方向と注文方向が一致しているか確認します。 |
price | 注文価格です。 | BUYはAsk、SELLはBidを使う場面が基本です。 |
sl | 損切り価格です。 | StopLevelやFreezeLevelとの距離を確認します。 |
tp | 利確価格です。 | 銘柄のdigits、point、StopLevelを考慮します。 |
magic | EA識別用のMagic Numberです。 | 他EAや手動ポジションと混同しないようにします。 |
type_filling | 約定方式に関する指定です。 | 銘柄やブローカーで許可される方式を確認します。 |
MqlTradeCheckResultで確認する項目
OrderCheckの結果は、MqlTradeCheckResultで受け取ります。ここでは、retcode、balance、equity、profit、margin、margin_free、margin_level、commentなどを確認できます。
実務では、check.retcodeとcheck.commentだけでなく、必要証拠金や余剰証拠金もログに残すと原因追跡がしやすくなります。注文前チェックで止める場合は、「なぜ止めたのか」をログに出してください。
| フィールド | 内容 | ログで確認したいこと |
|---|---|---|
retcode | OrderCheckの確認結果コードです。 | チェックが通ったか、どの理由で失敗したか。 |
balance | 残高情報です。 | 検証時の口座状態確認に使います。 |
equity | 有効証拠金です。 | 含み損益込みの状態を確認します。 |
profit | 見込み損益に関係する値です。 | 注文種別や口座状態との整合を確認します。 |
margin | 必要証拠金です。 | 注文予定ロットで必要な証拠金を確認します。 |
margin_free | 余剰証拠金です。 | 証拠金不足を確認する時に重要です。 |
margin_level | 証拠金維持率に関係する値です。 | リスク確認や停止条件と組み合わせます。 |
comment | 確認結果のコメントです。 | retcodeと併せてログに残します。 |
OrderCheckの基本コード例
以下は、OrderCheckの流れを確認するための簡略例です。実際のEAでは、この前にシグナル判定、フィルター、ロット補正、SL/TP距離確認、最大ポジション数確認などを行います。
bool CheckBuyOrder(double lots)
{
MqlTradeRequest request;
MqlTradeCheckResult check;
ZeroMemory(request);
ZeroMemory(check);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lots;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.magic = 123456;
bool ok = OrderCheck(request, check);
PrintFormat("ORDER_CHECK ok=%s retcode=%d margin=%.2f free=%.2f level=%.2f comment=%s",
ok ? "true" : "false",
check.retcode,
check.margin,
check.margin_free,
check.margin_level,
check.comment);
return ok;
}このコードはOrderCheckの基本的な流れを示すものです。実際には、OrderCheckの戻り値だけでなく、check.retcode、check.comment、証拠金、ロット、価格、SL/TP距離を確認します。また、OrderCheckが通った後でも、OrderSend時点で失敗する可能性があるため、OrderSend側の結果確認も必要です。
OrderCheck前にロットを確認する
OrderCheckを行う前に、注文ロットが銘柄仕様に合っているか確認します。MQL5では、銘柄ごとに最小ロット、最大ロット、ロットステップが異なります。たとえば、0.01単位で注文できる銘柄もあれば、0.10単位でしか注文できない銘柄もあります。
ロットがVolumeStepに合っていない場合、OrderCheckやOrderSendで失敗することがあります。EA側でロット計算を行う場合は、計算後のロットをそのまま使うのではなく、銘柄仕様に合わせて丸める処理が必要です。
| 確認項目 | MQL5で見る値 | 注意点 |
|---|---|---|
| 最小ロット | SYMBOL_VOLUME_MIN | これ未満の注文は不正になります。 |
| 最大ロット | SYMBOL_VOLUME_MAX | これを超える注文は不正になります。 |
| ロットステップ | SYMBOL_VOLUME_STEP | ステップに合わないロットは失敗要因になります。 |
| 要求ロット | EA側で計算したロット | 計算後に銘柄仕様へ合わせます。 |
| 丸め後ロット | 発注に使うロット | ログに残すと原因追跡しやすくなります。 |
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の仕様として決めておく必要があります。
StopLevelとFreezeLevelを確認する
SL/TPを設定するEAでは、StopLevelとFreezeLevelを確認する必要があります。SLやTPが現在価格に近すぎる場合、注文が拒否されたり、変更に失敗したりすることがあります。
OrderCheckを使う前に、SL/TPの価格が銘柄のdigits、point、StopLevel、FreezeLevelに合っているかを確認してください。特にXAUUSDや指数など、pointやdigitsの扱いを間違えやすい銘柄では注意が必要です。
| 項目 | 意味 | 確認ポイント |
|---|---|---|
| StopLevel | SL/TPや指値を置く時に必要な最小距離に関係します。 | SL/TPが近すぎないか確認します。 |
| FreezeLevel | 注文変更や決済操作が制限される距離に関係します。 | 変更処理やトレーリングで影響します。 |
| digits | 銘柄の小数桁です。 | 価格丸めに使います。 |
| point | 最小価格単位です。 | 距離計算に使います。 |
| SL距離 | 現在価格からSLまでの距離です。 | StopLevelを満たすか確認します。 |
| TP距離 | 現在価格からTPまでの距離です。 | StopLevelを満たすか確認します。 |
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の段階だけではなく、ポジション保有後の変更処理で表面化することがあります。そのため、発注前チェックと保有後の変更チェックを分けてログ化してください。
証拠金を確認する
OrderCheckでは、注文予定ロットに対して必要証拠金がどの程度か、余剰証拠金が十分かを確認できます。証拠金不足は、EAが注文できない代表的な原因の1つです。
EAでロットを自動計算する場合、残高やリスク率だけでロットを決めると、実際の銘柄仕様やレバレッジ条件に合わないことがあります。OrderCheckの結果として必要証拠金と余剰証拠金をログに残しておくと、注文失敗の原因確認に役立ちます。
PrintFormat("MARGIN_CHECK retcode=%d margin=%.2f margin_free=%.2f margin_level=%.2f comment=%s",
check.retcode,
check.margin,
check.margin_free,
check.margin_level,
check.comment);証拠金確認では、単に「注文できない」と出すのではなく、必要証拠金、余剰証拠金、ロット、銘柄、口座通貨、retcodeをセットで確認できるようにします。
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結果も別に確認してください。
retcodeとcommentをログに残す
OrderCheckの結果を確認する時は、retcodeとcommentを必ずログに残します。retcodeは確認結果を判断するための重要な値です。commentには、ブローカーやサーバー側の補足情報が含まれることがあります。
OrderCheckのログが「OK」「NG」だけでは、あとから原因を追えません。どのリクエストを確認したのか、どのretcodeが返ったのか、証拠金やロットがどうだったのかを残してください。
| ログ項目 | 残す理由 | 例 |
|---|---|---|
| symbol | 対象銘柄を特定するため。 | symbol=XAUUSD |
| type | BUY / SELLを確認するため。 | type=BUY |
| volume | 注文ロットを確認するため。 | volume=0.10 |
| price | 注文予定価格を確認するため。 | price=2350.12 |
| sl / tp | SL/TP距離を確認するため。 | sl=2345.12 tp=2360.12 |
| retcode | OrderCheck結果を確認するため。 | retcode=10009 |
| margin | 必要証拠金を確認するため。 | margin=1250.00 |
| comment | 補足情報を確認するため。 | comment=Request checked |
OrderCheck後にOrderSendを実行する時の注意
OrderCheckが通った場合でも、すぐに安心してはいけません。OrderCheckとOrderSendの間に価格やスプレッドが変わることがあります。特に短期売買やスプレッドが広がりやすい時間帯では、OrderCheck時点では問題がなくても、OrderSend時点で失敗することがあります。
OrderCheck後にOrderSendを実行する場合は、OrderSend側でもresult.retcode、GetLastError、注文番号、Deal番号、commentを確認します。OrderCheckのretcodeとOrderSendのretcodeを分けてログに残すと、どの段階で問題が起きたかを原因を確認しやすくなります。
bool check_ok = OrderCheck(request, check);
PrintFormat("ORDER_CHECK ok=%s retcode=%d margin=%.2f free=%.2f comment=%s",
check_ok ? "true" : "false",
check.retcode,
check.margin,
check.margin_free,
check.comment);
if(!check_ok)
return false;
MqlTradeResult result;
ZeroMemory(result);
bool send_ok = OrderSend(request, result);
PrintFormat("ORDER_SEND ok=%s retcode=%d order=%I64u deal=%I64u last_error=%d comment=%s",
send_ok ? "true" : "false",
result.retcode,
result.order,
result.deal,
GetLastError(),
result.comment);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は成功したが約定内容が想定と違うのかを分けることが重要です。
よくあるOrderCheck失敗の原因
OrderCheckで失敗する場合、リクエスト内容、ロット、証拠金、価格、SL/TP、銘柄仕様、取引可否などを確認します。原因を1つに決めつけず、項目ごとにログを確認してください。
| 症状 | 確認項目 | 対応方針 |
|---|---|---|
| ロット不正 | volume min / max / step。 | 銘柄仕様に合わせてロットを補正します。 |
| 証拠金不足 | margin、margin_free、volume。 | ロットを下げる、証拠金条件を見直す。 |
| SL/TP不正 | StopLevel、FreezeLevel、digits、point。 | SL/TP距離を広げる、価格丸めを確認する。 |
| 価格不正 | Bid / Ask、注文方向、現在価格。 | BUYとSELLで使う価格を確認する。 |
| 取引不可 | trade mode、口座状態、取引時間。 | 銘柄や口座の取引可否を確認する。 |
| 注文種別不一致 | action、type、type_filling。 | 銘柄で許可される注文方式を確認する。 |
| Magic管理不足 | magic、symbol、position count。 | 対象EAのポジションだけを見る。 |
invalid stopsが出る時の確認順序
invalid stopsが出る時は、SL/TPの距離だけでなく、方向、価格、丸め、StopLevel、FreezeLevelを順番に確認します。
| 順番 | 確認項目 | 確認内容 |
|---|---|---|
| 1 | 注文方向 | BUYかSELLかを確認する |
| 2 | 基準価格 | BUYはAsk、SELLはBidを使っているか |
| 3 | SL / TP方向 | BUYのSLは下、TPは上。SELLのSLは上、TPは下 |
| 4 | StopLevel | 現在価格から必要距離を満たしているか |
| 5 | FreezeLevel | 変更処理時に制限範囲へ入っていないか |
| 6 | digits / tick size | 価格丸めが銘柄仕様に合っているか |
| 7 | ログ | entry、sl、tp、distance、min_distanceを確認する |
invalid stopsは、SL/TPの距離だけを広げれば解決するとは限りません。価格の基準や方向を間違えている場合、距離を広げても解決しないことがあります。
SymbolInfoと組み合わせて確認する
OrderCheckだけでは、EA側で事前に確認すべきすべての情報を整理できるわけではありません。ロット、StopLevel、FreezeLevel、digits、point、trade modeなどは、SymbolInfoDoubleやSymbolInfoIntegerを使って取得し、OrderCheck前に確認しておくと安全です。
特に複数銘柄EAや、XAUUSD、指数、仮想通貨CFDなど銘柄仕様が異なる環境では、symbolごとに仕様を取得してログに出すことが重要です。固定値で判断すると、別銘柄で注文失敗する可能性があります。
| 確認値 | 用途 | ログに残す理由 |
|---|---|---|
SYMBOL_VOLUME_MIN | 最小ロット確認。 | ロット不正を防ぐため。 |
SYMBOL_VOLUME_MAX | 最大ロット確認。 | 過大ロットを防ぐため。 |
SYMBOL_VOLUME_STEP | ロットステップ確認。 | 端数ロットによる失敗を防ぐため。 |
SYMBOL_TRADE_STOPS_LEVEL | StopLevel確認。 | SL/TP距離不正を防ぐため。 |
SYMBOL_TRADE_FREEZE_LEVEL | FreezeLevel確認。 | 注文変更や決済補助で確認するため。 |
SYMBOL_DIGITS | 小数桁確認。 | 価格丸めに使うため。 |
SYMBOL_POINT | point確認。 | 距離計算に使うため。 |
SYMBOL_TRADE_MODE | 取引可否確認。 | 銘柄が取引可能か確認するため。 |
BUY / SELL価格の基準を確認する
OrderCheckやOrderCalcMarginへ渡す価格は、注文方向に合わせて確認します。
一般的に、BUY注文ではAsk、SELL注文ではBidを基準にします。価格の取り違えは、発注前チェックやSL/TP距離確認の結果に影響します。
| 注文方向 | 基準価格 | 主な確認内容 |
|---|---|---|
| BUY | SYMBOL_ASK | 買い注文の発注価格、SLは下側、TPは上側 |
| SELL | SYMBOL_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で価格関連の失敗が起きた時に原因を追いやすくなります。
発注前チェックを関数化する
EA開発では、OrderCheckをOnTick内に直接書き込むよりも、発注前チェック用の関数として分けると確認しやすくなります。シグナル判定、フィルター、ロット補正、OrderCheck、OrderSendを分けることで、不具合時の原因を追いやすくなります。
たとえば、CanEntry、BuildTradeRequest、CheckTradeRequest、SendTradeRequestのように分けると、各工程のログを整理しやすくなります。OrderCheckで止まった場合はCHECK_FAIL、OrderSendで止まった場合はSEND_FAILとしてログを分けます。
| 関数例 | 役割 | ログ例 |
|---|---|---|
CheckSignal() | BUY / SELL候補を判定します。 | SIGNAL side=BUY reason=MA_CROSS |
CheckEntryFilter() | スプレッドや時間帯を確認します。 | FILTER_BLOCK reason=SPREAD |
NormalizeLots() | 銘柄仕様に合わせてロットを補正します。 | LOT_NORMALIZED raw=0.037 lot=0.03 |
BuildRequest() | MqlTradeRequestを作成します。 | REQUEST_BUILD side=BUY lot=0.10 |
CheckRequest() | OrderCheckを実行します。 | CHECK_OK retcode=10009 |
SendRequest() | OrderSendを実行します。 | SEND_OK retcode=10009 |
EAが注文できない時の原因確認
EAが注文できない時は、OrderCheckだけを疑うのではなく、処理の流れを順番に確認します。シグナルが出ていない、フィルターで止まっている、OrderCheckで止まっている、OrderSendで失敗している、取引サーバー側で拒否されている、というように段階を分けます。
OrderCheckを使っているEAでも、ログが不足していると原因は追えません。各段階で、どの条件で止まったのか、どの値で注文しようとしたのかを残してください。
| 段階 | 確認すること | ログ名の例 |
|---|---|---|
| 起動 | OnInitが成功しているか。 | INIT_OK / INIT_FAIL |
| シグナル | BUY / SELL候補が出ているか。 | SIGNAL_BUY / SIGNAL_NONE |
| フィルター | スプレッドや時間帯で止まっていないか。 | FILTER_BLOCK |
| リクエスト作成 | MqlTradeRequestの値が正しいか。 | REQUEST_BUILD |
| OrderCheck | 注文前チェックが通るか。 | ORDER_CHECK_OK / ORDER_CHECK_FAIL |
| OrderSend | 注文送信が成功するか。 | ORDER_SEND_OK / ORDER_SEND_FAIL |
| 約定確認 | 注文後のDealやPositionを確認する。 | TRADE_TRANSACTION |
バックテストでOrderCheckを確認する
OrderCheckを使うEAは、バックテストでもログを確認します。注文が出ない場合、シグナルが出ていないのか、OrderCheckで止まっているのか、OrderSendで失敗しているのかをログで分けてください。
バックテストでは、銘柄、時間足、期間、スプレッド、setファイル、初期証拠金、モデルを記録します。ロットや証拠金に関係する不具合は、初期証拠金やレバレッジ、銘柄仕様によって結果が変わることがあります。
- EA名とバージョンを記録する
- 使用したsetファイルを保存する
- 銘柄、時間足、期間を記録する
- 初期証拠金とスプレッド条件を記録する
- OrderCheckのretcodeとcommentを確認する
- 必要証拠金と余剰証拠金を確認する
- OrderSendのretcodeも別に確認する
- バックテスト結果を将来成績保証として扱わない
OrderCheck利用時の実務チェック表
- OrderSend前にMqlTradeRequestを正しく作成している
- OrderCheckの戻り値だけでなくcheck.retcodeを確認している
- check.commentをログに残している
- 注文予定ロットがVolumeStepに合っている
- 最小ロット・最大ロットを確認している
- SL/TP距離がStopLevelを満たしている
- FreezeLevelの影響を確認している
- 必要証拠金と余剰証拠金をログに出している
- OrderCheckとOrderSendのretcodeを分けて確認している
- BUYとSELLで価格の扱いを混同していない
- Magic Numberと対象ポジション範囲を確認している
- バックテスト条件とsetファイルを保存している
OrderCheckをどこに置くか
EAの発注処理では、OrderCheckを単独で呼ぶだけではなく、signal判定、filter確認、risk確認、request生成、OrderCheck、OrderSend、結果ログの順に分けて配置すると原因を追いやすくなります。
特に、注文が出ない不具合では「シグナルが出ていない」のか、「スプレッドや時間条件で止まっている」のか、「OrderCheckで止まっている」のか、「OrderSendで拒否されている」のかを分けることが重要です。OrderCheckは、発注処理全体の中ではexecution直前の確認工程として扱います。
| 工程 | 主な確認内容 | OrderCheckとの関係 |
|---|---|---|
| signal | BUY / SELL候補が出ているか | OrderCheckより前の判定です。 |
| filter | スプレッド、時間帯、曜日、最大ポジション数 | 発注を見送る条件を先に確認します。 |
| risk | ロット、最大損失、証拠金、保有数 | request.volumeやSL/TPの前提になります。 |
| request生成 | MqlTradeRequestにaction、symbol、volume、type、price、sl、tpを設定 | OrderCheckに渡す対象を作ります。 |
| OrderCheck | 注文前の証拠金やリクエスト内容を確認 | 発注前チェックの中心です。 |
| OrderSend | 取引サーバーへ注文を送信 | OrderCheck通過後でも結果確認が必要です。 |
| result確認 | retcode、order、deal、comment、GetLastError | OrderCheckとは別にログ化します。 |
OrderCheckを使っても、filterやriskの責務をすべてOrderCheckへ押し込むべきではありません。OrderCheckはMqlTradeRequestの妥当性や証拠金状態を見る工程であり、EA独自の取引禁止条件、時間帯制限、最大ポジション数、外部制御、通知可否などは別工程で確認します。
OrderCheckのログ設計
OrderCheckを使う目的は、注文前に失敗要因を見つけることだけではありません。あとからログで原因を追えるようにすることも重要です。OrderCheckの結果を「OK」「NG」だけで出すと、なぜ止まったのかが分からなくなります。
最低限、symbol、type、volume、price、sl、tp、retcode、margin、margin_free、margin_level、commentを同じログ行または近いログ行に残すと、バックテストや問い合わせ対応で確認しやすくなります。
| ログ項目 | 残す理由 | 例 |
|---|---|---|
| symbol | 対象銘柄を特定するため | symbol=XAUUSD |
| type | BUY / SELL方向を確認するため | type=BUY |
| volume | 注文予定ロットを確認するため | volume=0.10 |
| price | 確認時点の価格を追うため | price=2350.12 |
| sl / tp | StopLevel違反や価格方向ミスを見るため | sl=2347.12 tp=2356.12 |
| retcode | OrderCheckの判定結果を分類するため | check.retcode=... |
| margin | 必要証拠金を確認するため | margin=120.50 |
| margin_free | 余剰証拠金を確認するため | free=8500.00 |
| comment | サーバー側の補足を残すため | comment=... |
ログの粒度をそろえておくと、バックテストで注文が出ない時、リアル運用で注文が失敗した時、setファイル変更後に結果が変わった時に、原因を比較しやすくなります。
OrderCheckで確認しきれないこと
OrderCheckは便利ですが、EAの注文処理に関するすべてを保証するものではありません。OrderCheckが通っても、OrderSend時点で価格が変わる、スプレッドが広がる、取引時間が変わる、サーバー側で拒否されるなどの理由で注文に失敗する場合があります。
そのため、OrderCheckの結果だけで「注文成功」と判断せず、OrderSend後のMqlTradeResult、OnTradeTransaction、ポジション確認、履歴確認まで含めて設計します。
| OrderCheckで分かりやすいこと | OrderCheckだけでは不十分なこと | 追加確認 |
|---|---|---|
| 必要証拠金 | 約定時点の価格変動 | OrderSend結果 |
| ロット不正の一部 | ブローカー側の瞬間的な拒否 | retcodeとcomment |
| SL/TP距離の問題 | 送信直前のスプレッド拡大 | Bid / Ask再取得 |
| リクエスト内容の不整合 | 通信・サーバー応答の問題 | GetLastErrorとJournal |
| 証拠金余力 | 約定後のポジション状態 | PositionSelectと履歴確認 |
OrderCheckは「OrderSend前に確認する工程」として使い、OrderSend後の結果確認と分けてログに残してください。この分離ができていると、発注失敗時に修正すべき場所を特定しやすくなります。
CTradeを使う場合のOrderCheckの考え方
CTradeのBuyやSellを使う場合、内部的には注文リクエストを組み立てて送信します。そのため、CTradeを使っているからといって、発注前チェックが不要になるわけではありません。
CTradeは記述を簡潔にできる一方で、MqlTradeRequestを直接組み立てる場合よりも、発注前の中間状態を自分でログ化しにくいことがあります。重要なEAや検証用EAでは、CTradeの前段でロット、銘柄仕様、SL/TP距離、証拠金、スプレッドを確認しておくと安全です。
| 実装方法 | 特徴 | OrderCheckとの関係 |
|---|---|---|
| CTrade | Buy / Sellなどで簡潔に書ける | 前段で独自チェックを用意すると原因追跡しやすい |
| MqlTradeRequest + OrderSend | request内容を細かく制御できる | OrderCheckと同じrequestを使いやすい |
| 検証用EA | ログや診断を多く出す | OrderCheck結果を詳細に残すとよい |
| 通常利用向けEA | 表示やログ量を抑えることがある | 必要最低限の安全ログは残す |
EAファンクラブでは、OrderCheckを単独の関数説明としてではなく、CTrade、MqlTradeRequest、OrderSend、SymbolInfo、OrderCalcMargin、ログ確認とつながる発注前チェックの一部として扱います。
OrderCalcMarginとの使い分け
必要証拠金を事前に確認したい場合、OrderCheckだけでなくOrderCalcMarginも候補になります。OrderCalcMarginは、指定した注文タイプ、銘柄、ロット、価格に対する必要証拠金を計算するための関数です。
OrderCheckはMqlTradeRequest全体に対する確認であり、OrderCalcMarginは証拠金計算に特化した確認です。EAの設計では、ロット計算段階でOrderCalcMarginを使い、最終的なrequest確認でOrderCheckを使う、という分け方ができます。
| 関数 | 主な用途 | 使う場面 |
|---|---|---|
| OrderCalcMargin | 必要証拠金の概算確認 | ロット計算、証拠金余力確認 |
| OrderCalcProfit | 指定価格差の想定損益確認 | SL/TP幅や想定損益の確認 |
| OrderCheck | 注文リクエスト全体の事前確認 | OrderSend直前のrequest確認 |
| OrderSend | 実際の注文送信 | 発注処理本体 |
OrderCalcMarginとOrderCheckは競合するものではありません。証拠金計算と発注前request確認を分けて使うと、ロット計算の問題と注文リクエストの問題を分離できます。
よくあるretcodeの原因確認
OrderCheckやOrderSendで確認するretcodeは、注文処理の結果を確認するための重要な情報です。retcodeを数値だけで保存すると後から読みづらいため、可能であれば意味が分かるログ名やcommentも合わせて残します。
retcodeの値は環境や取引条件によって異なるため、記事内で特定の値だけを丸暗記するよりも、どの分類の問題かを見分けることが重要です。
| 分類 | 代表的な確認内容 | 次に見る場所 |
|---|---|---|
| ロット不正 | 最小ロット、最大ロット、VolumeStep | SymbolInfoDouble、input、ロット丸め処理 |
| 証拠金不足 | 必要証拠金、余剰証拠金、レバレッジ | OrderCheck、OrderCalcMargin、口座情報 |
| SL/TP不正 | StopLevel、FreezeLevel、価格方向、digits | SymbolInfoInteger、Bid / Ask、SL/TP計算 |
| 取引不可 | 銘柄取引許可、取引時間、口座状態 | SymbolInfo、AccountInfo、Journal |
| 価格変動 | 価格再取得、deviation、スプレッド | OrderSend直前のBid / Askログ |
| サーバー側拒否 | ブローカー条件、type_filling、約定方式 | MqlTradeResult、comment、Journal |
retcodeは、OrderCheckだけでなくOrderSendでも確認します。両方を同じ名前のログにまとめると混同しやすいため、ORDER_CHECK と ORDER_SEND を分けて出すと確認しやすくなります。
OrderCheck記事としての役割分担
このページでは、OrderCheckの基本的な役割、MqlTradeRequest、MqlTradeCheckResult、retcode、comment、OrderSend前確認を中心に整理します。
本記事では、証拠金、ロット、StopLevel、FreezeLevel、OrderCalcMargin、価格丸めまで同じページ内で確認できるように統合しています。あわせて、銘柄仕様、注文・ポジション管理、ログ設計など周辺テーマは、それぞれの専門ページで確認できる構成にしています。
| 確認したい内容 | 見るページ | 役割 |
|---|---|---|
| OrderCheckの基本 | このページ | 関数の役割、request、check result、retcodeの概要 |
| 証拠金・ロット・StopLevel | 証拠金・ロット・StopLevelの確認 | 実務的な発注前チェック |
| 銘柄仕様 | MQL5ロット・証拠金・銘柄仕様完全ガイド | volume step、digits、point、tick valueの確認 |
| CTrade | MQL5標準ライブラリ・CTrade完全ガイド | CTrade利用時の発注処理 |
| 注文結果ログ | MQL5 OrderSend結果ログを実コードで解説 | OrderSend後のretcodeとMqlTradeResult確認 |
OrderCheckの基本と、証拠金・ロット・StopLevel・価格丸めまでを本記事内で連続して確認し、周辺の注文管理やログ設計は専門ページで補完できる構成です。
開発依頼前に整理したい情報
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を使えば注文は必ず成功しますか?
いいえ。OrderCheckは注文前の確認であり、注文成功を保証するものではありません。OrderCheck後に価格、スプレッド、サーバー状態、取引可能状態が変わると、OrderSendで失敗することがあります。
OrderCheckとOrderSendは両方必要ですか?
役割が違います。OrderCheckは注文前チェック、OrderSendは実際の注文送信です。発注失敗の原因を追いやすくするためには、OrderCheckとOrderSendの結果を分けてログに残すのが有効です。
OrderCheckで何をログに出せばよいですか?
symbol、type、volume、price、sl、tp、check.retcode、check.margin、check.margin_free、check.margin_level、check.commentを必要に応じて出します。機密情報や口座情報は出さないようにしてください。
ロット不正はOrderCheckで分かりますか?
OrderCheckで確認できる場合がありますが、EA側でも事前に最小ロット、最大ロット、VolumeStepを確認する方が安全です。計算ロットと丸め後ロットをログに残すと原因追跡がしやすくなります。
invalid stopsが出る場合は何を確認しますか?
SL/TP距離、StopLevel、FreezeLevel、digits、point、BUY/SELL方向ごとの価格を確認します。特にXAUUSDや指数などでは、価格単位の扱いを間違えやすいため注意が必要です。
CTradeを使う場合もOrderCheckは必要ですか?
CTradeを使っていても、発注前チェックの考え方は重要です。CTradeのBuyやSellを呼ぶ前に、ロット、証拠金、SL/TP距離、スプレッド、最大ポジション数を確認すると、注文失敗の原因を追いやすくなります。
関連ページ
OrderCheckの確認を広げる場合は、注文処理、銘柄仕様、ログ、EA設計、バックテストを目的別に確認してください。リンク先は、今回のサイト再編後も残す最終URLだけに整理しています。
| 確認したい内容 | 関連ページ |
|---|---|
| MQL5関数全体の位置づけを確認する | MQL5関数辞典|EA・インジケーター開発で使う主要関数一覧 |
| OrderSend・MqlTradeRequest・MqlTradeResultを確認する | MQL5注文関数・取引構造体辞典|OrderSend・MqlTradeRequest・MqlTradeResultの基本 |
| 注文・ポジション・約定・履歴管理を確認する | MQL5注文・ポジション・履歴管理完全ガイド|OrderSend・Position・Deal・Historyの基本 |
| volume step・証拠金・銘柄仕様を確認する | MQL5ロット・証拠金・銘柄仕様完全ガイド|volume step・tick value・stops levelの確認 |
| ログ確認とデバッグ方法を確認する | MQL5デバッグ・ログファースト開発完全ガイド|Print・Expertsログ・再現条件の整理 |
| EAの責務分離と注文処理設計を確認する | MQL5 EA設計パターン完全ガイド|signal・execution・risk・exitの責務分離 |
| EAを自作する前の設計項目を確認する | 自動売買EAを自作する前に確認すること|ロジック・バックテスト・ログ設計 |
| MQL5開発の基本構造を確認する | MQL5開発入門|MetaEditor・EA・インジケーター・イベント関数・コンパイルエラーの基本 |
| ストラテジーテスターでの確認方法を整理する | MT5ストラテジーテスター・最適化完全ガイド|バックテスト結果を読むための基本 |
| setファイル共有前の確認事項を整理する | MT5 EAのsetファイルを送る前に確認すること|設定・機密情報・ログ整理 |
| 問い合わせ前のExperts・Journalログを整理する | MT5 EAログ完全ガイド|Experts・Journalの見方・問い合わせ前の整理 |
EA・MT5・MQL5 技術辞典|用語・関数・設定を目的別に探す
EAの開発・改修について相談する場合は、開発・改修の相談ページで受付内容を確認できます。
あわせて確認したいページ
今回の確認内容に関連する補足ページです。必要な項目だけ確認してください。
| 確認目的 | 関連ページ |
|---|---|
| 「MQL5 OrderCheck 使い方」の読後に「MQL5エラーコード辞典」を補足確認 | MQL5エラーコード辞典 |
| 「MQL5 OrderCheck 使い方」の読後に「MQL5 ORDER_FILLINGの違い」を補足確認 | MQL5 ORDER_FILLINGの違い |
| 「MQL5 OrderCheck 使い方」の読後に「MQL5 OrderCalcMargin / OrderCalcProfitの使い方」を補足確認 | MQL5 OrderCalcMargin / OrderCalcProfitの使い方 |
まとめ
OrderCheckは、MQL5でOrderSendを実行する前に、注文リクエストや証拠金状態を確認するための重要な関数です。注文成功を保証するものではありませんが、ロット不正、証拠金不足、SL/TP距離不正、銘柄仕様との不一致を早い段階で原因を確認しやすくなります。
OrderCheckを使う時は、MqlTradeRequestの内容、MqlTradeCheckResultのretcode、margin、margin_free、commentをログに残してください。また、OrderCheckが通った後でも、OrderSend側のretcode、GetLastError、order、deal、commentを別に確認する必要があります。
EA開発では、シグナル判定、フィルター、ロット補正、OrderCheck、OrderSend、取引イベント確認を分けることで、不具合時の原因追跡がしやすくなります。バックテストや開発依頼では、setファイル、検証条件、Expertsログ、Journalログもあわせて整理してください。
お問い合わせはEAFC公式LINEへ
EAFCサイト内の記事、商品、導入前確認、設定確認、ログ確認、開発依頼前のご相談など、各種お問い合わせはEAFC公式LINEより受け付けています。
※投資助言、売買指示、利益保証、推奨ロット、推奨銘柄の案内は行っておりません。
口座番号、認証情報、Webhook URL、GAS URL、APIキーなどの機密情報は送信しないでください。
