https://s3-us-west-2.amazonaws.com/secure.notion-static.com/679529ea-d97e-4770-a097-1152084adfd7/chart3.png

日中足のチャートに日足のテクニカル指標を表示させるマルチタイムフレーム指標の一例として、PIVOTを取り上げます。

PIVOTとは回転軸という意味です。前日の高値(H)、安値(L)、終値(C)の平均値をPIVOT(P)として、売買の目安となるレジスタンスライン(R1,R2,R3)、サポートライン(S1,S2,S3)を以下のように算出するものです。

P = (H + L + C)/3
R1 = P + (P - L)
S1 = P - (H - P)
R2 = P + (H - L)
S2 = P - (H - L)
R3 = R1 + (H - L)
S3 = S1 - (H - L)

コード

Pivot.mq5

💡MQL4用にはファイルの拡張子をmq4にしてダウンロードしてください。

プログラムのプロパティ

//MQL4互換ライブラリ(MQL5のみ)
#include "LibMQL4.mqh"

//プログラムのプロパティ
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots   7
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE
#property indicator_type3   DRAW_LINE
#property indicator_type4   DRAW_LINE
#property indicator_type5   DRAW_LINE
#property indicator_type6   DRAW_LINE
#property indicator_type7   DRAW_LINE
#property indicator_color1  clrGreen
#property indicator_color2  clrSkyBlue
#property indicator_color3  clrViolet
#property indicator_color4  clrRoyalBlue
#property indicator_color5  clrMagenta
#property indicator_color6  clrBlue
#property indicator_color7  clrRed

//指標バッファ用の配列
double PBuf[];  //PIVOT
double R1Buf[]; //R1
double S1Buf[]; //S1
double R2Buf[]; //R2
double S2Buf[]; //S2
double R3Buf[]; //R3
double S3Buf[]; //S3

PIVOTに対して、3本のサポートライン(S1,S2,S3)、3本のレジスタンスライン(R1,R2,R3)を表示するために、計7本の指標バッファを用意します。

初期化関数

void OnInit()
{
   //配列を指標バッファに関連付ける
   SetIndexBuffer(0, PBuf);
   SetIndexBuffer(1, R1Buf);
   SetIndexBuffer(2, S1Buf);
   SetIndexBuffer(3, R2Buf);
   SetIndexBuffer(4, S2Buf);
   SetIndexBuffer(5, R3Buf);
   SetIndexBuffer(6, S3Buf);

   //時系列配列に設定
   ArraySetAsSeries(PBuf, true);
   ArraySetAsSeries(R1Buf, true);
   ArraySetAsSeries(S1Buf, true);
   ArraySetAsSeries(R2Buf, true);
   ArraySetAsSeries(S2Buf, true);
   ArraySetAsSeries(R3Buf, true);
   ArraySetAsSeries(S3Buf, true);
}

SetIndexBuffer()で、上で宣言した7つの配列を指標バッファに関連付けます。さらにArraySetAsSeries()で、それぞれの配列を時系列配列に設定します。

指標計算関数

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[])       //バーのスプレッドの配列
{
   //時系列配列に設定
   ArraySetAsSeries(time, true);

   //指標を表示する範囲
   int limit = rates_total - prev_calculated;
   limit = MathMin(limit, rates_total-PeriodSeconds(PERIOD_D1)/PeriodSeconds()); //プロットの左端をずらす

   //指標表示の繰り返し
   for(int i=0; i<limit; i++)
   {
      int last_shift = iBarShift(_Symbol, PERIOD_D1, time[i])+1; //前日のshift
      double lastH = iHigh(_Symbol, PERIOD_D1, last_shift);      //前日の高値
      double lastL = iLow(_Symbol, PERIOD_D1, last_shift);       //前日の安値
      double lastC = iClose(_Symbol, PERIOD_D1, last_shift);     //前日の終値
      double P = (lastH + lastL + lastC)/3;
      if(P == 0) return 0;

      PBuf[i] = P;
      R1Buf[i] = P + (P - lastL);
      S1Buf[i] = P - (lastH - P);
      R2Buf[i] = P + (lastH - lastL);
      S2Buf[i] = P - (lastH - lastL);
      R3Buf[i] = R1Buf[i] + (lastH - lastL);
      S3Buf[i] = S1Buf[i] - (lastH - lastL);
   }

   return rates_total-1;
}

まず、iBarShift()でチャートの各バーの時間time[i]から日足チャートのバーの位置に変換します。そして、それに1を加えることで前日の日足チャートのバーの位置をlast_shiftに求めます。

前日の高値、安値、終値は、それぞれ、iHigh()iLow()iClose()の2番目の引数に日足を表すPERIOD_D1、3番目の引数にlast_shiftを代入して求めます。

前日の高値lastH、安値lastL、終値lastCより、PIVOT、R1、R2、R3、S1、S2、S3を求め、対応する配列に代入します。

指標を表示する範囲については、マルチタイムフレーム指標を参考にして日足1本分のバーの数だけずらしています。