# ジグザグ ZIGZAG # 引数 値幅 値 ($PriceRange, \@High, \@Low) # 戻り値 ジグザグ (@zigzag) sub ZIGZAG{ my ($PriceRange, $High, $Low) = @_; my @zigzag = (); my $Highest = 0; my $Lowest = 0; my $X1 = 0; my $X2 = 0; my $Up = 1; my $Down = 1; my $Check = 0; my $count = @$High - 1; # 値幅と配列数の確認 if(($PriceRange <= 0) || ($count < 0) || (@$High != @$Low)){ return 0; } # 計算 $Highest = $$High[$count]; $Lowest = $$Low[$count]; $X2 = $count; $X1 = $X2 - 1; for(my $i = $count - 1; $i >= 0; $i--){ if($Up == 1){ # 高値更新 if($Highest <= $$High[$i]){ $Highest = $$High[$i]; $X1 = $i; } # 最高値==高値ならトレンドを反転させない if(($Highest != $$High[$i]) && (($Highest - $PriceRange) >= $$Low[$i])){ # 連続してトレンドが変化した場合 $X1 = $i if(($i == ($X2 - 1)) && ($X1 == $X2)); # Flag $Up = 0; $Down = 1; $Check = 1; } }else { if($Down == 1){ # 連続してトレンドが変化した場合 $X1 = $i if(($i == ($X2 - 1)) && ($X1 == $X2)); # 安値更新 if($Lowest >= $$Low[$i]){ $Lowest = $$Low[$i]; $X1 = $i; } # 最安値==安値ならトレンドを反転させない if(($Lowest != $$Low[$i]) && (($Lowest + $PriceRange) <= $$High[$i])){ # Flag $Up = 1; $Down = 0; $Check = 1; } } } if($Check == 1){ my @Line = (); if($Up == 1){ # 下降トレンドからの転換 my $Y1 = $Lowest; my $Y2 = $Highest; @Line = &LINE($X1, $X2, $Y1, $Y2); # 上昇トレンドへ $Highest = $$High[$i]; }else { if($Down == 1){ # 上昇トレンドからの転換 my $Y1 = $Highest; my $Y2 = $Lowest; @Line = &LINE($X1, $X2, $Y1, $Y2); # 下降トレンドへ $Lowest = $$Low[$i]; } } for(my $j = 0; $j < @Line; $j++){ # ジグザグ ZIGZAG $zigzag[$X1 + $j] = $Line[$j]; } # 最高値・最安値の位置 $X2 = $X1; $X1 = $i; # Flag $Check = 0; } } # 残り my @Line = (); if($Up == 1){ # 上昇中 @Line = &LINE(0, $X2, $$High[0], $Lowest); }else { if($Down == 1){ # 下降中 @Line = &LINE(0, $X2, $$Low[0], $Highest); } } for(my $i = 0; $i < @Line; $i++){ # ジグザグ ZIGZAG $zigzag[$i] = $Line[$i]; } return @zigzag; }