【動画】MT4のMQLプログラミング超初心者入門
初心者でもできるMT4のMQLプログラミング
今回は、超初心者向け、ド素人でもわかるMT4によるプログラミングをやってみたいと思います。内容は、MQLを使ってチャートの高値を線で結んでみる、というものです。だから、移動平均線ですらないというレベルです。
でも、この線を1本引くだけの作業で、変数や配列、for文、if文を使うので、内容はかなり濃いと思います。
MetaEdior(メタエディター)の起動
まず、MT4を起動します。上部メニューの「ツール」から、「メタエディター」を選びます。MetarEditorが起動しました。
何もありませんので、画面左上の「ファイル」から「新規作成」を選びます。MQLウィザードが起動しました。こういう画面は、ウィザードと言います。
ウィザードは魔法使いとか名人、専門家という意味で、最初にこういうクリックして進んでいくような画面ができたときはものすごく画期的だったので、ウィザードという呼び名が付けられました。Wizard=魔法使い
今回はインジケーターを作るので、2番目のカスタムインディケータを選び、次に進みます。
インジケーター名を入力、今回は「test」にしておきます。最初から左に入っているものはインジケーターを保存するパスなので消さず、あとはそのままで次に行きます。
カスタムインディケータのイベントハンドラの選択、イベントハンドラというのは、特定の出来事、これをイベントと言いますが、それが発生した時に実行するよう処理することです。一番上のOnCalculateというのは、新しいtickを受信した時に何か処理する、という意味で、チャートの動きを検知して計算してくれるので、このままでOKです。次に行きます。
インジケーターの描画に関する設定で、今回はメインチャートにラインを描くのでサブウィンドウにはチェックを入れません。
チャートの高値を線で結ぶ、というプログラムなので、その下の追加を押して、メインチャートに赤いラインを表示してみようと思います。プロットに出てきたら、これで赤いラインを引く準備ができました。
完了をクリックします。そうすると、色々出てきました。これは、ソースコードと言います。
プロパティ部分
全体の大雑把な構造としては、3つの部分に分かれていまして、一番上は設定などのプロパティ部分、真ん中はOninit関数による初期化部分、一番下がOnCalculate関数によるインジケーター作成部分になります。
まず、一番上から見ていきます。
スラッシュスラッシュで始まって灰色になっている部分は、コメントアウトといってプログラムの記述ではなく、メモのようなものです。
だから、全部消してしまってもいいんですが、自分がどういう理由で記述したかをメモしておいたり、他人がソースコードを見た時何だか分からないと困るので、ヒントになるよう今回は残しておきます。
コメントは、次の二つの書き方があります。
// 1行コメント
/*
ブロックコメント
*/
1行目から5行目、この部分のコメントはこのプログラムの名前や著作権表示です。インジケーター名を「test」としましたので、2行目の一番右にa.mq4とこのファイル名が記載されています。
その下にある、実際のプログラム部分は色が付いていまして、6行目から18行目は全部「#property」になっています。
この#から始まる命令はプリプロセッサ命令と呼ばれていて、プログラム全体に関わる設定を表します。
#property 識別子 値
という書き方をしますが、値のないものもあります。
プロパティというのは設定みたいなものでして、6行目はcopyrightで著作権、7行目はリンクでMQL公式サイトへのリンク、8行目はバージョンが書いてあります。
このあたりは大したことないんですが、次から難しくなっていきます。
9行目、#property strictのストリクトは「厳格」という意味で、省略できるところも省略しないでしっかり書いていく、ということを表しています。
昔のMT4はややあいまいな部分があったので、Build600以降から付け加えられるようになりました。
10行目、インディケーター、チャートウィンドウ、メインチャートにインジケーターを描画するという意味です。
さっきのウィザードでサブウィンドウにチェックを入れると、「indicator_separate_window」という表記に変わって、作成したインジケーターがサブウィンドウに表示されます。
11行目、インディケーター、バッファズ 1
これは、表示させたい指標の数を表します。ここでは1つです。
12行目、インディケーター、プロッツ 1
プロッツは描画の意味で、1本描画することを意味します。
13行目はコメント、削除してもいいんですが、ヒントが書いてあるので残しておきます。
プロットラベル1と書いてあって、ここから下はプロットラベル1の説明ですよ、という意味です。プロットラベル1と言うのは、さっきウィザードで設定した赤い線のことです。14から18行目は、赤い線の設定が書いてあります。
14行目、インディケーターラベル1の名前はラベル1、
15行目、インディケーターのタイプ1はドローラインで線の描画
16行目、インディケーターカラー1は色の設定、
カラーレッドなので赤い色
17行目、インディケータースタイル1はスタイルソリッド、
ソリッドは実線の意味です。点線だったらSTYLE_DOTにします。
18行目、インディケーターウィドス1は1、線の太さが1です。
14から18行目を簡単にいうと、「赤い太さ1の実線を引く」という意味になります。
ここまでは設定なので、まだ線は引かれないです。
19行目はコメントでインディケーター バッファズ。
初期化部分
次の20行目から急に難しくなります。さっきまでは分かって当然の部分です。このあと難しいです。ここから本格的にプログラミングになりますので、一気に難しくなります。
警戒してください、
という意味で、難しくなると3回言いました。
20行目 ダブル ラベル1バッファ
角かっこ開始、角かっこ閉じ、セミコロン
この四角の文字は角(かく)かっこといいます。この20行目は、倍精度浮動小数点数型で配列ラベル1バッファをプログラム全体に対して宣言する、という意味になります。
いま僕が言った言葉、全然分からなくても大丈夫です。全部、詳しく説明します。
最初のdoubleというは倍精度浮動小数点数型、すごく簡単に言うとたくさん小数点を使える型、という意味になります。
倍精度ということは倍じゃないのもありまして、単精度浮動小数点型(float)というのもあるんですが、精度が限定されて十分な結果を得られない事があるため、ほとんどの場合doubleを使用します。
その次の配列Lavel1Buffer、Lavel1Bufferの部分は半角英数で最大31文字の長さあればabcとかaiueoとか何でもいいんですが、本来であれば「Buf」とかが分かりやすいです。
ここへ、あとでインジケーターを作るときに指標の値を入れて計算させるために使います。だから、この20行目だけだと何の役にも立たず、このあとの記述で使っていくことになります。
本来は、角かっこのなかに10や20など数字を入れて、データを入れる箱を決まった数だけ確保するのですが、ここには数字が入っておらず空っぽになっています。
なぜかというと、チャート上に何個のデータがあるか分からないですし、時間が経てばチャートのデータが増えてしまうので、あらかじめ箱の数を決めることができないからです。
今の段階では、データの入れ物を作ったと考えておいてください。
あと、命令文の一番最後は半角のセミコロンを入れます。コロンではなくセミコロンなので注意してください。
21~23行目はコメント、カスタムインディケータ― イニシャリゼーション ファンクションイニシャリゼーションは初期化、ファンクションは機能の意味、プログラムの初期化部分で、プログラムを読み込むときの最初に実行されます。
24行目 int OnInit
int型のオンイニット関数を宣言、int は Integer(インテジャー) の略で,整数型を宣言する場合に使います.
オンイニットは初期化関数と言って、プログラムをチャートに挿入したときに実行されます。
関数とは、一定の処理を実行する流れをひとまとめにしたものです。注文を出す、とか、決済する、とかです。ここでは、プログラムをチャートに挿入したときに実行する処理です。
その内容は、25から31行目、25行目と31行目には、ここからここまでですよ、という意味で中かっこが書かれています。
26行目はコメント インディケーター バッファズマッピング
27行目 SetIndexBuffer(0,Label1Buffer);セットインデックスバッファ、ゼロ、カンマラベル1バッファ、セミコロン。
さっき20行目で倍精度浮動小数点数型の配列ラベル1バッファというそれだけだと役に立たないものが出てきていましたが、それを活性化させるのがこの27行目です。
セットインデックスバッファという関数を使って、配列ラベル1バッファを0番目の指標バッファに割り当てています。
プログラミングの場合、最初のスタートは1からではなく0からで、今回の0が1番目の意味です。
27行目をすごく簡単に言うと、これで20行目の配列ラベル1バッファが使えるようになったという命令、あるいはグローバル領域に宣言した配列を、インジケーター用の配列に活性化させた、ということになります。
20行目とこのあたりの記述が、セットになっています。
28行目 空白、
29行目 空白のコメント、
30行目 リターン、イニットサクセスド、ここで初期化が完了しました、の意味です。
32~34行目のコメント、カスタムインディケータ―、イテレイション、ファンクションイテレイションは繰り返しの意味、ここから下がインジケーターの動作内容を記述するところになります。
だから、このプログラムのメイン部分のような感じです。
35~45行目、たくさん書いてありますが、インジケーター作成に使える10個のデータになります
35行目、int OnCalculate(const int rates_total
イント オンカルキュレイト
コンスト イント レーツトータル
イントは整数型、OnCalculate はチャート上でTick値が更新されるたびに呼び出されます。コンストは(constant)のことで定数、こちらからは外部から値を勝手に変えられない内容です。
レーツトータルは各レート要素数、簡単に言うとチャート上のローソク足の本数で、チャートに新しいローソク足が出るたび1増えます。
36行目はイント型のプリブ カルキュレイテッド、プリブはPrevious、前のという意味で、前回オン カルキュレイトを呼び出した際のリターン値が入ってきます。
まだ一度も呼び出していないときは0で、ちょっと飛びますが49行目にリターンレーツトータルとあるので、次の処理からはレーツトータルの値が入り、レーツトータルの方はローソク足が描画されるので1足されます。
これは、最後の仕上げで使ってみます。
37行目はタイム、チャート上のバーの時間が配列の値として入ってきます。
38行目はオープン、始値の値が配列に入ってきます。
39行目はハイ、高値の値が配列に入ってきます。
今回は高値を結んだラインを引いてみるので、あとでこのハイを使います。
40行目はロウ、安値の値が配列に入ります。
41行目はクローズ、終値の値が配列に入ります。
42行目はティックボリューム、ティックの更新回数のデータが配列に入ります。
43行目はボリューム、約定枚数のデータですが、FXでは使用されていません。
44行目はスプレッド、MT4では使用されていません。
45行目に開始の中かっこ、
50行目の終了の中かっこまでが処理内容の記述場所です。
46行目と51行目はコメント、
48行目はプリブ カルキュレイテッドの戻り値だというコメント、49行目はレーツトタールの値を最初に返すという意味で、この値が36行目のプリブ カルキュレイテッドに入ります。
インジケーター作成部分
配列の数字

変数limitの中身

アルゴリズム

高値ラインを引くソースコード
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Label1
#property indicator_label1 "Label1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 3
//--- indicator buffers
double Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Label1Buffer);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
int i;
int limit;
if(prev_calculated==0){
limit=rates_total-1;
}
else
{
limit=rates_total-prev_calculated;
}
for(i=limit; i>=0; i--)
{
Label1Buffer[i]=high[i];
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
最終更新日 : 2020-11-12