WMA
This function computes a rolling weighted moving average (WMA) where each window position uses a specified weight.
For window length m and weights w_0,\dots,w_{m-1}, each output value is:
\text{WMA}_t = \frac{\sum_{i=0}^{m-1} w_i x_{t-m+1+i}}{\sum_{i=0}^{m-1} w_i}
The function returns values only for complete windows, beginning at the first index where all weights can be applied.
Excel Usage
=WMA(data, weights)
data(list[list], required): Time-series observations as a 2D range (data points).weights(list[list], required): Weight coefficients as a 2D range (relative weights).
Returns (list[list]): Column vector of rolling weighted moving-average values for complete windows.
Example 1: WMA with linearly increasing weights
Inputs:
| data | weights | ||||||
|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 1 | 2 | 3 |
Excel formula:
=WMA({1,2,3,4,5}, {1,2,3})
Expected output:
| Result |
|---|
| 2.33333 |
| 3.33333 |
| 4.33333 |
Example 2: WMA with equal weights matches rolling mean
Inputs:
| data | weights | ||||
|---|---|---|---|---|---|
| 2 | 4 | 6 | 8 | 1 | 1 |
Excel formula:
=WMA({2,4,6,8}, {1,1})
Expected output:
| Result |
|---|
| 3 |
| 5 |
| 7 |
Example 3: Single weight returns original series
Inputs:
| data | weights | ||
|---|---|---|---|
| 7 | 9 | 11 | 5 |
Excel formula:
=WMA({7,9,11}, {5})
Expected output:
| Result |
|---|
| 7 |
| 9 |
| 11 |
Example 4: Scalar input with scalar weight
Inputs:
| data | weights |
|---|---|
| 10 | 1 |
Excel formula:
=WMA(10, 1)
Expected output:
10
Python Code
import numpy as np
def wma(data, weights):
"""
Compute a rolling weighted moving average using user-supplied weights.
See: https://en.wikipedia.org/wiki/Moving_average#Weighted_moving_average
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).
weights (list[list]): Weight coefficients as a 2D range (relative weights).
Returns:
list[list]: Column vector of rolling weighted moving-average values for complete windows.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
data = to2d(data)
weights = to2d(weights)
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 not isinstance(weights, list) or not all(isinstance(row, list) for row in weights):
return "Error: Invalid input - weights must be a 2D list"
series = []
for row in data:
for item in row:
try:
series.append(float(item))
except (TypeError, ValueError):
continue
win = []
for row in weights:
for item in row:
try:
win.append(float(item))
except (TypeError, ValueError):
continue
if not series:
return "Error: data must contain at least one numeric value"
if not win:
return "Error: weights must contain at least one numeric value"
weight_sum = float(np.sum(win))
if weight_sum == 0:
return "Error: weights must sum to a nonzero value"
window = len(win)
if len(series) < window:
return "Error: data length must be at least as large as the number of weights"
out = []
for end_idx in range(window - 1, len(series)):
segment = series[end_idx - window + 1:end_idx + 1]
val = float(np.dot(segment, win) / weight_sum)
out.append([val])
return out
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Time-series observations as a 2D range (data points).
Weight coefficients as a 2D range (relative weights).