[EA]MQL5プログラミングのためのMQL4との違い

公開日: : MT5/MQL5 , , ,

 

MQL4プログラマがMQL5を始める前に知らないと失敗すること

MQL4はできるけどMQL5と言語仕様が違うと聞いて、MQL5は保留状態だった方は多いと思います。このページに来たということは、何かしらの理由でMQL5を始めてみよう、あるいは、始めてみたけどよく分からんって方だと思います。

 

MQL4は開発されたのがかなり昔の話なので、「もっとこうした方が良いよね」とか「本来こうすべきだったよね」というのをMQL5では改良されています。

逆に言うと、MQL5では、慣例的に周知された仕様よりも厳密性や定義を重視するので、それまでのMQL4の仕様を一切無視した仕様などもあります。

 

MQL5を始める前に、そうした泥沼にはまるような仕様の違いについてご紹介します。基本的にMT5をディスっているのでMT5の良いところを知りたい方はMT5がMT4よりも優れている点 一覧

MT5対応のおすすめ海外FX会社一覧

 

ヘッジアカウントとネッティングアカウントの大幅な差

 

MT5ではアカウントの種類にヘッジタイプとネッティングタイプがあります。これはFX業者に依存したもので、MT5内で変更することはできません。

そのMT5がどちらのアカウントタイプかは

で調べられます。

中にはヘッジタイプかネッティングタイプかを選択できるFX業者さんも存在します。裁量トレードの場合は、ネッティングタイプの方が便利ですが、EAを稼働させる場合はヘッジアカウントの方が対応しているものが多いです。

また、現時点では9割型のMT5アカウントがヘッジモードです。ネッティングアカウントはわざわざ探さないと見つからないレベルではありますが、EA開発者であるならば必ず知っておかなければならないモードです。

 

ネッティングアカウントの場合

 

ネッティングタイプとはオーダーを合算させる仕様の口座タイプです。例えば、両建てをした場合、ヘッジタイプではMT4のように表示されますが、ネッティングタイプでは前に持っていたポジションが決済されて終了です。

 

そもそも両建て、ナンピンはできない

 

また、同じ通貨ペアで同じ方向にロットを増やした場合(ピラミッティングした場合)、ヘッジタイプでは新たなオーダーとして区別されますが、ネッティングタイプの場合はオーダーが合体させられます。

つまり、ネッティングアカウントでは、ナンピン、ピラミッティング、両建てなどの手法は一切できません

 

オーダーコメントは上書きされる

 

同じ通貨ペアでポジションを新規にとると、すでに保有しているポジションのチケットナンバーでロットだけ増加します。
同じように、もしEAにコメント付きでオーダーを送信させて、そのあと裁量で同じ通貨ペアのオーダーをすると、
オーダーコメントが上書きされてしまいます。

 

コメントでオーダーを管理するというのは、安定性に欠けるので避けるべきではありますが、
それでも複雑な開発要件の場合、どうしても使用せざるをえないことがあります。

 

しかし、MT5ではコメントがリアルタイムで変化する可能性があるので、
コメントを使ったプログラミングは比較的穴になる可能性があります。

 

(見かけ上は古いコメントが消滅したように見えますが、中では残っているようです。)

 

 

 

オーダー決済の仕方

ネッティングアカウントの場合、決済は反対売買によって行います。そのため、もっているポジションの逆向きの同じロットの注文を送信すれば決済されます。

 

ヘッジアカウントの場合

ヘッジタイプは、ポジション、オーダーの扱いに関しては従来のMT4とまったく同じタイプのアカウントです。CTradeという標準ライブラリを使えばMQL4と同様に処理できます。

 

 

 

MQL5ではポジション、オーダー、ディールを厳密に区別する必要がある

MT4ではオーダーとポジションがあまり厳密に区別されることはありませんが、MT5ではディールが追加され、この3つを厳密に区別します。

 

MT5でのオーダーとは

MT5/MQL5でいうところのオーダーとはブローカーサーバーに送信された注文そのものを指します。

基本的には約定前の予約注文、決済注文をサーバーに送ることなどを指します。

そのため、一回の往復の取引で、オーダーは少なくとも2つ存在します。(エントリー時と決済)

 

MT4/MQL4では、約定済みのポジションも未約定のオーダーも一緒にしてオーダーと呼んでいましたが、MQL5では約定済みのオーダーはポジションとなり、約定していないオーダーはオーダーのままになります。

オーダーにはオーダーチケット(≠ポジションID nor ≠ディールチケット)が付与されます。

 

 

 

MT5でのディールとは

 

MT5/MQL5ではDeal(ディール)というものが存在します。これはMT4にはなかった言葉です。

約定した注文をディールと呼びます。オーダーが実際には上手くいくかどうかわからないリクエストのようなものであるのに対して、ディールは実際に注文が取ったことを表します。

 

また、厄介な点として、ロットが大きい場合には一つのオーダーに対してディールが分割されることがあります。言い換えると、指定したロットのオーダーを単一の価格で約定させることができなかったために、ロットと価格を分割して約定させるモードがありますが、それによって約定した場合、ディールが分割されます。

 

 

例えば、USDJPYの成行買い注文を30ロットで出したとします。30ロットというのはかなり大きなロットなので、まず分割されます。15ロットは100.001で約定(ディール)し、25ロットは100.002で約定(ディール)が発生します。

 

この場合、それぞれにディールチケットを持つディールがMT5に表示されます。MQL5でのディールの取得の際もそれぞれ別個のものとして扱われます。

 

1回の往復の取引で、ディールは少なくとも2つ以上存在する可能性があります。

ディールにはディールチケットが付与されます。(≠ディールチケット nor ≠ ポジションID )

また、ディールの場合、エントリーか決済かをIN/OUTで区別することが可能です。

オーダーとディール(左に矢印がついているものがディール)

 

MT5でのポジションとは

 

約定したオーダーです。予約注文(未約定オーダー)は含まれません。また、未約定中の予約注文(指値注文、逆指値注文)にはそもそもポジションID(MQL4で言うところのチケット)が付与されません。

 

MQL5では、オーダーが約定したタイミングでポジションごとにポジションID(≠ディールチケット nor ≠オーダーチケット)が振り分けられます。

 

オーダーがエントリーの場合、オーダーチケットとポジションIDは一致します。

 

MT5のポジション履歴

以前のMT5のbuildバージョンではターミナル上でポジション履歴を表示する機能がありませんでしたが、修正されて閲覧できるようになりました。ポジション一覧はMT4のポジション一覧と同じような見た目なので、分かりやすいと思います。

 

 

まとめると、ポジション、ディール、オーダーはこのように構成されます。

 

オーダー、ディール、ポジションの記事はこちら

https://www.mql5.com/en/articles/211

 

オーダー/ポジションの注文の仕方

MQL5ではオーダーはOrderSendの関数を使いますが、MQL4のOrderSendとは全くの別物です。構造体を使ってオーダーを送ります。

 

標準ライブラリ(CTrade)を使ったオーダーの注文

また、あまりのオーダー関数の使いずらさにクレームが大量に行った関係で、その後に標準ライブラリが実装されました。MT5にデフォルトで搭載されています。標準ライブラリのCTradeを使えば、MQL4ライクな実装が可能です。

 

OrderOpenとPositionOpenがあるので混同に注意してください。

 

ポジション決済の仕方

CTrade

デフォルト関数

こちらの場合、そのシンボルのポジションが全部決済されてしまうので、チケットごとに決済したい場合は上の書き方の方がおすすめです。

 

 

MQL5でのオーダー、ディール、ポジションの識別処理

MT4では何かと御世話になるOrdersTotalですが、MT5では注意深い使用が必要です。類似の関数にPositionsTotalというものができているのですが、MQL5では約定したポジションと予約注文が分かれています。

 

Order~ Position~系は完全に関数が分離しています。

 

ここら辺をしっかり把握せずにMQL4と同じようにコーディングすると洗礼を受けます。

MQL4ではOrderSelect一つで済んでいたことが、MQL5では状況に応じて関数の使い分けが必要です。

では、その関数はなんなの?というと…

OrdersTotal()とOrderSelectの併用の代わりに、MQL5では6つの関数の使い分けが必要

OrderSelect(ticket):

引数はチケット番号。MQL4で言うところの、OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADE)です。ただし、対象はオーダー。SELECT_BY_POSとかSELECT_BY_TICKETの指定はもうありません。チケットでしか渡せません。


PositionSelectByTicket(ticket):

チケットを引数に入れると、MQL4で言うところのOrderSelectした状態になります。MQL4で言うところの、OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADE)です。ただし、対象はポジション。


PositionSelect(symbol):

引数はシンボル。MT5のネッティング口座の場合、シンボル毎にオーダーが集約されるので、シンボルを選択すればオーダーの情報が引っ張ってこれるよね、って仕組みです。

ヘッジ口座の場合は意図しないポジションも一気に処理してしまうので、これを使うと汎用性がガガガ…


HistorySelect(from_date,   to_date ):

MQL4のOrderSelect(i,SELECT_BY_POS, MODE_HISTORY)と見せかけて違います。

履歴を参照する期間をUNIXタイムで指定します。(HistoryReadPeriod()とかの名前の方が良かったんじゃないの?)


HistoryOrderSelect(ticket):

MQL4で言うところの、OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISOTRY)です。

呼び出せば、

HistoryOrderGetDouble(), HistoryOrderGetInteger(), HistoryOrderGetString() が使えるようになります。


HistoryDealSelect(ticket):

ディールごとに履歴を参照できます。

呼び出せば、HistoryDealGetDouble(), HistoryDealGetInteger()を利用できるようになります。


HistorySelectByPosition(position_id):

position_idは、全ての新しくオープンしたポジションに割り当てられ、ポジションのライフタイムに一貫する固有の番号です。これに関してはあまり馴染みがないと思います。指定した条件のポジション履歴を参照・回収します。こいつを使うとHistoryDealsTotal() とHistoryOrdersTotal()の値が変わります。

 

でも、上の関数を従来のように使うにはチケットがわかってないと駄目だよねってことで、

チケットを取得する関数

オーダーチケット、ディールチケット、ポジションID(MQL4で言うところのオーダーチケット)の混同に注意してください。

OrderGetTicket(index):

MQL4で言うところの、OrderSelect(index,SELECT_BY_POS,MODE_TRADE)ですが、チケットを返すと同時にOrderSelectの役割も自動的に果たすので、OrderTicket()とOrderSelectの合体版のようなやつです。(逆にこいつのあとでOrderSelectするとバグります。)  注:約定済みのポジションは範囲外なので、予約注文のみを返します。


PositionGetTicket(index):

ポジションの数未満の数値を引数に入れると、そのポジションのチケットを返します。


PositionGetSymbol(index):

持っているポジションの数以下の数値を引数に入れると、そのポジションのシンボルを返します。返すのはチケットではありませんが、PositionSelect(symbol)と組み合わせて使えます。


HistoryOrderGetTicket(index):

履歴のチケットを返します。使うには事前にHistorySelectで期間を指定しておく必要があります。


HistoryDealGetTicket(index):

履歴のディールのチケットを返します。

 

オーダー情報に関するサンプルコード

未約定のオーダー情報が欲しい場合のコード

ストップロスとテイクプロフィットはそのオーダーがエントリーのときのみ取得可能です。決済時のオーダーではSL/TPが0になります。

 

未決済のポジションの情報が欲しい場合のコード

 

MQL4と同じように生きているオーダー、ポジションの取得をしたい場合は、上の二つを回せば何とかなります。ディールに関してはポジションの中に内包されるので、よっぽど細かいディールデータが欲しい場合を除いて必要ありません。

 

履歴のオーダー情報が欲しい場合のコード

履歴の取引のデータの取得も基本的に流れは変わりませんが、事前にHistorySelectで取得する期間を指定する必要があります。

 

 

履歴のディール情報が欲しい場合のコード

 

履歴のポジション情報が欲しい場合のコード

未決済のポジションの取得はPosition関数があるので簡単ですが、履歴のポジションデータを取得するには専用の関数HistoryPositionGet***の関数群がありません。そのため、MT4と同じように履歴にあるポジションを取得するにはかなり遠回りをしなくてはなりません。

〇=取得可能 ×=取得不可

  Order Deal
シンボル
ロット ×(分割されたロットなら可)
注文方式 〇(エントリー時のみ可能) ×
マジックナンバー
注文価格 ×
注文時間 ×
約定価格 ×
約定時間 ×
SL 〇(エントリー時のみ可能) ×
TP 〇(エントリー時のみ可能) ×
決済注文価格 ×
決済注文時間 ×
決済約定価格 ×
決済約定時間 ×
ポジションID
オーダーチケット
ディールチケット ×

履歴の取引情報を取得する際の比較表

 

また、MT4の場合はキャンセルされた予約注文はポジション扱いとして履歴に残りますが、MT5ではポジション欄の履歴に削除済みのオーダーは表示されません。(オーダーの履歴には残ります。) また、削除された指値注文、逆指値注文にはポジションIDが付与されないので、別個に処理する必要があります。

  履歴のポジション 履歴のディール 履歴のオーダー 削除された予約注文
HistorySelect HistoryOrdersTotal() HistoryOrderGetTicket × ×
HistorySelect HistoryOrdersTotal() HistoryDealGetTicket × × ×
HistorySelectByPosition HistoryOrdersTotal() HistoryOrderGetTicket × ×
HistorySelectByPosition HistoryOrdersTotal() HistoryDealGetTicket × × ×

関数の組み合わせと取得可能なデータ

 

流れとしては、

履歴のポジションチケット(ポジションID)を履歴のオーダーをループさせることで配列に取得

取得したポジションチケットには順不同の重複があるので、ソートして重複を削除

精製した一意の連番のポジションチケットからHistorySelectByPositionを使ってオーダーとディールを検索

検索結果のオーダーとディールから対応した約定価格などの数値を取ってくる

上の処理とは別に、削除された予約注文は、ポジションIDが0になっている履歴のオーダーから取得する

という形です。

 

 

 

時系列予約変数・関数がない

Open[],Close[],iOpen(),iClose()がない

MQL4では始値、終値、高値、安値を取得する関数がありましたが、
MQL5ではありません。「いや、でも名前が変わっても似たような関数があるんでしょ?」
と思うのが普通だと思います。

それがないんですね~

MQL5では、自分で配列を宣言して、配列の向きを変えて、配列に値を入れないと始値~安値を取得できない!

さすがにバージョンアップで実装されたようです。逆にオリジナル関数で代用していた人の場合、定義済みの関数としてバグを吐き出すので、ほんと大変ですよね。

 

iMA, iMACD, iRSIなどのテクニカル指標の返値がint

移動平均や、MACDなどをはじめとしたテクニカル指標i〇〇関数の返値はすべて整数でハンドルが返ってきます。そのため、例えばATRの値が欲しい場合は、これまではiATR(Symbol(),Period(),14)とすればよかったところ、

とする必要があります。

 

その他

ところどころ良くなっているところはもちろんあるのですが、
その他にも

  • MT5を複数インストールフォルダにコピーするとEAの紐づけがバグる
  • 特定の条件でコンパイルしてもEAが初期化されないバグ(コンパイルの失敗)
  • ヒストリーデータがいじれない(import,export)
  • コンパイルしたときにエラーが一番上に来ない
  • 決済後のトレードのコメントを表示できない

などあります。

 

チャートにセットした実行中のEAのパラメータは変えられない

【追記】バージョンアップで変えられるようになりました

MT4ではEAが稼働しているチャート上で右クリックを押せばパラメータを変更できましたが、MT5では変更できません。(変更できないなら、あたかも変更できるように見せかけるUIやめてほしいものです)

 

実行中のEAのパラメータを変更するには一度EAを停止するか、新規にEAをチャートにセットしなければなりません。

 

そのため、ちょっとだけパラメータを変更したい場合でも、リセットされた状態からすべて設定しなおさなければなりません。

 

つまり、MT4では「とりあえずEAをセットしてもらってから、後でパラメータを変更してもらう」ということができましたが、MT5ではなるべく最初の時点ですべてのパラメータをきっちり入力できるようにコーディングする必要があります。

 

 

インジケーターバッファの最大が512

MT4のインジケーターはバッファが最大8なので、どんなに頑張ってもシグナルに関連する数値は8までしか出すことができませんでした。

しかし、MT5ではバッファが512なので、サブウィンドウ上で8以上のラインを表示させることも可能です。

 

MQL5ではBarsが使えない

MQL4ではBars, MQL5ではChartGetInteger(Chart_ID,CHART_VISIBLE_BARS)。→バージョンアップでMQL4由来の配列も使えるようになりました。

 

オブジェクトの扱い

MQL5では、関数の引数のチャートIDの省略が不可になりました。

 

MQL5にはMarketInfoがない

MQL4ではMarketInfo(),

MQL5では返値の型に応じて関数を使い分けます。

AccountInfoInteger()~AccountInfoDouble()

 

MQL5ではIsDemoの返値の順番が違う

MQL4では0-ライブ 1-デモか、

MQL5では0-デモ、1-コンテスト、2-ライブ、

いや、数字の順番は一緒にしてくれよ・・・

 

AccountInfoInteger(ACCOUNT_TRADE_MODE)で取り出します。

 

MQL5のこれまでのざっくりした変遷

MQL5の発表。ただし、MQL4との互換性なしということで誰も使わない。(MQL4の関数がない)

あまりに使われないのでMQL4をMQL5にちょっとずつ似せる

MQL4の関数も一部使えるようになる。(オリジナル関数を作っていたコードはコンパイルでエラーを吐き出すようになる)

公式が互換関数(標準ライブラリ)を実装する。

ヘッジアカウントとネッティングアカウントの2タイプに分かれる。

【現状】

・同じMT5なのにそれぞれの口座タイプに合わせたEAを作らなければいけなくなる。

・古いMQL5のコードは書き直しをしないとエラーでコンパイルできない。

 

レート取得の対応

MQL4 MQL5 内容

SymbolInfoDouble(Symbol(),SYMBOL_ASK);

でも可

Barsは変わりなし
SymbolInfoDouble(Symbol(),SYMBOL_BID)でよくね? 

さすがに批判殺到で、

iClose(Symbol(),Period(),shift)が使えるようになりました。

Digitsは_Digitsです。

アンダーバーを忘れずに

バージョンアップでiHigh(Symbol(),Period(),shift)が使えるようになりました。
MQL4と同じようにiLow()が使えます。
MQL4と同じようにiOpen()が使えます。

Pointは_Pointです。

アンダーバーを忘れずに。

iTime()が使えます。
iVolumeが使えます。

 

この投稿は役に立ちましたか? 役に立った 役に立たなかった 15 人中 15 人がこの 投稿 は役に立ったと言っています。

Message

メールアドレスが公開されることはありません。

CAPTCHA


関連記事

MT5の使い方(MetaTrader5) インストールから~バックテストまで

MT5はMT4に慣れ親しんだトレーダーであれば比較的簡単に移行することができるトレードプラットフォー

記事を読む

日経225はSP500の後追いをするのか検証 & 日経225vsSP500裁定取引

よく「日本の株式市場は前日のニューヨーク市場の後追いをする」と言われています。実際に裁量トレードする

記事を読む

株価指数両建て裁定取引のやり方と検証

日経225やダウ、SP500のチャートには強い相関関係があります。かつては「日経はニューヨークの後追

記事を読む

no image

MQL4 MQL5 関数変換表

https://www.mql5.com/ja/articles/81 を見れば良いんですが、万が一

記事を読む

 

Translate »
上に戻る