Moving Average Calculator
Computes moving averages for a numeric series with configurable window size.
Function signature
ogCalculateMovingAverageSeries(values = array(), options = array())
Categories
- Analytics and Reports
Parameters
valuesNumeric values in chronological order.optionsOptional keys: window, allow_partial. Recognized keys: `allow_partial`, `window`.Return value
Short public-safe status message.
- window
- allow_partial
- series
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Computes moving averages for a numeric series with configurable window size.
*
* @param array $values Numeric values in chronological order.
* @param array $options Optional keys: window, allow_partial.
* @return array Moving-average rows with index, value, average, and window count.
*/
function ogCalculateMovingAverageSeries($values = array(), $options = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($values)) {
$result['message'] = 'Values must be an array.';
return $result;
}
if (!is_array($options)) {
$options = array();
}
$window = 3;
if (!empty($options['window'])) {
$window = (int)$options['window'];
}
if ($window < 1) {
$window = 1;
}
$allow_partial = false;
if (!empty($options['allow_partial'])) {
$allow_partial = true;
}
$numeric_values = array();
foreach ($values as $value) {
if (is_numeric($value)) {
$numeric_values[] = (float)$value;
}
}
if (count($numeric_values) < 1) {
$result['message'] = 'No numeric values were supplied.';
return $result;
}
if (!$allow_partial && count($numeric_values) < $window) {
$result['message'] = 'Window is larger than the available series.';
return $result;
}
$rows = array();
for ($index = 0; $index < count($numeric_values); $index++) {
$start = $index - $window + 1;
if ($start < 0) {
$start = 0;
}
$window_values = array_slice($numeric_values, $start, ($index - $start + 1));
if (!$allow_partial && count($window_values) < $window) {
continue;
}
$average = array_sum($window_values) / count($window_values);
$rows[] = array(
'index' => $index,
'value' => $numeric_values[$index],
'average' => $average,
'window_count' => count($window_values)
);
}
$result['success'] = true;
$result['message'] = 'Moving average series calculated.';
$result['data'] = array(
'window' => $window,
'allow_partial' => $allow_partial,
'series' => $rows
);
return $result;
}