グランビルの法則の2番を表示するインジケーター
グランビルの法則はご存知ですかね?
ジョセフ・E・グランビル(Joseph E. Granville)が考案した買いと売りの8つのパターンを言います。
具体的には
- 移動平均線
- ローソク足
を活用して、価格との位置関係やチャートパターンと組み合わせて見ていきます。
グランビルの法則については以下の記事を参照してください。
今回はその中でも2番を表示するインジケーターです。
また、グランビルをただ表示するだけではなく、
MTFの移動平均線を目安にしたグランビルのインジケーターとなります。
- グランビルでシグナルを表示
- MTFの
- ここにテキストを入力
メタエディタ(MetaEditor)を立ち上げる
メタエディタ(MetaEditor)を立ち上げましょう。操作は以下に記載しています。

今回は名前を「Granville」で作成します。
プロパティを記述する
プロパティを記述しましょう。
まず、シグナル2つを表示させるのでindicator_buffersは2つです。
#property indicator_buffers 2//バッファ2つ
それぞれの色を指定します。
#property indicator_color1 clrBlue//青色 #property indicator_color2 clrRed//赤色
幅を指定します。
#property indicator_width1 2//幅2 #property indicator_width2 2//幅2
これでプロパティを記述は完了です。
#property indicator_buffers 2//バッファ2つ #property indicator_color1 clrBlue//青色 #property indicator_color2 clrRed//赤色 #property indicator_width1 2//幅2 #property indicator_width2 2//幅2
バッファを定義する
バッファを定義しましょう。
今回は上矢印のupArrow[]と下矢印のdownArrow[]の2つを用意します。
double upArrow[], downArrow[];//上矢印と下矢印
これで、バッファを定義は完了です。
/*バッファ*/ double upArrow[], downArrow[];//上矢印と下矢印
パラメータを記述する
パラメータを記述しましょう。
maPeriodで移動平均線の期間を設定します。
input int maPeriod = 21;//移動平均線の期間
ENUM_TIMEFRAMESはチャート時間軸です。今回は1時間に設定したいので60にします。
input ENUM_TIMEFRAMES timeFrame = 60;//MTFのMAの期間
mtfMaPeriodでMTF(マルチタイムフレーム)用の移動平均線の期間を設定します。
input int mtfMaPeriod = 21;//MTF移動平均線の期間
最後にsignAlerでアラートのON/OFFを設定します。
input bool signAlert = false;//アラートのON/OFF
これでパラメータを記述は完了です。
/*パラメーター*/ input int maPeriod = 21;//移動平均線の期間 input ENUM_TIMEFRAMES timeFrame = 60;//MTFのMAの期間 input int mtfMaPeriod = 21;//MTF移動平均線の期間 input bool signAlert = false;//アラートのON/OFF
OnInit()関数に記述する
OnInit()関数に記述しましょう。
それぞれのインデックスに紐付けします。
SetIndexBuffer(0, upArrow);//インデックス0にupArrowを紐付け SetIndexBuffer(1, downArrow);//インデックス1にdownArrowを紐付け
スタイルを矢印の実線を選択しましょう。
SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID);//矢印の実線 SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID);//矢印の実線
最後に矢印の種類を決めましょう。
SetIndexArrow(0, 233);//矢印の種類 SetIndexArrow(1, 234);//矢印の種類
これで、OnInit()関数に記述は完了です。
SetIndexBuffer(0, upArrow);//インデックス0にupArrowを紐付け SetIndexBuffer(1, downArrow);//インデックス1にdownArrowを紐付け SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID);//矢印の実線 SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID);//矢印の実線 SetIndexArrow(0, 233);//矢印の種類 SetIndexArrow(1, 234);//矢印の種類
OnCalculate()関数に記述する
OnCalculate()関数に記述しましょう。
if(rates_total == prev_calculated) return(rates_total);
int limit = rates_total-maPeriod-1;//バー総数-maPeriod-1
int flag = 0;//フラッグを0にする
for(int i=limit; i>=1; i--)
{
upArrow[i] = EMPTY_VALUE;//配列を空にする
downArrow[i] = EMPTY_VALUE;//配列を空にする
int shift = iBarShift(NULL, timeFrame, time[i]);//MTFの設定
double mtfMa1 = iMA(NULL, timeFrame, mtfMaPeriod, 0, MODE_SMA, PRICE_CLOSE, shift+1);//MTFのMAのシフト1
double mtfMa2 = iMA(NULL, timeFrame, mtfMaPeriod, 0, MODE_SMA, PRICE_CLOSE, shift+2);//MTFのMAのシフト2
double ma = iMA(NULL, 0, maPeriod, 0, MODE_SMA, PRICE_CLOSE, i);//MA
double ma1 = iMA(NULL, 0, maPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);//MAのシフト1
if(mtfMa2 < mtfMa1 && mtfMa1 <= close[i])//MTFのMAシフト2の期間よりもMTFのMAシフト1の方が大きく、終値がMTFのMAシフト1以上の場合
{
if(flag == 1)//フラッグが1であれば
{
if(ma1 <= ma && close[i+1] <= ma1 && ma < close[i])//MAのシフト1がMA以下で終値のシフト1がMAのシフト1以下でMAが終値よりも小さい場合
{
upArrow[i] = low[i];//上矢印を安値に表示
}
}
else//フラッグが1以外であれば
{
if(ma < close[i]) flag = 1;//MAが終値よりも小さい場合はフラッグを1にする
}
}
if(mtfMa2 > mtfMa1 && mtfMa1 >= close[i])//MTFのMAのシフト1の期間よりもMTFのMAのシフト2の方が大きく、MTFのMAのシフト1が終値以上の場合
{
if(flag == -1)//フラッグが-1であれば
{
if(ma1 >= ma && close[i+1] >= ma1 && ma > close[i])//MAのシフト1がMA以上で終値のシフト1がMAシフト1以上でMAが終値よりも大きい場合
{
downArrow[i] = high[i];//下矢印を高値に表示
}
}
else//フラッグが-1以外であれば
{
if(ma > close[i]) flag = -1;//MAが終値より大きい場合はフラッグを-1にする
}
}
}
if(signAlert)//signAlertがTrunの場合
{
if(upArrow[1] != EMPTY_VALUE) Alert("Granville 2nd UP");//upArrowが空ではない場合にアラート
if(downArrow[1] != EMPTY_VALUE) Alert("Granville 2nd DOWN");//downArrowが空ではない場合にアラート
}コンパイルする
コンパイルしましょう。シグナルが表示されていたら完了です。

移動平均線を表示した場合は以下のようになります。

ソースコード全体
ソースコード全体です。
//+------------------------------------------------------------------+
//| Granville.mq4 |
//| Copyright 2020, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#property indicator_chart_window
/*プロパティ*/
#property indicator_buffers 2//バッファ2つ
#property indicator_color1 clrBlue//青色
#property indicator_color2 clrRed//赤色
#property indicator_width1 2//幅2
#property indicator_width2 2//幅2
/*バッファ*/
double upArrow[], downArrow[];//上矢印と下矢印
/*パラメーター*/
input int maPeriod = 21;//移動平均線の期間
input ENUM_TIMEFRAMES timeFrame = 60;//MTFのMAの期間
input int mtfMaPeriod = 21;//MTF移動平均線の期間
input bool signAlert = false;//アラートのON/OFF
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, upArrow);//インデックス0にupArrowを紐付け
SetIndexBuffer(1, downArrow);//インデックス1にdownArrowを紐付け
SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID);//矢印の実線
SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID);//矢印の実線
SetIndexArrow(0, 233);//矢印の種類
SetIndexArrow(1, 234);//矢印の種類
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[]){
if(rates_total == prev_calculated) return(rates_total);
int limit = rates_total-maPeriod-1;//バー総数-maPeriod-1
int flag = 0;//フラッグを0にする
for(int i=limit; i>=1; i--)
{
upArrow[i] = EMPTY_VALUE;//配列を空にする
downArrow[i] = EMPTY_VALUE;//配列を空にする
int shift = iBarShift(NULL, timeFrame, time[i]);//MTFの設定
double mtfMa1 = iMA(NULL, timeFrame, mtfMaPeriod, 0, MODE_SMA, PRICE_CLOSE, shift+1);//MTFのMAのシフト1
double mtfMa2 = iMA(NULL, timeFrame, mtfMaPeriod, 0, MODE_SMA, PRICE_CLOSE, shift+2);//MTFのMAのシフト2
double ma = iMA(NULL, 0, maPeriod, 0, MODE_SMA, PRICE_CLOSE, i);//MA
double ma1 = iMA(NULL, 0, maPeriod, 0, MODE_SMA, PRICE_CLOSE, i+1);//MAのシフト1
if(mtfMa2 < mtfMa1 && mtfMa1 <= close[i])//MTFのMAシフト2の期間よりもMTFのMAシフト1の方が大きく、終値がMTFのMAシフト1以上の場合
{
if(flag == 1)//フラッグが1であれば
{
if(ma1 <= ma && close[i+1] <= ma1 && ma < close[i])//MAのシフト1がMA以下で終値のシフト1がMAのシフト1以下でMAが終値よりも小さい場合
{
upArrow[i] = low[i];//上矢印を安値に表示
}
}
else//フラッグが1以外であれば
{
if(ma < close[i]) flag = 1;//MAが終値よりも小さい場合はフラッグを1にする
}
}
if(mtfMa2 > mtfMa1 && mtfMa1 >= close[i])//MTFのMAのシフト1の期間よりもMTFのMAのシフト2の方が大きく、MTFのMAのシフト1が終値以上の場合
{
if(flag == -1)//フラッグが-1であれば
{
if(ma1 >= ma && close[i+1] >= ma1 && ma > close[i])//MAのシフト1がMA以上で終値のシフト1がMAシフト1以上でMAが終値よりも大きい場合
{
downArrow[i] = high[i];//下矢印を高値に表示
}
}
else//フラッグが-1以外であれば
{
if(ma > close[i]) flag = -1;//MAが終値より大きい場合はフラッグを-1にする
}
}
}
if(signAlert)//signAlertがTrunの場合
{
if(upArrow[1] != EMPTY_VALUE) Alert("Granville 2nd UP");//upArrowが空ではない場合にアラート
if(downArrow[1] != EMPTY_VALUE) Alert("Granville 2nd DOWN");//downArrowが空ではない場合にアラート
}
return(rates_total);
}
//+------------------------------------------------------------------+





コメント