/** * Weighted n-point moving average (WMA) * * Similar to simple n-point moving average, * however, each n-point has a weight associated with it, * and instead of dividing by n, we divide by the sum of the weights. * * Each weighted average = ∑(weighted values) / ∑(weights) * * @param array $numbers * @param int $n n-point moving average * @param array $weights Weights for each n points * * @return array of averages * * @throws BadDataException if number of weights is not equal to number of n-points */ public static function weightedMovingAverage(array $numbers, int $n, array $weights) : array { if (count($weights) !== $n) { throw new Exception\BadDataException('Number of weights must equal number of n-points'); } $m = count($numbers); $∑w = array_sum($weights); $WMA = []; for ($i = 0; $i <= $m - $n; $i++) { $∑wp = array_sum(Map\Multi::multiply(array_slice($numbers, $i, $n), $weights)); $WMA[] = $∑wp / $∑w; } return $WMA; }