MQL4プログラミング 第2回 インジケーターを作成してみよう(実践編)
前回の予告通り、今回は実際にチャート上で動作するインジケーターをMT4プログラムで作成します。
作成するインジケーターは2本のMA(Moving Avarage)を利用してゴールデンクロスならHighサイン、デッドクロスならLowサインを表示します。
// prg-0002.mq4
#property copyright "Copyright 2024, smile-invest-blog.com"
#property link "https://www.smile-invest-blog.com/prg-0002/"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Yellow
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2
double Log1Up[]; // Highサイン用バッファ
double Log1Down[]; // Low サイン用バッファ
int realBars = 0;
int shortMaPeriod = 10; // 短期移動平均線の期間
int longMaPeriod = 30; // 長期移動平均線の期間
//+------------------------------------------------------------------+
//| initialization function
//+------------------------------------------------------------------+
int init() {
//---- indicators
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 233);
SetIndexBuffer(0, Log1Up);
SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 234);
SetIndexBuffer(1, Log1Down);
//----
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| deinitialization function
//+------------------------------------------------------------------+
int deinit() {
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| start function
//+------------------------------------------------------------------+
int start() {
double shortMaPrevious, longMaPrevious;
double shortMaCurrent, longMaCurrent;
int counted_bars=IndicatorCounted();
int limit = Bars - counted_bars;
for(int i = limit - 1; i >= 0; i--) {
if(i == 0) {
Log1Down[i] = EMPTY_VALUE;
Log1Up[i] = EMPTY_VALUE;
// 前回の移動平均値を取得
shortMaPrevious = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
longMaPrevious = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
// 現在の移動平均値を取得
shortMaCurrent = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
longMaCurrent = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
// 移動平均線のクロスを確認
if (shortMaPrevious < longMaPrevious && shortMaCurrent > longMaCurrent) {
// ゴールデンクロス → Highサイン
Log1Up[i] = Low[i] - 10 * Point;
if (realBars < Bars) { // 1本のローソク足で1回だけ実行するための条件
Alert(Symbol(), " *** High ***");
realBars = Bars; // realBarsをBarsにする事で同じローソク足では1回だけ実行する
}
}
else if (shortMaPrevious > longMaPrevious && shortMaCurrent < longMaCurrent) {
// デッドクロス → Lowサイン
Log1Down[i] = High[i] + 10 * Point;
if (realBars < Bars) { // 1本のローソク足で1回だけ実行するための条件
Alert(Symbol(), " *** Low ***");
realBars = Bars; // realBarsをBarsにする事で同じローソク足では1回だけ実行する
}
}
}
}
return(0);
}
上記のプログラムを軽く解説すると
2行目:#property indicator_buffers 2
これは12行目、13行目のサインを表示するバッファを2つ使うのでその数を宣言します。
7行目:#property indicator_color1 Yellow
これは、Highサインの矢印は黄色に設定する宣言です。
8行目は同じくLowサインの矢印は赤色に設定する宣言です。
9行目:#property indicator_width1 2
これは、上矢印の大きさを宣言しています。
10行目も同じく下矢印の大きさです。
12行目:double Log1Up[];
先程上記で説明した上下サインを表示するためのバッファの宣言となります。
16行目:int shortMaPeriod = 10;
ソースコードのコメント(// 以降のコードの説明)通りです。
22行目:int init() {
これはインジケータが初期化される時(例えばインジケータを起動する時やロウソク足の時間を変えた時など)に1回だけこの関数を実行します。
矢印のスタイルやどんな形の矢印に設定するかを宣言しています。
37行目:int deinit() {
これはinit()と同じくインジケータが終了される時やロウソク足の時間を変えた時などに1回だけこの関数を実行します。
あと、細かい内容は省略してキモになる箇所を説明すると
56~61行目:
ここではチャート上のMAの値を取得しています。
16~17行目でshortMaPeriodとlongMaPeriodがそれぞれ10、30と宣言されているのでMAの期間を指定してMAの値を取得しています。
「mql4 iMA」などとグーグル先生に聞いてみるとこの関数の詳細が分かるので是非調べてみてください。
64行目、72行目:
ここでiMA関数から取得した期間10と30のMAのゴールデンクロス、デッドクロスを条件を満たしていれば矢印用バッファに矢印を表示するように値をセットします。
52、53行目で矢印用バッファが毎回クリアされているので、ゴールデンクロスやデッドクロスの条件を満たすか満たさないかの微妙なチャート状況では矢印が出たり消えたりします。次足に変わるまで条件を満たしていれば確定したローソク足の矢印は表示されたままとなります。
以上で大まかな解説は終わりですが、このプログラムソースをそのままコピーしてインジケータを作成、起動すると動作するので是非試してください。
次回は今回と同じ動作をするプログラムを将来的に応用が利く構造に修正していきます。