EMAベースのZigZagの書き方

1.きっかけ

 EMAベースのZigZagってあんま見ないんで作ってみようかなっていうか,前に作ったんだけどどのパソコンに入ってるっけっていう状態

2.そもそもZigZagってどうやってるっけ

 高値,安値を探してジグザグにする感じ。最低算出期間とかもろもろ決められる。ダウ理論っぽいのが視覚化できる。

3.EMAべースにするとどうなる?

 こんなんなると思います。
 f:id:iinebot:20201112124519p:plain

4.実装

 実装するにあたり一番大事なことは,もとのZigZagのコードを見ないことです。
 なぜなら,元のコードを見ると,それを理解するところから始めなくてはいけません。
 コードの読み解く力は育まれる可能性が高いですが,ぼくには合ってません。
 自分でまず書いてみて,うまくいかなかったら見て参考にするくらいが良いと思います。
 あんまりちゃんとしてないけど・・・。

//+------------------------------------------------------------------+
//|                                                    ZigZagEMA.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 6
#property indicator_color2 clrBlack
#property indicator_type2 DRAW_LINE
#property indicator_color3 clrCyan
#property indicator_type3 DRAW_LINE
#property indicator_color4 clrMagenta
#property indicator_color5 clrBlue
#property indicator_color6 clrRed

// 設定項目
input string dummy1 = "---------------------";//MAの期間
input int   MAband = 25;//MAの期間
input ENUM_MA_METHOD MA_Method1  = MODE_EMA;  //移動平均の種類

double maValue[];
double zigZagValue[];
double zigZagHighValue[];
double zigZagLowValue[];
double lowbuf[];
double highbuf[];

bool highTrend = false;
bool lowTrend = false;
bool highMode = false;
bool lowMode = false;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   IndicatorBuffers(6);

   SetIndexBuffer(0, maValue);

   SetIndexBuffer(1, zigZagValue);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2,Magenta);

   SetIndexBuffer(2, zigZagHighValue);
   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,3,clrAqua);

   SetIndexBuffer(3, zigZagLowValue);
   SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,3,clrYellow);

   SetIndexBuffer(4, highbuf);
   SetIndexBuffer(5, lowbuf);
//
//   SetIndexStyle(4,DRAW_ARROW,STYLE_SOLID,5,Blue);
//   SetIndexArrow(4,233);
//
//   SetIndexStyle(5,DRAW_ARROW,STYLE_SOLID,5,Red);
//   SetIndexArrow(5,234);
//SetIndexEmptyValue(0,0.0);
//---
   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[])
  {
//---

   int limit;

   int i = 0;
   int counted_bars=IndicatorCounted();
   if(counted_bars<0)
      return(-1);
   limit=Bars-counted_bars-1;

   int counter = 0;
   int hPosition,lPosition;
   double hValue,lValue;
   for(i = 0 ; i < limit  ; i++)
     {
      lowbuf[i] = EMPTY_VALUE;
      highbuf[i] = EMPTY_VALUE;
      zigZagValue[ i ] = EMPTY_VALUE;
      zigZagHighValue[ i ] = EMPTY_VALUE;
      zigZagLowValue[ i ] = EMPTY_VALUE;
      maValue[i] = 0.0;                  // インジケータ1に算出結果を設定
     }
   for(i = 0 ; i < limit  ; i++)
     {
      maValue[i] = iMA(
                      NULL,            // 通貨ペア
                      0,               // 時間軸
                      MAband,          // MAの平均期間
                      0,               // MAシフト
                      MA_Method1,      // MAの平均化メソッド
                      PRICE_CLOSE,     // 適用価格
                      i                // シフト
                   );
      zigZagValue[ i ]  =  maValue[i];

     }

   highTrend = true;

   for(i = limit - 1  ; i >= 0  ; i--)
     {
      if(zigZagValue[i + 1] <= zigZagValue[i])//upper trend
        {
         if(lowMode)//down trend からやってきた
           {
            zigZagHighValue[i] = zigZagValue[i];
           }
         lowMode = false;
         highMode = true;


        }

      else
         if(zigZagValue[i + 1] > zigZagValue[i])//down trend
           {
            if(highMode) //upper trendからやってきた
              {
               //lowbuf[i] = zigZagValue[i];

               zigZagHighValue[i] = zigZagValue[i];

              }
            lowMode = true;
            highMode = false;

           }


     }
     
     zigZagHighValue[0] = maValue[0];

//補完作業

   int count,j;
   count = 0;
   double a,b;
   for(i = limit - 1  ; i >= 0  ; i--)
     {
      if(zigZagHighValue[i] == EMPTY_VALUE)
        {
         count += 1;

        }
      else
        {
         if(count ==0)
           {
            lowbuf[i] =zigZagHighValue[i];
           }
         else
           {
            a = (zigZagHighValue[i + count + 1] -zigZagHighValue[i]) / count;
            b = zigZagHighValue[i]  - i * a;
            for(j = i; j <= i+count; j++)
              {
               lowbuf[j] = a * j + b;
              }
            count = 0;
            i += 1;

           }
        }

     }


//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {

  }//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

//---

//+------------------------------------------------------------------+