# ポイント&フィギュア チャート Point and Figure Chart # 引数 値幅 値 ($PriceRange, \@Price) # 戻り値 PointandFigureChart (@PointAndFigureChart) sub POINTANDFIGURECHART{ my ($PriceRange, $Price) = @_; my @PointAndFigureChart = (); my %TempPointAndFigureChart = (); my $TempHigh = 0; my $TempLow = 0; my $PrevTempHigh = 0; my $PrevTempLow = 0; my $Highest = 0; my $Lowest = 0; my $Reverse = 3; my $Up = 1; my $Down = 1; my $Check = 0; my $Number = 0; my $count = @$Price - 1; # 値幅と配列数の確認 if(($PriceRange <= 0) || ($count < 0)){ return 0; } # 計算 $TempHigh = $PrevTempHigh = $Highest = int($$Price[$count] / $PriceRange) * $PriceRange; $TempLow = $PrevTempLow = $Lowest = int($$Price[$count] / $PriceRange) * $PriceRange; for(my $i = $count - 1; $i >= 0; $i--){ if($Up == 1){ if(($TempHigh - ($PriceRange * ($Reverse + 1))) >= $$Price[$i]){ # トレンドの変化 陰転 $PrevTempHigh = $TempHigh - $PriceRange; $TempLow = (int($$Price[$i] / $PriceRange) * $PriceRange); # 同値でないならば、値幅を足す $TempLow = $TempLow + $PriceRange if($TempLow < $$Price[$i]); # Flag $Check = 1; }else { # 高値更新 if(($TempHigh + $PriceRange) < $$Price[$i]){ $TempHigh = (int($$Price[$i] / $PriceRange) * $PriceRange); } } }else { if($Down == 1){ if(($TempLow + ($PriceRange * ($Reverse + 1))) <= $$Price[$i]){ # トレンドの変化 陽転 $PrevTempLow = $TempLow + $PriceRange; $TempHigh = (int($$Price[$i] / $PriceRange) * $PriceRange); # Flag $Check = 1; }else { # 安値更新 if(($TempLow - $PriceRange) > $$Price[$i]){ $TempLow = (int($$Price[$i] / $PriceRange) * $PriceRange); # 同値でないならば、値幅を足す $TempLow = $TempLow + $PriceRange if($TempLow < $$Price[$i]); } } } } # 非時系列 if(($Check == 1) || ($i == 0)){ # ポイント&フィギュア Point and Figure if($Up == 1){ $TempPointAndFigureChart{'high'}->[$Number] = $TempHigh; $TempPointAndFigureChart{'low'}->[$Number] = $PrevTempLow; $TempPointAndFigureChart{'flag'}->[$Number] = 1; # 下降トレンドに転換 # Flag $Up = 0; $Down = 1; # 最高値 $Highest = $TempHigh if($Highest < $TempHigh); }else { if($Down == 1){ $TempPointAndFigureChart{'high'}->[$Number] = $PrevTempHigh; $TempPointAndFigureChart{'low'}->[$Number] = $TempLow; $TempPointAndFigureChart{'flag'}->[$Number] = -1; # 上昇トレンドに転換 # Flag $Up = 1; $Down = 0; # 最安値 $Lowest = $TempLow if($Lowest > $TempLow); } } $Number++; $Check = 0; } } # UP = O DOWN = X # ポイント&フィギュア チャート Point and Figure Chart my $Range = ($Highest - $Lowest) / $PriceRange; for(my $i = 0; $i < $Number; $i++){ my $high = $TempPointAndFigureChart{'high'}->[$i]; my $low = $TempPointAndFigureChart{'low'}->[$i]; my $flag = $TempPointAndFigureChart{'flag'}->[$i]; for(my $j = 0; $j <= $Range; $j++){ my $p = $Highest - ($PriceRange * $j); if(($low <= $p) && ($p < $high)){ if($flag == 1){ # UP = X $PointAndFigureChart[$j] .= "X"; }elsif ($flag == -1){ # DOWN = O $PointAndFigureChart[$j] .= "O"; } }else { # Flagが無いなら空白 $PointAndFigureChart[$j] .= " "; } } } # 右に価格帯をつける for(my $i = 0; $i <= $Range; $i++){ my $p = $Highest - ($PriceRange * $i); $PointAndFigureChart[$i] .= "\t$p"; } return @PointAndFigureChart; }