MQL4で成行注文を送るときは、`OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, sl, tp, comment, magic, 0, clr)`のように、
11個の引数を順番どおりに並べるだけでした。
MQL5で同じ処理を`OrderSend()`で書こうとすると、
公式リファレンスの関数シグネチャがまったく違うことに気づきます。
bool OrderSend( MqlTradeRequest &request, //送信する注文の内容 MqlTradeResult &result //発注結果が書き込まれる );
引数は2つの「構造体」への参照だけです。
この記事では、MQL5の`OrderSend()`で成行注文を送る基本の流れを、
MQL4版との違いを踏まえて解説します。
MqlTradeRequest構造体に注文内容を詰める
MQL4では発注時にその場で引数を並べましたが、MQL5ではまず`MqlTradeRequest`型の変数を用意し、
フィールドに1つずつ値を代入します。
主なフィールドは以下のとおりです。
MqlTradeRequest構造体の主なフィールド action 注文の種類(ENUM_TRADE_REQUEST_ACTIONS。成行・決済ならTRADE_ACTION_DEAL) symbol 通貨ペア volume ロット数 type 売買種別(ENUM_ORDER_TYPE。買いならORDER_TYPE_BUY、売りならORDER_TYPE_SELL) price 注文価格 sl 損切り価格 tp 利確価格 deviation 許容スリッページ(ポイント単位) magic マジックナンバー type_filling 注文執行方式(ENUM_ORDER_TYPE_FILLING)
`action`は「これから何をする注文か」を表すフィールドで、
成行注文・指値注文の新規発注はすべて`TRADE_ACTION_DEAL`(即時約定)または`TRADE_ACTION_PENDING`(予約注文)を指定します。
ポジションの決済も同じ`TRADE_ACTION_DEAL`で、
`type`を反対売買にして`position`フィールドに決済対象のチケットを指定する形で行います(決済については別記事で扱います)。
構造体は宣言時に`={}`を付けて全フィールドを0初期化しておくのが安全です。
付け忘れると、この記事で使わないフィールドに不定値が残ったまま送信され、
意図しない注文になる可能性があります。
MqlTradeRequest request={};//全フィールドを0初期化
MqlTradeResult result={};
成行買い注文を組み立てて送信する
実際に成行買い注文を組み立てるコードです。
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.01;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.sl = request.price - 100 * _Point;
request.tp = request.price + 100 * _Point;
request.deviation = 10;
request.magic = 123456;
request.type_filling = ORDER_FILLING_FOK;
if(!OrderSend(request, result))
{
Print("OrderSend自体が失敗しました。エラーコード=", GetLastError());
return;
}
MQL4の`OrderSend()`は成功すればチケット番号、
失敗すれば-1を返す1つの戻り値で結果を表していました。
MQL5の`OrderSend()`が返す`bool`は、あくまで「サーバーに送信できたか」
を表すだけで、注文が実際に約定したかどうかは別途`result`(`MqlTradeResult`構造体)を見る必要があります。
MqlTradeResultのretcodeを必ず確認する
`OrderSend()`が`true`を返しても、ブローカー側で注文が拒否されているケースがあります。
必ず`result.retcode`を確認してください。
if(result.retcode != TRADE_RETCODE_DONE)
{
PrintFormat("注文は拒否されました。retcode=%d comment=%s", result.retcode, result.comment);
return;
}
PrintFormat("成行買い成立: order=%d deal=%d price=%.5f", result.order, result.deal, result.price);
`TRADE_RETCODE_DONE`(10009)は「注文が完全に処理された」
ことを表す値です。
これ以外の値が返ってきた場合は、`result.comment`にブローカーからの拒否理由が入っているので、
まずそれを確認してください。
実際に動くコード全体
ここまでの内容をまとめた、成行買い注文を1回送信する、実際にMetaEditorでコンパイルできるスクリプトです。
実際に注文を送信するコードのため、動作確認は必ずデモ口座で行ってください。
//+------------------------------------------------------------------+
//| OrderSendDemo.mq5 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property script_show_confirm
input double Lots = 0.01;//ロット数
input int SlPoints = 100;//損切り幅(ポイント)
input int TpPoints = 100;//利確幅(ポイント)
input int Deviation = 10;//許容スリッページ(ポイント)
input long MagicNumber = 123456;//マジックナンバー
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
MqlTradeRequest request={};
MqlTradeResult result={};
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = Lots;
request.type = ORDER_TYPE_BUY;
request.price = ask;
request.sl = ask - SlPoints * _Point;
request.tp = ask + TpPoints * _Point;
request.deviation = Deviation;
request.magic = MagicNumber;
request.type_filling = ORDER_FILLING_FOK;
if(!OrderSend(request, result))
{
Print("OrderSend自体が失敗しました。エラーコード=", GetLastError());
return;
}
if(result.retcode != TRADE_RETCODE_DONE)
{
PrintFormat("注文は拒否されました。retcode=%d comment=%s", result.retcode, result.comment);
return;
}
PrintFormat("成行買い成立: order=%d deal=%d price=%.5f", result.order, result.deal, result.price);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MetaTrader 5の「ツール」→「MetaQuotes Language Editor」でMetaEditorを開く
- 「ファイル」→「新規作成」→「スクリプト」を選び、名前を「OrderSendDemo」にして作成する(中身は空のテンプレートで構いません)
- テンプレートの中身を全て削除し、上のコードを丸ごと貼り付ける
- F7キー(またはコンパイルボタン)でコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- MT5でデモ口座を選択していることを確認したうえで、ナビゲーターパネルからスクリプトをチャートへドラッグ&ドロップする(入力パラメーターの確認画面が出るので内容を確認してOKを押す)
- 「表示」→「ツールボックス」の「取引」タブに新規ポジションが表示されれば成功です
コピペしてコンパイルが通らない・注文が拒否されるときに確認すること
- 拡張子が「.mq5」になっているか(このコードはMQL4の`OrderSend()`とは別物の関数のため、.mq4ファイルには貼れません)
- retcodeが「10030(Unsupported filling mode)」の場合、`type_filling`にそのブローカー・銘柄が対応していない執行方式を指定しています。`SymbolInfoInteger(_Symbol, SYMBOL_FILLING_MODE)`で対応方式を確認し、`ORDER_FILLING_FOK`で拒否される場合は`ORDER_FILLING_IOC`を試してください
- retcodeが「10019(No money)」の場合、証拠金不足です。デモ口座の残高またはLots(ロット数)を確認してください
まとめ
MQL5で成行注文を送るには、①`MqlTradeRequest`構造体に注文内容を詰める、
②`OrderSend(request, result)`を呼ぶ、
③戻り値の`bool`だけでなく`result.retcode`が`TRADE_RETCODE_DONE`かを確認する、
という3段階の流れになります。
MQL4のように1回の関数呼び出しで完結しない分、送信できたことと約定したことが別物である点を意識すると、
エラー処理が書きやすくなります。
コメント