MQL5 ORDER_FILLINGの違い|FOK・IOC・RETURNと注文エラー確認
MQL5でOrderSendを使う時は、注文種類だけでなく、約定方式も確認する必要があります。
ORDER_FILLINGは、注文数量をどのように約定させるかを指定するための設定です。MqlTradeRequestでは、type_fillingへORDER_FILLING_FOK、ORDER_FILLING_IOC、ORDER_FILLING_RETURNなどを指定します。
EAがOrderSendで失敗する、成行注文が通らない、ブローカーや銘柄によって注文エラーになる、デモ口座では動いたのに別口座で動かない、といった場合は、ORDER_FILLINGとSYMBOL_FILLING_MODEを確認することが重要です。
このページでは、MQL5のORDER_FILLINGの違いを、FOK、IOC、RETURN、MqlTradeRequest.type_filling、SYMBOL_FILLING_MODE、OrderSendエラー確認の観点から整理します。
なお、このページはMQL5開発における技術確認を目的とした内容です。売買判断、推奨エントリー、推奨ロット、利益保証、損失回避保証を行うものではありません。
- ORDER_FILLINGとは何か
- FOK・IOC・RETURNの違い
- MqlTradeRequest.type_fillingで指定する
- ORDER_FILLING_FOKの考え方
- ORDER_FILLING_IOCの考え方
- ORDER_FILLING_RETURNの考え方
- SYMBOL_FILLING_MODEを確認する
- FOK / IOCを判定するhelper例
- 銘柄に合わせてtype_fillingを選ぶ例
- 成行注文と保留注文で分ける
- OrderCheckと組み合わせる
- OrderSend結果ログで確認する
- CTradeを使う場合の注意点
- 注文エラー時に見るポイント
- ログ出力例
- よくある失敗パターン
- 関連ページ
- 注文処理と銘柄仕様をあわせて確認する場合
- 開発依頼前に整理したい情報
- まとめ
ORDER_FILLINGとは何か
ORDER_FILLINGは、MQL5で注文の約定方式を指定するための設定です。
OrderSendでMqlTradeRequestを送る時、request.type_fillingに約定方式を指定します。
MqlTradeRequest request = {};
MqlTradeResult result = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.type_filling = ORDER_FILLING_IOC;
OrderSend(request, result);ORDER_FILLINGは、注文方向を表すORDER_TYPE_BUYやORDER_TYPE_SELLとは別の項目です。注文種類はrequest.type、約定方式はrequest.type_fillingで指定します。
FOK・IOC・RETURNの違い
MQL5でよく確認する約定方式には、ORDER_FILLING_FOK、ORDER_FILLING_IOC、ORDER_FILLING_RETURNがあります。
| 定数 | 意味 | 確認ポイント |
|---|---|---|
| ORDER_FILLING_FOK | Fill or Kill。指定数量をすべて約定できる場合のみ成立させる方式です。 | 一部数量だけの約定を許容しない設計で確認します。 |
| ORDER_FILLING_IOC | Immediate or Cancel。すぐ約定できる分だけ約定し、残りはキャンセルする方式です。 | 部分約定の可能性を考慮します。 |
| ORDER_FILLING_RETURN | 一部約定後の残数量をキャンセルせず、注文として残す方式です。 | Market Executionでは使えない場合があるため注意します。 |
どの約定方式を使えるかは、銘柄や約定方式、ブローカー設定によって変わります。そのため、EA側で固定値を決め打ちする前に、SYMBOL_FILLING_MODEを確認してください。
MqlTradeRequest.type_fillingで指定する
注文要求では、MqlTradeRequestのtype_fillingへORDER_FILLINGを指定します。
type、type_filling、type_timeは似ていますが、役割が異なります。
| フィールド | 意味 | 例 |
|---|---|---|
| request.type | 注文種類 | ORDER_TYPE_BUY、ORDER_TYPE_SELL、ORDER_TYPE_BUY_LIMIT |
| request.type_filling | 約定方式 | ORDER_FILLING_FOK、ORDER_FILLING_IOC、ORDER_FILLING_RETURN |
| request.type_time | 有効期限種別 | ORDER_TIME_GTC、ORDER_TIME_DAY、ORDER_TIME_SPECIFIED |
| request.action | 取引操作 | TRADE_ACTION_DEAL、TRADE_ACTION_PENDING、TRADE_ACTION_SLTP |
注文エラーを調査する時は、request.typeだけでなく、request.type_fillingとrequest.actionも一緒にログへ出してください。
ORDER_FILLING_FOKの考え方
ORDER_FILLING_FOKは、指定した数量をすべて約定できる場合だけ注文を成立させる方式です。
指定数量の一部しか約定できない場合は、注文が成立しない可能性があります。
| 確認項目 | 内容 |
|---|---|
| 全数量の約定 | 指定lotすべてを約定できるか確認します。 |
| 部分約定の扱い | 部分約定を許容しない設計になります。 |
| 銘柄側の許可 | SYMBOL_FILLING_MODEでFOKが許可されているか確認します。 |
| OrderSend結果 | retcode、comment、GetLastErrorを確認します。 |
FOKは、注文数量をすべて一括で成立させたい場合に確認する約定方式です。ただし、対象銘柄で許可されていない場合は、別方式を使う必要があります。
ORDER_FILLING_IOCの考え方
ORDER_FILLING_IOCは、すぐに約定できる数量だけを約定し、残り数量をキャンセルする方式です。
そのため、OrderSendが成功しても、希望した数量すべてが約定したとは限らない場合があります。
| 確認項目 | 内容 |
|---|---|
| 部分約定 | 一部数量のみ約定する可能性があります。 |
| 残数量 | 残り数量はキャンセルされる前提で確認します。 |
| result.volume | 実際に約定した数量を確認します。 |
| Deal履歴 | OnTradeTransactionやHistoryDealGet系で実約定を確認します。 |
IOCを使うEAでは、OrderSendの成功だけでなく、実際にどれだけ約定したかをDeal履歴で確認することが重要です。
ORDER_FILLING_RETURNの考え方
ORDER_FILLING_RETURNは、一部約定後に残った数量をキャンセルせず、注文として残す方式です。
ただし、Market ExecutionではORDER_FILLING_RETURNが使えない場合があります。成行注文でRETURNを固定指定しているEAは、銘柄や口座によってOrderSendが失敗することがあります。
| 確認項目 | 内容 |
|---|---|
| Market Execution | RETURNが使用できない場合があります。 |
| 保留注文 | 保留注文ではRETURNを使う前提で確認します。 |
| 残数量 | 一部約定後の残数量がどう扱われるか確認します。 |
| Order履歴 | 残注文や履歴移動を確認します。 |
RETURNは便利ですが、すべての注文や実行方式で常に使えるわけではありません。Market Executionかどうか、保留注文かどうかを分けて確認してください。
SYMBOL_FILLING_MODEを確認する
銘柄ごとに許可されるfilling modeは、SYMBOL_FILLING_MODEで確認できます。
EAでは、注文前にSYMBOL_FILLING_MODEを取得し、FOKやIOCが許可されているかを確認すると、注文エラーを減らしやすくなります。
void PrintSymbolFillingMode(const string symbol)
{
long filling_mode = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
PrintFormat("[SYMBOL_FILLING_MODE] symbol=%s mode=%d",
symbol,
(int)filling_mode);
}SYMBOL_FILLING_MODEは、許可されている方式をフラグとして持つ場合があります。ログではmode数値だけでなく、FOK可否、IOC可否、RETURNの扱いも読みやすく出すと確認しやすくなります。
FOK / IOCを判定するhelper例
SYMBOL_FILLING_MODEを確認し、使える約定方式を判定するhelperを作ると、ブローカーや銘柄差に対応しやすくなります。
bool IsFillingFokAllowed(const string symbol)
{
long mode = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
return ((mode & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK);
}
bool IsFillingIocAllowed(const string symbol)
{
long mode = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
return ((mode & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC);
}
void PrintFillingSupport(const string symbol)
{
long mode = SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
PrintFormat("[FILLING_SUPPORT] symbol=%s mode=%d fok=%s ioc=%s",
symbol,
(int)mode,
(IsFillingFokAllowed(symbol) ? "true" : "false"),
(IsFillingIocAllowed(symbol) ? "true" : "false"));
}RETURNについては、銘柄の実行方式や注文種類によって扱いが変わるため、Market Executionや保留注文の条件と合わせて確認してください。
銘柄に合わせてtype_fillingを選ぶ例
EAでは、固定でORDER_FILLING_FOKやORDER_FILLING_IOCを指定するより、銘柄側で許可されている方式を確認してから指定する方が安全です。
ENUM_ORDER_TYPE_FILLING SelectFillingTypeForMarketOrder(const string symbol)
{
if(IsFillingIocAllowed(symbol))
{
PrintFormat("[FILLING_SELECT] symbol=%s selected=ORDER_FILLING_IOC", symbol);
return ORDER_FILLING_IOC;
}
if(IsFillingFokAllowed(symbol))
{
PrintFormat("[FILLING_SELECT] symbol=%s selected=ORDER_FILLING_FOK", symbol);
return ORDER_FILLING_FOK;
}
PrintFormat("[FILLING_SELECT] symbol=%s selected=ORDER_FILLING_RETURN reason=fallback_check_required", symbol);
return ORDER_FILLING_RETURN;
}この例では、IOCを優先し、次にFOKを選んでいます。ただし、実際の優先順はEA仕様、銘柄、約定方式、ブローカー環境に合わせて決めてください。
成行注文と保留注文で分ける
ORDER_FILLINGは、成行注文と保留注文で扱いを分けます。
成行注文では、銘柄の実行方式やSYMBOL_FILLING_MODEを確認します。一方、保留注文では、注文が送信時点で即時約定するものではないため、RETURNを使う前提で確認することが多くあります。
| 注文区分 | 代表action | ORDER_FILLING確認 |
|---|---|---|
| 成行注文 | TRADE_ACTION_DEAL | SYMBOL_FILLING_MODE、実行方式、retcodeを確認します。 |
| 保留注文 | TRADE_ACTION_PENDING | RETURNを基本に、type_timeやexpirationも確認します。 |
| SL/TP変更 | TRADE_ACTION_SLTP | type_fillingよりもposition、sl、tp、stop levelを確認します。 |
| 注文変更 | TRADE_ACTION_MODIFY | 対象order、price、type_time、expirationを確認します。 |
注文エラーを確認する時は、action、type、type_fillingをセットでログに出してください。
OrderCheckと組み合わせる
ORDER_FILLINGの指定が正しいかを確認するために、OrderSend前にOrderCheckを使うことがあります。
OrderCheckでは、MqlTradeRequestの内容を事前確認し、retcode、comment、margin、margin_freeなどをログに残せます。
bool CheckOrderFillingRequest(MqlTradeRequest &request)
{
MqlTradeCheckResult check = {};
ResetLastError();
bool ok = OrderCheck(request, check);
PrintFormat("[ORDER_CHECK_FILLING] ok=%s symbol=%s action=%d type=%d filling=%d retcode=%u comment=%s margin=%.2f margin_free=%.2f last_error=%d",
(ok ? "true" : "false"),
request.symbol,
request.action,
request.type,
request.type_filling,
check.retcode,
check.comment,
check.margin,
check.margin_free,
GetLastError());
if(!ok)
return false;
if(check.retcode != 0)
return false;
return true;
}OrderCheckで問題が見つからない場合でも、OrderSend時点の価格変動やサーバー状態により失敗することがあります。OrderCheckログとOrderSendログは分けて確認してください。
OrderSend結果ログで確認する
ORDER_FILLINGに関係する不具合を調べる時は、OrderSend前のrequest内容と、OrderSend後のMqlTradeResultをセットで確認します。
bool SendOrderWithFilling(const ENUM_ORDER_TYPE order_type,
const double volume,
const ulong magic)
{
MqlTradeRequest request = {};
MqlTradeResult result = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = volume;
request.type = order_type;
request.magic = magic;
request.comment = "EAFC_FILLING_CHECK";
request.type_filling = SelectFillingTypeForMarketOrder(_Symbol);
if(order_type == ORDER_TYPE_BUY)
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
else if(order_type == ORDER_TYPE_SELL)
request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
else
{
PrintFormat("[ORDER_TYPE_NG] type=%d reason=not_market_order", order_type);
return false;
}
PrintFormat("[ORDER_REQUEST_FILLING] symbol=%s type=%d volume=%.2f price=%.5f filling=%d magic=%I64u",
request.symbol,
request.type,
request.volume,
request.price,
request.type_filling,
request.magic);
if(!CheckOrderFillingRequest(request))
return false;
ResetLastError();
bool ok = OrderSend(request, result);
PrintFormat("[ORDER_SEND_FILLING_RESULT] ok=%s retcode=%u deal=%I64u order=%I64u volume=%.2f price=%.5f bid=%.5f ask=%.5f comment=%s last_error=%d",
(ok ? "true" : "false"),
result.retcode,
result.deal,
result.order,
result.volume,
result.price,
result.bid,
result.ask,
result.comment,
GetLastError());
return ok;
}OrderSend結果では、retcode、deal、order、volume、price、bid、ask、comment、GetLastErrorを確認できるようにしてください。
CTradeを使う場合の注意点
MQL5標準ライブラリのCTradeを使う場合も、filling typeの確認は重要です。
CTradeではSetTypeFillingで約定方式を設定できます。また、銘柄に合わせて設定する処理も用意されています。
#include <Trade/Trade.mqh>
CTrade trade;
int OnInit()
{
trade.SetExpertMagicNumber(24017);
trade.SetTypeFilling(ORDER_FILLING_IOC);
Print("[TRADE_INIT] magic=24017 filling=ORDER_FILLING_IOC");
return INIT_SUCCEEDED;
}CTradeを使う場合でも、注文が失敗した時はResultRetcode、ResultRetcodeDescription、ResultCommentなどを確認し、どのfilling typeで送ったのかをログに残してください。
注文エラー時に見るポイント
ORDER_FILLINGが原因で注文が通らない場合、OrderSendのretcodeだけでなく、銘柄仕様、実行方式、type_filling、OrderCheck結果を合わせて確認します。
| 確認項目 | 確認内容 | ログ名例 |
|---|---|---|
| SYMBOL_FILLING_MODE | 銘柄で許可されるfilling mode | FILLING_SUPPORT |
| SYMBOL_TRADE_EXEMODE | 銘柄の実行方式 | SYMBOL_EXECUTION_MODE |
| request.type_filling | EAが実際に指定した約定方式 | ORDER_REQUEST_FILLING |
| OrderCheck | 発注前の事前確認 | ORDER_CHECK_FILLING |
| OrderSend結果 | retcode、comment、deal、order | ORDER_SEND_FILLING_RESULT |
| 部分約定 | 希望数量と実約定数量の差 | DEAL_VOLUME_CHECK |
「注文できない」というログだけでは、ORDER_FILLINGが原因かどうか分かりません。注文要求の中身と銘柄仕様をセットで出してください。
ログ出力例
[FILLING_SUPPORT] symbol=GOLD mode=3 fok=true ioc=true
[FILLING_SELECT] symbol=GOLD selected=ORDER_FILLING_IOC
[ORDER_REQUEST_FILLING] symbol=GOLD type=ORDER_TYPE_BUY volume=0.10 price=2350.12 filling=ORDER_FILLING_IOC magic=24017
[ORDER_CHECK_FILLING] ok=true symbol=GOLD action=TRADE_ACTION_DEAL type=ORDER_TYPE_BUY filling=ORDER_FILLING_IOC retcode=0 comment=Done margin=120.50 margin_free=9879.50 last_error=0
[ORDER_SEND_FILLING_RESULT] ok=true retcode=10009 deal=123456789 order=987654321 volume=0.10 price=2350.13 bid=2350.10 ask=2350.13 comment=Request executed last_error=0
ログ例の数値、retcode、約定方式、価格、証拠金は確認用です。実際の値は、銘柄、口座、ブローカー、約定方式によって変わります。
よくある失敗パターン
| 失敗パターン | 問題点 | 確認方法 |
|---|---|---|
| ORDER_FILLING_RETURNを成行で固定する | Market Executionで使えず注文エラーになる場合がある | SYMBOL_TRADE_EXEMODEとtype_fillingを確認する |
| FOKを固定する | 銘柄でFOKが許可されていない場合がある | SYMBOL_FILLING_MODEを確認する |
| IOCの部分約定を考慮しない | 希望lotすべてが約定した前提で処理してしまう | result.volume、Deal履歴を確認する |
| 注文種類と約定方式を混同する | ORDER_TYPEとORDER_FILLINGの役割を取り違える | request.typeとrequest.type_fillingを別々にログ化する |
| 保留注文と成行注文を同じ処理にする | RETURNやtype_timeの扱いが混ざる | TRADE_ACTION_DEALとTRADE_ACTION_PENDINGを分ける |
| CTradeのfilling設定を確認しない | どの約定方式で送信したか追えない | SetTypeFilling、ResultRetcode、ResultCommentを確認する |
関連ページ
ORDER_FILLINGは、列挙型、注文構造体、OrderSend結果ログ、発注前チェック、約定まわりの基本用語と合わせて確認すると理解しやすくなります。
| 関連ページ | 確認できること |
|---|---|
| MQL5列挙型・定数辞典 | ENUM_ORDER_TYPE、ENUM_TIMEFRAMES、ORDER_FILLINGなどの定数整理 |
| MQL5 ENUM_ORDER_TYPEの基本 | 注文種類とMqlTradeRequest.typeの確認 |
| MQL5 OrderSend結果ログを実コードで解説 | retcode、MqlTradeResult、注文結果ログの確認 |
| MQL5でEAの発注前チェックを作る考え方 | OrderSend前のspread、lot、margin、trading allowed確認 |
| スリッページ・約定拒否・リクオートとは | EA注文で確認する約定まわりの基本用語 |
| MQL5標準ライブラリ・CTrade完全ガイド | CTrade、SetTypeFilling、ResultRetcodeの確認 |
注文処理と銘柄仕様をあわせて確認する場合
ORDER_FILLINGは、MqlTradeRequestのtype_fillingで指定する約定方式です。注文種類、注文要求、銘柄ごとのfilling mode、OrderSend結果をあわせて確認すると、注文エラーの原因を追いやすくなります。
| 確認したいこと | 確認するページ | 主な確認内容 |
|---|---|---|
| 注文関数と取引構造体の全体を確認したい | MQL5注文関数・取引構造体辞典 | OrderSend、OrderCheck、MqlTradeRequest、MqlTradeResult、注文処理全体の確認 |
| 銘柄ごとのfilling modeを確認したい | MQL5 SymbolInfoDouble / SymbolInfoIntegerの使い方 | SYMBOL_FILLING_MODE、point、digits、volume step、stop level、Bid / Askの確認 |
ORDER_FILLINGの不一致を確認する時は、request.type_fillingだけでなく、SYMBOL_FILLING_MODE、注文種類、OrderCheck結果、OrderSendのretcodeとcommentを分けてログに出してください。
開発依頼前に整理したい情報
ORDER_FILLINGや注文エラーの調査を相談する場合は、次の情報を整理してください。
| 整理する情報 | 確認内容 |
|---|---|
| 対象EA | 新規EA、既存EA改修、注文エラー調査のどれか |
| 対象銘柄 | GOLD / XAUUSD、USDJPY、CFD、suffix付き銘柄など |
| 口座・約定方式 | デモ / リアル、Market Execution、Instant Executionなど |
| 注文種類 | 成行、指値、逆指値、保留注文、決済注文など |
| 指定中のfilling | FOK、IOC、RETURN、CTradeの設定など |
| 銘柄仕様ログ | SYMBOL_FILLING_MODE、SYMBOL_TRADE_EXEMODE、volume stepなど |
| OrderCheckログ | retcode、comment、margin、margin_free |
| OrderSendログ | retcode、deal、order、volume、price、comment、GetLastError |
| 再現条件 | 発生時刻、対象set、ロット、価格、スプレッド、MT5ログ |
注文エラーの調査では、エラー番号だけでなく、MqlTradeRequestの内容、SYMBOL_FILLING_MODE、OrderCheck結果、OrderSend結果をまとめて確認してください。
まとめ
ORDER_FILLINGは、MQL5で注文数量をどのように約定させるかを指定するための設定です。
ORDER_FILLING_FOKは全数量約定を前提にし、ORDER_FILLING_IOCは即時約定できる分だけを約定し、ORDER_FILLING_RETURNは一部約定後の残数量を注文として残す方式です。
EA開発では、request.type_fillingを固定する前に、SYMBOL_FILLING_MODEや銘柄の実行方式を確認してください。特にMarket Executionでは、RETURNが使えない場合があります。
注文エラーを調査する時は、request.type、request.type_filling、request.action、OrderCheck結果、OrderSend結果、retcode、comment、GetLastErrorを分けてログ化すると、原因を追跡しやすくなります。
