OrderSend で注文を出す

MT4のEA(MQL4)で新規注文を出すときに使うのがOrderSend()です。引数の意味と、注文が通らないときに確認すべきポイントをまとめます。


[PR]


OrderSend

OrderSend()は1行で書けるため「注文はこれを呼ぶだけ」と思いがちですが、実際にはそう簡単ではありません。FX業者ごとにシンボル名・ロットの単位・ストップレベルなどが異なり、確認を怠ると「ロジックは成立しているのに注文が出ない」「想定外のロットで発注される」といったトラブルになります。

この記事では、まず関数の定義と各引数の意味を確認し、そのあと実際にEAへ組み込むときの注意点とサンプルコードを紹介します。

Definition(定義)

戻り値は、注文が成功したときはトレードサーバーが割り当てたチケット番号、失敗したときは -1 です。失敗した理由は、直後に GetLastError() を呼ぶと取得できます。

Ref: OrderSend – Trade Functions – MQL4 Documentation

Parameters(引数)

symbol:通貨ペア名

通貨ペア名を指定します。次のいずれかにしておくのが安全です。

  • Symbol()(EAをセットしたチャートの通貨ペア)
  • NULL(Symbol()と同じ意味)
  • FX口座に合わせたシンボル名(”USDJPY-b”、”USDJPY.pers”、”USDJPYm” など)

安易に “USDJPY” と固定で書くと、業者によっては存在しないシンボルとなり注文が失敗します。

例えば、Forex ExchangeのMT4で次のコードを実行し、「エキスパート」タブのログを確認してみます。

ログにはこう表示されました。

このように、Symbol()が返す名前は業者によって「XXX.pers」「XXX-b」などと異なり、注文もその名前どおりに出す必要があります。同じ業者でも、口座タイプ(最大注文ロット数やEAの利用可否など)ごとにシンボル名を分けている場合があります。

cmd:注文の種類

注文の種類を指定します。売り・買いそれぞれに、成行・指値(limit)・逆指値(stop)の3種類があります。

ID 値 注文の種類 price に入れる価格
OP_BUY 0 買いの成行注文 現在のAsk
OP_SELL 1 売りの成行注文 現在のBid
OP_BUYLIMIT 2 買いの指値注文 Askより下
OP_SELLLIMIT 3 売りの指値注文 Bidより上
OP_BUYSTOP 4 買いの逆指値注文 Askより上
OP_SELLSTOP 5 売りの逆指値注文 Bidより下

指値・逆指値では、price に指定する価格の位置が決まっています。逆の位置を指定するとエラー(130:ERR_INVALID_STOPS など)になります。

volume:ロット数

注文するロット数です。1ロットが何通貨かは、FX業者・口座タイプ・通貨ペアによって異なります(1万通貨、10万通貨、1,000通貨など)。事前に MarketInfo() の MODE_LOTSIZE で確認しておきましょう。

あわせて、最小ロット(MODE_MINLOT)・最大ロット(MODE_MAXLOT)・ロットの刻み(MODE_LOTSTEP)も確認し、その範囲と刻みに合ったロット数にしないと注文は通りません。

price:注文価格

注文する価格です。成行注文なら、買いは Ask、売りは Bid を指定します。

指値・逆指値の価格を計算するときは、Point(1ポイントの値幅)を使い、NormalizeDouble() で小数点以下の桁数(Digits)に丸めます。業者によって桁数が「2桁か3桁(円絡み)」「4桁か5桁(それ以外)」と違うため、丸めないと「価格が不正」としてエラーになることがあります。

例)現在のAskから100ポイント上に、買いの逆指値(OP_BUYSTOP)を置く価格

以下、stoploss・takeprofit など価格を指定する引数でも、同じように NormalizeDouble() で丸めます。

slippage:許容スリッページ

成行注文で許容するスリッページ(注文時の価格とのズレ)を、ポイント単位で指定します。

5桁表示(円絡みは3桁表示)の業者では 1pips=10ポイント なので、slippage に 3 と書くと0.3pipsしか許容しないことになります。pipsで考えたい場合は10倍して指定しましょう。

stoploss:損切り価格

損切り(ストップロス)の価格です。設定しない場合は 0 にします。

ECN口座など、成行注文が「マーケット執行(Market Execution)」方式の口座では、OrderSend() の時点で stoploss / takeprofit を指定するとエラーになることがあります。その場合は 0 で発注し、約定後に OrderModify() で損切り・利確を設定します。

ただし、約定直後に続けてリクエストを送るとサーバー側で拒否されることもあるため、少し待ってから再試行するような処理を入れておくと安心です。

ストップレベルに注意

業者によっては、現在価格から一定の距離(ストップレベル)以上離さないと、指値・逆指値や損切り・利確を置けない場合があります。この距離が足りないと注文は通りません。ストップレベルは次のコードで取得でき、MT4の「気配値表示」→ 通貨ペアの「仕様」からも確認できます。

なお、値が 0 の場合は「制限なし」の場合と、「サーバー側で動的に管理していて端末からは分からない」場合の両方があります。

takeprofit:利確価格

利確(テイクプロフィット)の価格です。考え方は stoploss と同じで、設定しない場合は 0 にします。

comment=NULL:注文コメント

注文に付けるコメントです。省略しても構いませんが、同じ口座で裁量トレードもしている場合、どれがEAの注文か見分けやすくなるので入れておくのがおすすめです。パラメータで変更できるようにしておくのもよいでしょう。

なお、コメントの末尾はサーバー側で書き換えられることがあります(決済時に「[sl]」「[tp]」が付くなど)。コメントで注文を識別するのは避け、識別には次のマジックナンバーを使いましょう。

magic=0:マジックナンバー

EAが自分の注文を識別するための番号です。EAごと(必要なら通貨ペアや時間足ごと)に重ならない番号を付けておくと、ポジション管理や決済のときに OrderMagicNumber() で自分の注文だけを選び出せます。

expiration=0:待機注文の有効期限

指値・逆指値(待機注文)の有効期限を、日時(datetime型)で指定します。例えば「今から1時間後」なら TimeCurrent() + 3600 のように、サーバー時間を基準にした日時を渡します。成行注文では使いません。

期限を設けない場合は 0 にします。取引サーバーによっては有効期限の設定自体が無効にされていて、指定するとエラーになる場合があります。

arrow_color=clrNONE:矢印の色

約定(エントリー)した位置にチャート上で表示される矢印の色です。省略するか clrNONE にすると矢印は表示されません。

Tips(注意点)

引数のところでも触れましたが、OrderSend() を呼ぶ前後には確認しておきたいことがいくつかあります。必須ではありませんが、手を抜くと「ロジックは成立しているのに注文が出ない」「想定外の結果になる」原因になります。

証拠金・ポジション数の確認

レバレッジをよく理解しないまま始める初心者も多く、証拠金ギリギリで注文が通り、少し逆行しただけで口座が溶けてしまうことがあります。口座内の他のポジションも含めて、レバレッジが高くなりすぎないか確認しておくと安心です。

AccountFreeMarginCheck() を使うと、その注文を出した後に残る余剰証拠金を事前に計算できます。

マジックナンバーの確認

ポジション数を数えたり決済したりする前に、その注文が自分のEAのマジックナンバーかどうかを確認します。他のEAや手動の注文を誤って操作しないためです。

通貨ペアの確認

エントリーするときの通貨ペアは Symbol() または NULL にしておきます。固定で書く場合は、「USDJPYm」「USDJPY.pers」など業者独自の文字が付いていることを考慮します。

損切り・利確の設定確認

前述のとおり、口座の方式によっては OrderSend() で損切り・利確を受け付けないことがあります。その場合は、OrderSend() が返したチケット番号で OrderSelect() し、OrderModify() で設定します。設定に失敗したまま損切りなしのポジションが残らないよう、結果も必ず確認しましょう。

注文が通らないときに確認する関数

  • IsStopped():EAの停止(チャートからの削除や端末の終了など)が指示されると true を返します。true なら、それ以上注文を出さずに処理を終えます。
  • IsTradeContextBusy():他のEAが同時に注文中などで、取引スレッドが使用中なら true を返します。少し待ってから再試行します。
  • GetLastError():注文に失敗したときのエラーコードを返します。エラーの種類によって、再試行すべきものと、すぐにやめるべきものがあります。

代表的なエラーの扱いは次のとおりです。

  • 再試行してよいもの:135(価格変更)、136(オフクオート)、138(リクオート)、146(取引スレッドがビジー)など。RefreshRates() で最新価格を取り直してから再発注します。
  • 再試行しても無駄なもの:130(不正なストップ)、131(不正なロット数)、134(証拠金不足)など。引数や口座の状態を見直す必要があります。

サンプルコード

ここまでの内容をまとめた、買いの成行注文を出すシンプルな例です。リクオートなど再試行できるエラーのときだけ、最大3回までやり直します。

損切り・利確が必要な場合は、返ってきたチケット番号を使って OrderSelect() → OrderModify() で設定します。

 

References:
OrderSend – Trade Functions – MQL4 Documentation
NormalizeDouble – MQL4 Reference – MQL4 Documentation
Point – Predefined Variables – MQL4 Documentation
Trade Server Return Codes – MQL4 Documentation

シェアする

  • このエントリーをはてなブックマークに追加

フォローする