SMA_CONV
This function smooths a time series by applying a simple moving-average kernel through discrete convolution.
For a window length w, the uniform kernel assigns equal weight 1/w to each value in the window. The smoothed value at index t is:
\text{SMA}_t = \frac{1}{w}\sum_{i=0}^{w-1} x_{t-i}
Different convolution modes control output length and boundary behavior.
Excel Usage
=SMA_CONV(data, window, mode)
data(list[list], required): Time-series observations as a 2D range (data points).window(int, optional, default: 3): Number of observations per averaging window (points).mode(str, optional, default: “valid”): Convolution output mode controlling boundary handling and output length.
Returns (list[list]): Column vector of simple moving-average values computed from the input series.
Example 1: Valid-mode SMA on increasing series
Inputs:
| data | window | mode | ||||
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 3 | valid |
Excel formula:
=SMA_CONV({1,2,3,4,5}, 3, "valid")
Expected output:
| Result |
|---|
| 2 |
| 3 |
| 4 |
Example 2: Same-mode SMA preserves series length
Inputs:
| data | window | mode | |||
|---|---|---|---|---|---|
| 10 | 12 | 14 | 16 | 2 | same |
Excel formula:
=SMA_CONV({10,12,14,16}, 2, "same")
Expected output:
| Result |
|---|
| 5 |
| 11 |
| 13 |
| 15 |
Example 3: Full-mode SMA includes boundary overlap
Inputs:
| data | window | mode | ||
|---|---|---|---|---|
| 3 | 6 | 9 | 2 | full |
Excel formula:
=SMA_CONV({3,6,9}, 2, "full")
Expected output:
| Result |
|---|
| 1.5 |
| 4.5 |
| 7.5 |
| 4.5 |
Example 4: Scalar input is normalized to 2D range
Inputs:
| data | window | mode |
|---|---|---|
| 8 | 1 | valid |
Excel formula:
=SMA_CONV(8, 1, "valid")
Expected output:
8
Python Code
import numpy as np
def sma_conv(data, window=3, mode='valid'):
"""
Compute a simple moving average using discrete convolution with a uniform window.
See: https://numpy.org/doc/stable/reference/generated/numpy.convolve.html
This example function is provided as-is without any representation of accuracy.
Args:
data (list[list]): Time-series observations as a 2D range (data points).
window (int, optional): Number of observations per averaging window (points). Default is 3.
mode (str, optional): Convolution output mode controlling boundary handling and output length. Valid options: Full, Same, Valid. Default is 'valid'.
Returns:
list[list]: Column vector of simple moving-average values computed from the input series.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
data = to2d(data)
if not isinstance(data, list) or not all(isinstance(row, list) for row in data):
return "Error: Invalid input - data must be a 2D list"
if mode not in ("full", "same", "valid"):
return "Error: mode must be one of 'full', 'same', or 'valid'"
if window < 1:
return "Error: window must be at least 1"
values = []
for row in data:
for item in row:
try:
values.append(float(item))
except (TypeError, ValueError):
continue
if not values:
return "Error: data must contain at least one numeric value"
if mode == "valid" and len(values) < window:
return "Error: data length must be at least as large as window for valid mode"
kernel = np.ones(int(window), dtype=float) / float(window)
result = np.convolve(np.asarray(values, dtype=float), kernel, mode=mode)
return [[float(x)] for x in np.asarray(result, dtype=float).tolist()]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Time-series observations as a 2D range (data points).
Number of observations per averaging window (points).
Convolution output mode controlling boundary handling and output length.