MQL4プログラミング 第6回 インジケーターを作成してみよう(過去足のサイン表示)
今回も追加する部分はごくわずかですが、大変優れた効果を発揮する技を紹介します。それはタイトルにもあるように過去足のサインを表示する事です。
本当に追加する行数はほんの数行ですが大変便利な機能を追加できます。
前回までのプログラムを起動させてみると分かると思いますが、サインを出すのは起動した後のローソク足に対して条件が合えばサインを出しています。
でも、起動した時以前のローソク足に対してはたとえ条件が合っていてもサインは出してくれません。今回の修正ではこの問題を解決できるので次回以降取り上げる予定の過去足も含めたサインツールの勝率計算が可能となります。今までサインツールをいろいろ試してこられたかたにとってはこの勝率が簡単に取得できる事は非常に重要になってきます。
前置きはこれくらいにして、今回のソースプログラムを示します。
// prg-0006.mq4
#property copyright "Copyright 2024, smile-invest-blog.com"
#property link "https://www.smile-invest-blog.com/prg-0006/"
#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 winCountMaxBar = Bars - 2; // 勝率計算の足本数
extern int shortMaPeriod = 10; // 短期移動平均線の期間
extern int longMaPeriod = 30; // 長期移動平均線の期間
extern 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 ***");
}
}
}
}
else if (i >= 1) {
// 過去足のサインを表示する
hantei(i);
}
}
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;
}
過去足のサイン表示
今回のプログラムソースの追加箇所はコメントも含めてたった4行です。
69行目から72行目となります。これは55行目のhantei関数を使い回しています。55行目では戻り値(ret_hantei)を取得してアラートを表示していますが、過去足はアラートを表示する必要がないので戻り値も不要です。
いかがですか。以前の投稿(第3回 インジケーターを作成してみよう)でおこなった処理の関数化がここで有効活用されていますね。
今回も追加箇所は少ないですが、非常に重要な機能が追加できました。次回は今回の追加機能をさらに活かしたものにするプログラムを公開いたします。ステップバイステップで少しずつ改良を加えていくので毎回のソースプログラムをしっかり自分のものとしてください。
毎度ですが、今回のソースプログラムもコピペで動作いたします。是非実際に動かしてみてください。