自作インジケーター|リペイントしないZigZagを作ろう!サンプルプログラムあり

Sponsor Link








皆さん、みーでございます。

今回はサインツールとは違いますが、自作インジケーターとして”リペイントしないZigZag”を作成してみましょう!

ZgiZagを使用サインツールは、以下の記事を参照してくださいね。

自作サインツール|ZigZagの頂点で高勝率サインを出す方法(サンプルプログラムあり)

2021年12月27日

ZigZagはリペイントする

非常に多くの方が使用しているインジケータのZigZagですが、リペイントすることで有名ですよね。それもそのはずで、反転する頂点を100%リアルに見つけることは不可能であり、リペイントしながら頂点を作成していきます。

リペイントしないZigZagがあれば・・・凄い勝率の高いサインツールが出来る!?って考えた方も多いかと思いますが、そんなサインツールは作成できません。ZigZagはリペイントするためサインツールには不向きなのですが、例えば、大きな相場の方向性などを見つけるには有効なインジケーターです。

そうした、大きな相場の方向性を見つける材料となるインジケーターとして、今回は、リペイントしないZigZagの作成方法について、解説していきます。

また、ZigZagのソースは公開されていますが、高値・安値の情報や、リペイントのために頂点を削除する処理などが組み込まれており、処理速度も遅いです。インジケーターはMT4に表示され、処理速度が遅いとイライラしたりしますよね。やっぱり、軽量なインジケーターの方が良いですので、今回は、シンプルな独自ZigZagロジックにて、ZigZagと同じ線を表示する、リペイントしないZigZagインジケーターをご紹介します。

リペイントしないZigZagのサンプル

以下のMQLコードが、リペイントしないZigZagのサンプルコードとなります。(ちゃんと動作します)

#property indicator_chart_window
#property indicator_buffers 1

extern int InpDepth_NRP = 12;
double ExtNRPZigZagBuffer[];
static int tick_count = 0;

int init()  {
   SetIndexStyle(0,DRAW_SECTION,STYLE_SOLID,1,clrRed);
   SetIndexStyle(0,DRAW_SECTION);
   SetIndexBuffer(0,ExtNRPZigZagBuffer);
   return(INIT_SUCCEEDED);
}

int start() {
   int counted_bars=IndicatorCounted(); 
   int limit = Bars - counted_bars;
   
   if(tick_count == 0){
      getZigzagNRP(limit,0);
   }
   else {
      getZigzagNRP(300,0);
   }
   tick_count++;

   return(0);
}

//+------------------------------------------------------------------+
// NoRepaint ZigZag情報取得
//+------------------------------------------------------------------+
void getZigzagNRP(int limit,int index){
   int ZagAA, ZagNN, zup, zdn;
   double ZZLL, ZZHH, BBHH, BBLL; 

   for(int i=limit; i>=index; i--){
      ZZLL = Low [iLowest (NULL,0,MODE_LOW, InpDepth_NRP,i+1)];
      ZZHH = High[iHighest(NULL,0,MODE_HIGH,InpDepth_NRP,i+1)];

      if(Low[i]<ZZLL && High[i]>ZZHH){
         ZagAA=2;
         if(ZagNN==1){
            zup=i+1;
         }
         if(ZagNN==-1){
            zdn=i+1;
         }
      } else {
         if(Low[i]<ZZLL){
            ZagAA=-1;
         }
         if(High[i]>ZZHH){
            ZagAA=1;
         }
      }
      if(ZagAA!=ZagNN && ZagNN!=0){
        if(ZagAA==2){
           ZagAA=-ZagNN;
           BBHH=High[i];
           BBLL=Low[i];
        }
        if(ZagAA==-1){
           ExtNRPZigZagBuffer[zup]=BBHH;
        } 
        if(ZagAA==1){
           ExtNRPZigZagBuffer[zdn]=BBLL;
        }
        BBHH=High[i];
        BBLL=Low[i];
     }
     if(ZagAA==1){
        if(High[i]>=BBHH){
           BBHH=High[i];
           zup=i;
        }
     } 
     if(ZagAA==-1){
        if(Low[i]<=BBLL){
           BBLL=Low[i];
           zdn=i;
        }
     } 
     ZagNN=ZagAA;
   }
}

 

実行結果

ZigZagの赤い線が表示されていると思います。そして、全て確定している頂点ですので、確定していない頂点は表示されていません。

この相場は、上昇傾向になりますよね。このインジケーターでは、少し長期的な相場の方向性を見極めるのに役に立つかと思います。

サンプルコードの説明

重要な個所のみ、サンプルコードの説明をします。

extern int InpDepth_NRP = 12;
double ExtNRPZigZagBuffer[];
static int tick_count = 0;

InpDepth_NRPですが、これはZigZagのパラメーターと同様です。

ExtNRPZigZagBufferは、ZigZagの頂点を格納し表示する配列ですね。

tick_countは、このインジケーターが何回呼び出されたかをカウントする、重要な変数です。この変数を使用している理由ですが、初回起動時は全てのローソク足を対象にZigZagの頂点を見つけます。2回目以降は、全てのローソク足に対するZigZagの頂点を見つける必要はありませんので、初回起動か、2回目以降かを見極めるための変数となります。

int init()  {
   SetIndexStyle(0,DRAW_SECTION,STYLE_SOLID,1,clrRed);
   SetIndexStyle(0,DRAW_SECTION);
   SetIndexBuffer(0,ExtNRPZigZagBuffer);
   return(INIT_SUCCEEDED);
}

上記は、赤色の線、表示する頂点は”ExtNRPZigZagBuffer”に格納されているという定義を行っています。”ExtNRPZigZagBuffer”に0以外の値が入っている場合、その頂点を結んだZigZagが表示されるということになります。

   if(tick_count == 0){
      getZigzagNRP(limit,0);
   }
   else {
      getZigzagNRP(300,0);
   }

tick_countの分岐処理ですね。tick_count が0の場合は初回起動、tick_count が0以外の場合は、2回目以降の処理であることが分かります。初回起動時は、getZigzagNRP()のパラメーターに、全てのローソク足を対象して呼び出します。2回目以降は、300本のローソク足を対象として、getZigzagNRP()のパラメーターを呼び出します。

なぜ、300か?という点ですが、もっと良い方法としては、直近の確定している頂点を求めて、その位置からgetZigzagNRP()を呼び出すのが、一番良い方法ですが、少し説明が長くなりますし、300本のローソーク足の中で、確定した頂点がないことは、ほぼありえませんので、説明の都合上、300としています。(ちゃんと動作するので安心してください)

//+------------------------------------------------------------------+
// NoRepaint ZigZag情報取得
//+------------------------------------------------------------------+
void getZigzagNRP(int limit,int index){
   int ZagAA, ZagNN, zup, zdn;
   double ZZLL, ZZHH, BBHH, BBLL; 

   for(int i=limit; i>=index; i--){
      ZZLL = Low [iLowest (NULL,0,MODE_LOW, InpDepth_NRP,i+1)];
      ZZHH = High[iHighest(NULL,0,MODE_HIGH,InpDepth_NRP,i+1)];

      if(Low[i]<ZZLL && High[i]>ZZHH){
         ZagAA=2;
         if(ZagNN==1){
            zup=i+1;
         }
         if(ZagNN==-1){
            zdn=i+1;
         }
      } else {
         if(Low[i]<ZZLL){
            ZagAA=-1;
         }
         if(High[i]>ZZHH){
            ZagAA=1;
         }
      }
      if(ZagAA!=ZagNN && ZagNN!=0){
        if(ZagAA==2){
           ZagAA=-ZagNN;
           BBHH=High[i];
           BBLL=Low[i];
        }
        if(ZagAA==-1){
           ExtNRPZigZagBuffer[zup]=BBHH;
        } 
        if(ZagAA==1){
           ExtNRPZigZagBuffer[zdn]=BBLL;
        }
        BBHH=High[i];
        BBLL=Low[i];
     }
     if(ZagAA==1){
        if(High[i]>=BBHH){
           BBHH=High[i];
           zup=i;
        }
     } 
     if(ZagAA==-1){
        if(Low[i]<=BBLL){
           BBLL=Low[i];
           zdn=i;
        }
     } 
     ZagNN=ZagAA;
   }
}

上記が独自ZigZagとなります。頂点が確定した場合に、ExtNRPZigZagBufferにHigh/Lowの値が設定されます。

このロジックは、直近のローソク足(InpDepth_NRPで指定した本数分)から高値、安値を見つけ、現在の相場の方向性(ZagNN)と異なる場合に、頂点が確定したと判断し、ExtNRPZigZagBufferに高値・安値を設定するものです。ここは、あまり深く考えず、コピーしてお使いいただくのが良いかと思います。

いかがでしたでしょうか?

リペイントしないZigZagのインジケーターも、100行程度のソースコードで実現できてしまいます。このインジケーターをベースに、現在の方向性を導きだして、サインツールの根拠に活用するなど、実は色々と活用できるシーンはあると思いますので、ぜひ、ご活用いただければと思います。ソースは無料公開しているので、ご自由に活用してください。

サインツール作成の記事一覧はこちら

Sponsor Link








コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です