How is the exponential moving average calculated?

1.7k Views Asked by At

For example, imagine I have the following data set $V =\{10,12,11,10,13,14,12\}$. How could I calculate the EMA of the data set at a given index? With $\alpha = 0.2$ I believe the equation is as follows: $EMA_i= \alpha V_i + (1-\alpha)EMA_{i-1}$. Is my equation correct? if so could someone provided example calculations for how it would play out?

2

There are 2 best solutions below

1
On BEST ANSWER

If you have a series $\{x_n, \; n=0,1, \ldots\}$, the exponential moving average would be computed as $y_n = (1-\alpha)y_{n-1} + \alpha x_n$. You will have to specify the initial condition (e.g. $y_{-1} = 0$).

Now you can compute the first few terms and see a trend:

$y_0 = (1-\alpha)y_{-1} + \alpha x_0 = \alpha x_0$

$y_1 = (1-\alpha)y_0 + \alpha x_1 = (1-\alpha)\alpha x_0 + \alpha x_1$

$y_2 = (1-\alpha)y_1 + \alpha x_2 = (1-\alpha)^2 \alpha x_0 + (1-\alpha)\alpha x_1 + x_2 $

$\ldots$

$y_n = \sum_{k=0}^{n-1} (1-\alpha)^{n-k} \alpha x_k + x_n$

So you can either use the above expression for $y_n$ as a function of $\{x_k\}$ directly, or do the computation recursively.

0
On

A python code example that illustrates the calculations for different $\beta$'s values:

enter image description here

import numpy as np
import matplotlib.pyplot as plot

def smooth(x, b=0.98):
  '''Compute the exponential weighted average: b*avg[i-1] + (1-b)*x[i].
     The sum of the geometric sequence is 1-b^(i+1).
  '''
  avg=0.0                     # set initial condition
  smooth=[]
  for i in range(len(x)):
    EMA = b * avg + (1-b) * x[i]
    smooth.append(EMA / (1-b**(i+1)))
    avg=EMA
  return np.array(smooth)

# Simulate data
np.random.seed(12)
x = np.linspace(3.5, 12, 300)
y = np.sin(x) + np.random.randn(300, ) * 0.4 

# Visualize values
SKIP_FIRST=0
fig, ax = plt.subplots(1, 2, sharey='row', figsize=(15,6))
ax[0].plot(x, y, 'o', color='black')
ax[1].plot(x, y, 'o', color='black', alpha=.2)
ax[1].plot(x[SKIP_FIRST:], smooth(y, b=.5)[SKIP_FIRST:], 'g-', label='EMA $\\beta=0.5$', alpha=.4)
ax[1].plot(x[SKIP_FIRST:], smooth(y, b=.9)[SKIP_FIRST:], 'b-', label='EMA $\\beta=0.9$')
ax[1].plot(x[SKIP_FIRST:], smooth(y, b=.98)[SKIP_FIRST:], 'r-', label='EMA $\\beta=0.98$')
ax[1].legend(loc='lower center', frameon=False)