Location: PHPKode > projects > Finasystem > fs_ta/zigzag.php
<?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; 
		
	}	
}
?>
Return current item: Finasystem