Database Reference
In-Depth Information
Moving Average
Thesimplest averaging approach foratime series isthe
moving average
.As
the name implies, this is the average of the values over a “sliding window” of
values. It is usually expressed in terms of the number of time buckets being
used in the average and is often written as
MA(k)
. For instance, moving
averages for stock market data are often expressed in terms of days.
The moving average is easy to implement as it only requires the storage of
k
different values. For efficiency, it is usually best to keep track of the running
sum, adding and removing values as appropriate. Otherwise, every update
of the moving average would require
k
operations instead of, at most, two.
This is shown in the following implementation:
public class
MovingAverage {
LinkedList<Double> values =
new
LinkedList<Double>();
double
sum;
int
k;
public
MovingAverage(
int
k) {
this
.k = k;
}
public double
observe(
double
value) {
sum += value;
values.add(value);
if
(values.size() > k) {
sum -= values.removeFirst();
return
sum/(
double
)k;
}
return
Double.
NaN
;
}
}
Notice that the moving average returns
NaN
if it has not received enough
observations. To produce a usable observation, the moving average loses the
first
k-1
values of the time series. Selecting the appropriate window size
for a moving average is a bit of an art. Moving averages act as a low-pass
filter on the actual data, and choosing too small a range does not smooth out
enough of the noise. Conversely, too large a range smoothes out important
signals in the data.
Figure 11.1
shows the effect of making different choices
about moving average windows on some simulated sine waves with a small