技術辞典

MQL5 ORDER_FILLINGの違い|FOK・IOC・RETURNと注文エラー確認

EAファンクラブ

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とは何か

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_FOKFill or Kill。指定数量をすべて約定できる場合のみ成立させる方式です。一部数量だけの約定を許容しない設計で確認します。
ORDER_FILLING_IOCImmediate 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 ExecutionRETURNが使用できない場合があります。
保留注文保留注文では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を使う前提で確認することが多くあります。

注文区分代表actionORDER_FILLING確認
成行注文TRADE_ACTION_DEALSYMBOL_FILLING_MODE、実行方式、retcodeを確認します。
保留注文TRADE_ACTION_PENDINGRETURNを基本に、type_timeやexpirationも確認します。
SL/TP変更TRADE_ACTION_SLTPtype_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 modeFILLING_SUPPORT
SYMBOL_TRADE_EXEMODE銘柄の実行方式SYMBOL_EXECUTION_MODE
request.type_fillingEAが実際に指定した約定方式ORDER_REQUEST_FILLING
OrderCheck発注前の事前確認ORDER_CHECK_FILLING
OrderSend結果retcode、comment、deal、orderORDER_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など
注文種類成行、指値、逆指値、保留注文、決済注文など
指定中のfillingFOK、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結果をまとめて確認してください。

MT4/MT5の開発・改修相談はこちら

まとめ

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を分けてログ化すると、原因を追跡しやすくなります。

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