# ジグザグ 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(($X1 != $i) && (($Highest - $PriceRange) >= $$Low[$i])){ # Flag $Check = 1; } }else { if($Down == 1){ # 安値更新 if($Lowest >= $$Low[$i]){ $Lowest = $$Low[$i]; $X1 = $i; } # 最安値==安値ならトレンドを反転させない if(($X1 != $i) && (($Lowest + $PriceRange) <= $$High[$i])){ # Flag $Check = 1; } } } if($Check == 1){ my @Line = (); if($Up == 1){ # 上昇トレンドの終わり my $Y1 = $Highest; my $Y2 = $Lowest; @Line = &LINE($X1, $X2, $Y1, $Y2); # 下降トレンドへ $Lowest = $$Low[$i]; # Flag $Up = 0; $Down = 1; }else { if($Down == 1){ # 下降トレンドの終わり my $Y1 = $Lowest; my $Y2 = $Highest; @Line = &LINE($X1, $X2, $Y1, $Y2); # 上昇トレンドへ $Highest = $$High[$i]; # Flag $Up = 1; $Down = 0; } } 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; } # 直線 # 引数 値幅 値 ($X1, $X2, $Y1, $Y2) # 戻り値 直線 (@line) sub LINE { my ($X1, $X2, $Y1, $Y2) = @_; my @line = (); my $m = ($Y2 - $Y1) / ($X2 - $X1); my $diff = $X2 - $X1; for(my $x = 0; $x < $diff; $x++){ $line[$x] = ($m * $x) + $Y1; } return @line; }