Overview
The calculation splits a time series value into two measurements, a level and a trend. The level can be thought of as where the time series currently sits, and the trend is a measurement of how much it changes from one period to the next.We define the level at time t as {% a_t %}, and the trend as {% b_t %}.
- a is the level
- b is the trend
The forecasted next period value is {% f_{t+1} = a_t + b_t %}. That is, the forecast is the current plus the currently measured change in level from one period to the next.
Setup
Starting from a time series {% x_0, x_1, ... x_n,... %}
{% a_0 = x_0 %}
For the initial trend, we look ahead and
{% b_0 = x_1- x_0 %}
Then the forecast is
{% f_{1} = a_0 + b_0 %}
which, given the definitions is a perfect forecast. (This is perfect because we allowed ourselves to
use the future value in the initialization of the trend above.)
Updates
Every period we update the level by the current measured valued {% x_t %}. There are two preset parameters that determine the speed of the update, {% \alpha %} and {% \beta %}.
{% a_t = \alpha x_t + (1-\alpha)(a_{t-1} + b_{t-1}) %}
{% b_t = \beta (a_t - a_{t-1}) + (1-\beta)b_{t-1} %}
The following
Example
demonstrates calculating the updates for a simple time series.
Trend with Dampening
A dampening factor, {% \phi %} can be added to the model. {% \phi %} measures the amount of decay of the trend per period.
{% a_t = \alpha x_t + (1-\alpha)(a_{t-1} + \phi \times b_{t-1}) %}
{% b_t = \beta (a_t - a_{t-1}) + (1-\beta) \phi b_{t-1} %}
The trend with dampening is equivalent to the trend with no dampening when {% \phi %}
is set equal to 1. A trend with a 20% decay per period should set {% \phi %} to 0.8.
When dampening is added to the trend, the forecast must include the dampening.
{% f_{t+1} = a_t + \phi b_{t} %}
Exponentially Weighted Moving Average API
The exponentially weighted moving average is implemented in the EWMA Library
let ew = await import('/lib/time-series/exponential-weighting/v1.0.0/exponential-weighting.mjs');
let ma = ew.ewma2(alpha, beta, phi, extract, initial, initialTrend)
- alpha :
- beta :
- phi :
- extract : a function that extracts a numeric sequence from the list of items
- initial : is a function that takes an array of extracted value and returns the initial level
- initialTrend : is a function that takes an array of extracted value and returns the initial trend
let ew = await import('/code/exponential-weighting/v1.0.0/exponential-weighting.mjs');
let data = [{price:100},{price:101},{price:102},{price:101},
{price:99},{price:102},{price:102},{price:103},];
//calculate the moving averages
let ma = ew.ewma2(data.map(p=>p.price),0.1,0.1,1);