(C系わかる人向け)MQL4言語について

過去のブログのアーカイブ
この記事は前身のブログのアーカイブを引き継いだものです. 画像が正しく表示できないなど,コンテンツの表示に問題がある恐れがあります.

FX取引でもメジャーなツールMetaTraderで使われる言語MQLについて、サンプルを見ただけじゃわかりづらいところ多いと思うのでC系と違うところ、要点をまとめておきます。
なおこちらの記事はMQL4であり、MQL5ではありません。多分互換性はあると思いますが。

そもそもMQL4とは

MQL4について知らない方も少なくないと思います。簡単にいえばMT4で自作インジケータや自作EAを作成する際に使用する言語で、今時珍しい非オブジェクト指向言語です。
スクリプトに近いもので、そこまで複雑なものを作るための言語ではありません。
sdfbvjhgvhbn
また、この言語の開発環境であるMetaEditorは日本語に対応していません。これはメニューが日本語表示じゃないとかそういう問題じゃないです。エディタそのものが2バイト文字に対応していないため、日本語でコメントをすると文字が重なります。(上記絵を参照)
そのため、ある程度英語ができる前提の言語です。また、そもそも日本語資料もほとんどないです。ただでさえ英語資料すら少ないのですからちょっと敷居の高い言語ですね。

非オブジェクト指向なので…

さて、この言語の最大の特徴は非オブジェクト指向なところだと思います。本来あってもいい特徴が特徴とは、変な感じですね。
C言語を普段使っている方には当たり前なことだと思います。私はC#を普段使っているため最初混乱しました。平和ボケっていうやつでしょうか。
本来、オブジェクトへのアクセスといえばObject.Method()みたいな感じで、オブジェクトにドットを挟んで簡単にアクセスできます。オブジェクト指向じゃないということはこのようなアクセスができないということ。
ではどうすればいいのでしょうか。例えば現在保持しているオプションを閉じるならこのようになります。

for ( int i = 0; i < OrdersTotal(); i++ ) {
    if ( OrderSelect(i, SELECT_BY_POS) == true && OrderMagicNumber() == Magic && OrderSymbol() == Symbol() ) {
        if ( OrderType() == OP_BUY )
            OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Black);
        if ( OrderType() == OP_SELL )
            OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Black);
    }
}

まずOrdersTotalで現在のオプション数を調べて、それをforで次々に回していきます。
オブジェクト指向だとこのタイミングでOrder[i]みたいにアクセスしますが、MQL4ではOrderSelectを使います。
これでMT4内部でそのオプションが選択されます。その次に例えばオプションの種類を知りたいならばOrderType()を呼び出します。引数の指定はいりません。内部でオプションが選択されているためです。
オブジェクト指向ではないとはこういうことなのです。

MQL4で抑えるべき点

さて、言語の簡単な仕様は紹介しました。え、これだけ?と思いますがこれだけで十分だと思います。
スクリプト言語みたいな簡単な言語なので、普段難しい言語を使っているだろうC系プログラマならすぐにできます。
ただ、この言語の特徴と言えるような点が幾つかあるのでそこだけ紹介致します。

Magic値

オプションは誰が開くかわかりません。自分の作ったEAが開くかも、もしかしたらユーザーが手動で開くのかも。
そこで識別するのがMagicという値です。これは勝手に決めてもいいです。しかしintの範囲内で、他のものと被らないであろう数値を指定するのがベターです。
この値はグローバル空間で変数として置いておくと便利です。
int Magic = 123456; みたいな感じで。

start関数

最初、私はここで混乱しました。start関数とあるのに何をどうスタートなのか。
これは値が変更されたり、新しい足になったときに毎回呼び出されます。つまり、ここの中に1つずつ足を調べていく…なんて必要はありません。
つまりはですね、EAならばstartが呼び出されたらオーダーや判定をして注文を出す。
インジケータならstartが呼び出されたら計算してバッファに入れる。
これをすることになります。

現在値を調べる

現在値を調べるにはいくつか方法があります。ただ、基本的に現在チャートに表示してある足のデータが返されます。
例えば、1分足のチャートを出している場合、High値を取得すれば1分足の、現在の最高値が返されることになります。
データの取得方法は以下の通り
Ask, Bid, HIGH, LOW, OPEN, CLOSE
また、これは配列になっています。1本前のデータが知りたければAsk[1]みたいに指定すると返ってきます。

オーダーは時間を調べること!

ちょっとわかりづらいですが、オーダーを開く(オプションを開く)際はまずは既にオプションを開いていないか、前回注文したのはいつかを調べるべきです。
なぜかといいますと、注文は重複して出すことができます。もし条件分岐で時間を管理しておかないとともかくカオスなことになります。1本の足から大量のオーダーが伸びます。
また、ロングとショートを同時に開くことだってできます。が、EAで自動売買するのにナンピンとか証拠金相殺をするのはナンセンスです。というか何のための自動売買ですか!ってなりますね。

インジケーターでの注意点

インジケーターはバッファで管理されることがかなり多いです。もし、チャート上に線や矢印を設定したいならばまずはバッファの存在をMT4に通知する必要があります。
1. つまり、まずソースコードの最初の方に次のコードを追加します。
#property indicator_buffers 1
2. その次にバッファをグローバル空間に確保します。初期化はいりません。
double signal[];
3. init関数内で初期化する
SetIndexStyle (0, DRAW_ARROW); // インジケータの種類は矢印
SetIndexBuffer (0, signal); // バッファをインデックス0に指定する
SetIndexLabel (0, “Test”); // 名前を指定する
と、この3つをしてあげる必要があります。そしてデータを格納するときはAskみたいなときと同じ、現在の足に指定するならsignal[0] = 値; って感じですね。1本前ならsignal[1] = 値;です。

MQL4の将来性

そもそもこれFXなんですよ、ついでにいうとマニー(money)な世界なわけです。もしも優秀なEAやインジケータを作ればものすごい高値で売ることだってできるわけですね。
いいやつなのかどうか知らないけれど2000ドルでソフトが取引なんてザラですから。まあ最もすごいリスクの高い商品になるわけですから怖いんですが。
最も、もしも勝率が高く、ロスの少ないEAを作れたならばそれだけで一生生活することだってできるかもしれませんね。