![見出し画像](https://assets.st-note.com/production/uploads/images/22709034/rectangle_large_type_2_67689250c8fd45b77eeb43155e83349d.jpg?width=1200)
ローソク実体でZigZag 始値終値で描く方法 MT4
どうも、@ひろぽんです。今日は実体部分でZigZagを取得するコードを紹介します。無料です。
ZigZagとは?
チャートで使用するインジケータの一つで、高値と安値を交互に直線で繋いでくれます。高安、高安と上下するラインがジグザグなので、ZigZagと呼ばれています。
要するに直近の高値と安値が分かりやすくなるインジケータです。これによって高値と安値が切り上がってきているから上昇トレンドだみたいな見方が出来ます。
MT4をインストールすれば、初期状態から使えます。(ZigZag.mq4)
一見便利そうですが、ZigZagの問題点にリペイントと言うものがあるので要注意です。リペイントとは、チャートの変化に合わせてラインが描き直されることです。安値を形成して上昇、V字のラインを描くも再下落、前回安値を下回るとV字のラインが下落の直線に描き直されちゃう、なんてことがあります。
ただし、2個以上前のポイントはリペイントされないので、このポイントを元にトレンドラインを自動で引いてライントレードやプライスアクションを考える参考にしようってのが、私の作ったインジケータの内容です。(宣伝)
ZigZagを実体で取るとどうなる?
・赤線 : 高値安値でZigZag
・黄線 : 始値終値(実体)でZigZag
真ん中あたりに注目してほしいんですが、高値安値だとひょこっとヒゲだけ伸ばした変なローソク足も拾っちゃうんですよね。
そこまで大きな問題は無いんですが、トレンドの流れを把握したい時にこのような動きはノイズとなり邪魔です。
一方、実体で描いた黄色の線は傾きは緩やかですが、状況把握がしやすくなります。
どちらを使用するにしても好みなので、もし実体でZigZagを描きたい場合は以下のコードをコピペして使ってください。
注意事項
当サイトに含まれる情報の全ては、情報提供を唯一の目的としたものであり、収益の保証、或いは、直接的に投資助言業務、投資勧誘を行うものではありません。投資方針や時期選択等の最終決定は、リスク等を熟知した上、ご自身で判断されますようお願いいたします。
当サイトの利用、あるいは取引により利用者に生じたいかなる損害についても著者及び発行者はそれに対し、一切の責任を負いません。あらかじめご了承ください。
万が一、損失を被った場合でも、著者は一切の責任を負わないものとします。
実体を使ったZigZagのコード
MT4に既存のZigZagを使用し、一部変更しただけです。
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
input int InpDepth=12; // Depth
input int InpDeviation=5; // Deviation
input int InpBackstep=3; // Backstep
//---- indicator buffers
double ExtZigzagBuffer[];
double ExtHighBuffer[];
double ExtLowBuffer[];
//--- globals
int ExtLevel=3; // recounting's depth of extremums
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(InpBackstep>=InpDepth)
{
Print("Backstep cannot be greater or equal to Depth");
return(INIT_FAILED);
}
//--- 2 additional buffers
IndicatorBuffers(3);
//---- drawing settings
SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers
SetIndexBuffer(0,ExtZigzagBuffer);
SetIndexBuffer(1,ExtHighBuffer);
SetIndexBuffer(2,ExtLowBuffer);
SetIndexEmptyValue(0,0.0);
//---- indicator short name
IndicatorShortName("ZigZag("+string(InpDepth)+","+string(InpDeviation)+","+string(InpBackstep)+")");
//---- initialization done
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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 i,limit,counterZ,whatlookfor=0;
int back,pos,lasthighpos=0,lastlowpos=0;
//double extremum;
double extremum,exOPEN,exCLOSE,exLOW,exHIGH;
double curlow=0.0,curhigh=0.0,lasthigh=0.0,lastlow=0.0;
//--- check for history and inputs
if(rates_total<InpDepth || InpBackstep>=InpDepth)
return(0);
//--- first calculations
if(prev_calculated==0)
limit=InitializeAll();
else
{
//--- find first extremum in the depth ExtLevel or 100 last bars
i=counterZ=0;
while(counterZ<ExtLevel && i<100)
{
if(ExtZigzagBuffer[i]!=0.0)
counterZ++;
i++;
}
//--- no extremum found - recounting all from begin
if(counterZ==0)
limit=InitializeAll();
else
{
//--- set start position to found extremum position
limit=i-1;
//--- what kind of extremum?
if(ExtLowBuffer[i]!=0.0)
{
//--- low extremum
curlow=ExtLowBuffer[i];
//--- will look for the next high extremum
whatlookfor=1;
}
else
{
//--- high extremum
curhigh=ExtHighBuffer[i];
//--- will look for the next low extremum
whatlookfor=-1;
}
//--- clear the rest data
for(i=limit-1; i>=0; i--)
{
ExtZigzagBuffer[i]=0.0;
ExtLowBuffer[i]=0.0;
ExtHighBuffer[i]=0.0;
}
}
}
//--- main loop
for(i=limit; i>=0; i--)
{
//--- find lowest low in depth of bars
//extremum=low[iLowest(NULL,0,MODE_LOW,InpDepth,i)];
exOPEN = open[iLowest(NULL,0,MODE_OPEN,InpDepth,i)];
exCLOSE = close[iLowest(NULL,0,MODE_CLOSE,InpDepth,i)];
extremum = exOPEN<exCLOSE ? exOPEN : exCLOSE;
exLOW = open[i]<close[i] ? open[i] : close[i];
//--- this lowest has been found previously
if(extremum==lastlow)
extremum=0.0;
else
{
//--- new last low
lastlow=extremum;
//--- discard extremum if current low is too high
//if(low[i]-extremum>InpDeviation*Point)
if(exLOW-extremum>InpDeviation*Point)
extremum=0.0;
else
{
//--- clear previous extremums in backstep bars
for(back=1; back<=InpBackstep; back++)
{
pos=i+back;
if(ExtLowBuffer[pos]!=0 && ExtLowBuffer[pos]>extremum)
ExtLowBuffer[pos]=0.0;
}
}
}
//--- found extremum is current low
//if(low[i]==extremum)
if(exLOW==extremum)
ExtLowBuffer[i]=extremum;
else
ExtLowBuffer[i]=0.0;
//--- find highest high in depth of bars
//extremum=high[iHighest(NULL,0,MODE_HIGH,InpDepth,i)];
exOPEN = open[iHighest(NULL,0,MODE_OPEN,InpDepth,i)];
exCLOSE = close[iHighest(NULL,0,MODE_CLOSE,InpDepth,i)];
extremum = exOPEN>exCLOSE ? exOPEN : exCLOSE;
exHIGH = open[i]>close[i] ? open[i] : close[i];
//--- this highest has been found previously
if(extremum==lasthigh)
extremum=0.0;
else
{
//--- new last high
lasthigh=extremum;
//--- discard extremum if current high is too low
//if(extremum-high[i]>InpDeviation*Point)
if(extremum-exHIGH>InpDeviation*Point)
extremum=0.0;
else
{
//--- clear previous extremums in backstep bars
for(back=1; back<=InpBackstep; back++)
{
pos=i+back;
if(ExtHighBuffer[pos]!=0 && ExtHighBuffer[pos]<extremum)
ExtHighBuffer[pos]=0.0;
}
}
}
//--- found extremum is current high
//if(high[i]==extremum)
if(exHIGH==extremum)
ExtHighBuffer[i]=extremum;
else
ExtHighBuffer[i]=0.0;
}
//--- final cutting
if(whatlookfor==0)
{
lastlow=0.0;
lasthigh=0.0;
}
else
{
lastlow=curlow;
lasthigh=curhigh;
}
for(i=limit; i>=0; i--)
{
switch(whatlookfor)
{
case 0: // look for peak or lawn
if(lastlow==0.0 && lasthigh==0.0)
{
if(ExtHighBuffer[i]!=0.0)
{
//lasthigh=High[i];
lasthigh=Open[i]>Close[i] ? Open[i] : Close[i];
lasthighpos=i;
whatlookfor=-1;
ExtZigzagBuffer[i]=lasthigh;
}
if(ExtLowBuffer[i]!=0.0)
{
//lastlow=Low[i];
lasthigh=Open[i]<Close[i] ? Open[i] : Close[i];
lastlowpos=i;
whatlookfor=1;
ExtZigzagBuffer[i]=lastlow;
}
}
break;
case 1: // look for peak
if(ExtLowBuffer[i]!=0.0 && ExtLowBuffer[i]<lastlow && ExtHighBuffer[i]==0.0)
{
ExtZigzagBuffer[lastlowpos]=0.0;
lastlowpos=i;
lastlow=ExtLowBuffer[i];
ExtZigzagBuffer[i]=lastlow;
}
if(ExtHighBuffer[i]!=0.0 && ExtLowBuffer[i]==0.0)
{
lasthigh=ExtHighBuffer[i];
lasthighpos=i;
ExtZigzagBuffer[i]=lasthigh;
whatlookfor=-1;
}
break;
case -1: // look for lawn
if(ExtHighBuffer[i]!=0.0 && ExtHighBuffer[i]>lasthigh && ExtLowBuffer[i]==0.0)
{
ExtZigzagBuffer[lasthighpos]=0.0;
lasthighpos=i;
lasthigh=ExtHighBuffer[i];
ExtZigzagBuffer[i]=lasthigh;
}
if(ExtLowBuffer[i]!=0.0 && ExtHighBuffer[i]==0.0)
{
lastlow=ExtLowBuffer[i];
lastlowpos=i;
ExtZigzagBuffer[i]=lastlow;
whatlookfor=1;
}
break;
}
}
//--- done
return(rates_total);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int InitializeAll()
{
ArrayInitialize(ExtZigzagBuffer,0.0);
ArrayInitialize(ExtHighBuffer,0.0);
ArrayInitialize(ExtLowBuffer,0.0);
//--- first counting position
return(Bars-InpDepth);
}
//+------------------------------------------------------------------+
詳しい説明は省きますが、ローソク足が確定した時、上のヒゲはHighで下のヒゲはLowです。しかし、実体部分の下縁と上縁は、陽線か陰線かによってOpenかCloseか異なります。
これを一か所一か所、三項定理で書き変えただけです。
exOPEN = open[iHighest(NULL,0,MODE_OPEN,InpDepth,i)];
exCLOSE = close[iHighest(NULL,0,MODE_CLOSE,InpDepth,i)];
extremum = exOPEN>exCLOSE ? exOPEN : exCLOSE;
こんな感じで。
ZigZagで取得した高値安値をつないでトレンドラインを描くインジケータも作成しました。高値安値でも実体部分でもトレンドラインを引けるような仕様にしてます。詳しくはこちら>>
ここまで読んでいただき、ありがとうございます。
不具合等があれば、コメントもしくは@ひろぽんにDMしてください。
よろしくお願いします。