1
votes

There seems to be a error in sma calculation in the code below... can someone point out where..

/** * Simple Moving Average (sma) * *

A Moving Average is an indicator that shows the average value of a security's price over a period of time. When calculating a moving average, a mathematical analysis of the security's average value over a predetermined time period is made. As the security's price changes,its average price moves up or down.

* *

A simple, or arithmetic, moving average is calculated by adding the closing price of the security for a number of time periods (e.g., 12 days) and then dividing this total by the number of time periods. The result is the average price of the security over the time period. Simple moving averages give equal weight to each daily price.

* *

Formula:

* * - SUM(Closes of n periods)/n */
<?php 
$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);

class sma
{
/**
 * @var double[]
 */
private $sma;
/**
 * @param double[] $data
 * @param int $range
 * @return double[]
 */
function get( $data, $range )
{
    $position = 0;
    while ( empty( $data[ $position ] ) ) {
        $position++;
    }
    $i = $position;
    while ( true ) {
        if ( empty( $data[ $i + $range - 1 ] ) ) {
            break;
        }
        $temp_sum = 0;
        for ( $j = $i; $j < $i + $range; $j++ ) {
            $temp_sum += $data[ $j ];
        }
        $this->sma[ $i + $range - 1 ] = $temp_sum / $range;
        $i++;
    }
    return $this->sma;
}
}

$mysma = new sma();
$mysma->get($data,5); $sma = $mysma->get();
echo mysma;

?>

Also sma calculation in other code seems to be easier.. a few example is here.. if someone has done it in php similarly..??

(defn moving-average
[coll n]
(cond
(< n 1) nil
(= n 1) coll
:else   (let [sums (reductions + 0 coll)]
          (map #(/ (- %1 %2) n) (drop n sums) sums))))

(time (doall (moving-average coll n)))
# "Elapsed time: 9.184 msecs"

Also this..

double[] MovingAverage(int period, double[] source)
{
    var ma = new double[source.Length];

    double sum = 0;
    for (int bar = 0; bar < period; bar++)
        sum += source[bar];

    ma[period - 1] = sum/period;

    for (int bar = period; bar < source.Length; bar++)
        ma[bar] = ma[bar - 1] + source[bar]/period
                              - source[bar - period]/period;

    return ma;
}
1
"There seems to be a error in sma calculation in the code below" and the error is?Marco Mura
the range is to be less.. yes 5, changed.. the error is there is no output.. it goes into a loop.. ""Warning: Missing argument 1 for sma::get(), called in P:\MOWES WAMP REL\MOWES\www\sma.php on line 51 and defined in P:\MOWES WAMP REL\MOWES\www\sma.php on line 28 Warning: Missing argument 2 for sma::get(), called in P:\MOWES WAMP REL\MOWES\www\sma.php on line 51 and defined in P:\MOWES WAMP REL\MOWES\www\sma.php on line 28 Fatal error: Maximum execution time of 120 seconds exceeded in P:\MOWES WAMP REL\MOWES\www\sma.php on line 31 ""Ajmal
The output is [4=>3,5=>4,6=>5,etc.] when you remove the $mysma->get(); call and var_dump($mysma->get($data, 5);.Ja͢ck

1 Answers

1
votes

Here's a translation based on the last piece of code in your question:

function get(array $data, $range)
{
    $sum = array_sum(array_slice($data, 0, $range));

    $result = array($range - 1 => $sum / $range);

    for ($i = $range, $n = count($data); $i != $n; ++$i) {
        $result[$i] = $result[$i - 1] + ($data[$i] - $data[$i - $range]) / $range;
    }

    return $result;
}