MQL4プログラミング 第4回 インジケーターを作成してみよう(条件の追加)
今回は前回作成したプログラムの進化版としてADX値をサイン表示の条件に追加したいと思います。
前回はMAがゴールデンクロス、あるいはデッドクロスとなったロウソク足でサインを出しましたが今回はあらたにADX値を取得していきます。
では、今回のプログラムを示します。
// prg-0004.mq4
#property copyright "Copyright 2024, smile-invest-blog.com"
#property link "https://www.smile-invest-blog.com/prg-0004/"
#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; // 長期移動平均線の期間
int adxPeriod = 14; // ADXの期間
//+------------------------------------------------------------------+
//| 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() {
bool ret_hantei; // hantei関数の結果格納用
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;
ret_hantei = hantei(i); // 上下サイン表示の判定を関数化した
if (ret_hantei == true) { // hantei関数の結果がtrueの時
if (realBars < Bars) { // 1本のローソク足で1回だけ実行するための条件
realBars = Bars; // realBarsをBarsにする事で同じローソク足では1回だけ実行する
if (Log1Up[i] != EMPTY_VALUE) { // hantei関数内で上サイン表示と判定された
Alert(Symbol(), " *** High ***");
}
else if (Log1Down[i] != EMPTY_VALUE) { // hantei関数内で下サイン表示と判定された
Alert(Symbol(), " *** Low ***");
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
//| エントリーの条件判定関数
//| int i メイン関数からのiの値
//+------------------------------------------------------------------+
bool hantei(int i) {
double shortMaPrevious, longMaPrevious;
double shortMaCurrent, longMaCurrent;
double adx;
// 前回の移動平均値を取得
shortMaPrevious = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);
longMaPrevious = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);
// 現在の移動平均値を取得
shortMaCurrent = iMA(NULL, 0, shortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
longMaCurrent = iMA(NULL, 0, longMaPeriod, 0, MODE_SMA, PRICE_CLOSE, i);
// 現在のADXベースライン値を取得する
adx = getAdx(MODE_MAIN, i);
if (shortMaPrevious < longMaPrevious && shortMaCurrent > longMaCurrent) {
// // 移動平均線のクロスを確認 → ゴールデンクロス
if (adx > 25) {
// adx値が25より大きい場合 → Highサイン
Log1Up[i] = Low[i] - 10 * Point;
return true;
}
}
else if (shortMaPrevious > longMaPrevious && shortMaCurrent < longMaCurrent) {
// 移動平均線のクロスを確認 → デッドクロス
if (adx > 25) {
// adx値が25より大きい場合 → Lowサイン
Log1Down[i] = High[i] + 10 * Point;
return true;
}
}
return false;
}
//+----------------------------------------------------------------------+
//| ADXの値を取得する
//| 引数1 MODE_MAIN(0):ベースライン,MODE_PLUSDI(1):+DIライン,MODE_MINUSDI(2):-DIライン
//| 引数2 シフト数
//+----------------------------------------------------------------------+
double getAdx(int mode, int i) {
double ret;
ret = iADX(
NULL, // 通貨ペア
0, // 時間軸
adxPeriod, // 平均期間
PRICE_CLOSE, // 適用価格
mode, // ラインインデックス
i // シフト
);
return ret;
}
ADX値を取得するgetAdx関数を追加
まず、118行目でADX値を取得する関数を追加しました。元々は120行目のiADXというテクニカルインジケータ関数を使えば良いのですが引数が6つもあるので必要な引数のみ与えれば済むように関数化しました。皆さんは余裕があれば82行目などで使っているiMAのテクニカルインジケータ関数をgetAdxのように独立した関数に書き換えてみてください。
サイン表示の条件を追加
90行目でADX値を取得しています。94行目と102行目でADX値が25より大きければ(adx > 25)という条件を追加しています。
以上から
上サインの表示条件:移動平均線がゴールデンクロス かつ ADX値が25より大きい場合
下サインの表示条件:移動平均線がデッドクロス かつ ADX値が25より大きい場合
と、それぞれ条件が追加されました。
追加の解説
125行目のmodeが取り得る値は115行目の引数の説明にもありますが再度まとめると下記になります
ID | 値 | 説明 |
MODE_MAIN | 0 | ベースライン |
MODE_PLUSDI | 1 | +DIライン |
MODE_MINUSDI | 2 | -DIライン |
今回はIDで記述していますが、値(0~2)で記述しても同じ結果が得られます。
次回はカスタムインジケーターにパラメーターを追加していきたいと思います。