<?php
/**
* Finasystem version 0.4 Lin Hai - Technical Analysis Library in PHP
*Release: 14/10/2006
*Copyright (C) 2006 Rudy Zuck
*mailto:rudy[-at-]zuck.fr
*web:http://sourceforge.net/projects/finasystem
*
*This program is free software; you can redistribute it and/or
*modify it under the terms of the GNU General Public License
*as published by the Free Software Foundation; either version 2
*of the License, or any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program; if not, write to the Free Software
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* Zig Zag (zigzag)
*
*<p>The Zig Zag filters out small movements in price to highlight trends.
*It looks for price moves greater than the threshold level and plots straight lines
*between those points. The Zig Zag is more of a visual tool than an indicator. It is
*non-predictive, in fact, the formula looks forward in time to find the zig zag points.
*The purpose of the Zig Zag is to make chart patterns clearer.</p>
*
*<p>Formula:</p>
*
*<p>There is no clear cut formula for the zig zag indicator like, for
*example, the Moving Average indicator. The basic procedure to draw it
*is the following:</p>
*
* - Decide a percentage filter (for example 10% if you want to filter out all movements less than 10%)
* - Choose an arbitrary date point in your chart.
* - Move forward until you see that price rises or decreases 10% or more from your chosen point. Draw a line that connects your original point and this one.
* - Let's assume that it rose 10% or more. Now you keep extending the line forward until it falls 10% from the highest high price in the "rising period". When this happens, connect that highest high with the new 10% lower price. This could result in erasing a part of the previous line, because you don't know that the highest high is actually a highest high until you see price drop 10%.
* - Repeat this procedure .
*
* @author Rudy Zuck <rudy[-at-]zuck.fr>
* @copyright Copyright, 2006, Rudy Zuck
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version 0.4
* @package fs_ta
*/
class zigzag{
/**
* Return only +1 or -1
* @var int[]
*/
private $zigzag;
/**
* $pr < 1
* @param double[] $data
* @param double $pr
* @return double[]
*/
function get($data,$pr){
$current = 0;
$best = 0;
//initialization
while (true){
$roc = ($data[$current] - $data[$best]) / $data[$best];
if ($roc < -$pr){
$best = $current;
$trend = -1;
$current++;
break;
}
if ($roc > $pr){
$best = $current;
$trend = 1;
$current++;
break;
}
$current++;
}
//Main part
$i=0;
while ($current<count($data)){
if($trend == 1){
if($data[$current] >= $data[$best]) {
$best = $current;
}
if ($data[$current] <= ($data[$best] - ($data[$best] * $pr))){
for($i;$i!=$best;$i++){
$this->zigzag[$i] = $trend;
}
$i=$best;
$best = $current;
$trend = -1;
$this->zigzag[$current] = $trend;
}
}
if($trend == -1){
if($data[$current] <= $data[$best]) {
$best = $current;
}
if ($data[$current] >= ($data[$best] + ($data[$best] * $pr))){
for($i;$i!=$best;$i++){
$this->zigzag[$i] = $trend;
}
$i=$best;
$best = $current;
$trend = 1;
$this->zigzag[$current] = $trend;
}
}
$current++;
}
//Finalization
$size_data = count($data);
for($i;$i<$size_data;$i++){
$this->zigzag[$i] = $trend;
}
return $this->zigzag;
}
}
?>