Implementation of double exponential smoothing, aka Double Exponential Moving Average (DEMA)

If I have time series data β€” a list of pairs {x, y} β€”and you want to smooth it out, I can use an exponential moving average like this:

EMA[data_, alpha_:.1] := Transpose @ {#1, ExponentialMovingAverage[#2, alpha]}& @@ Transpose@data 

How would you implement double exponential smoothing ?

 DEMA[data_, alpha_, gamma_] := (* unstub me! *) 

If he calculated good values ​​for alpha and gamma on his own, that would be nice.


A related question is how to handle the case when there are gaps in the time series, i.e. samples are not evenly distributed over time:

Exponential Moving Average, filmed at variable times

+6
wolfram-mathematica smoothing
source share
2 answers

I'm not sure if this is the fastest code I can get, but it looks like it looks like this:

 DEMA[data_, alpha_, gamma_] := Module[{st = First[data], bt = data[[2]] - data[[1]], btnew, stnew}, Reap[ Sow[st]; Do[ stnew = alpha y + (1 - alpha) (st + bt); btnew = gamma (stnew - st) + (1 - gamma) bt; Sow[stnew]; st = stnew; bt = btnew; , {y, Rest@data }]][[-1, 1] ]] 

This is almost straight from the page you linked to. You can change the initial condition for b in the source code. Setting bt to zero initially restores a single exponential smoothing.

 In[81]:= DEMA[{a, b, c, d}, alpha, gamma] Out[81]= {a, (1 - alpha) b + alpha b, alpha c + (1 - alpha) ((1 - alpha) b + alpha b + (-a + b) (1 - gamma) + (-a + (1 - alpha) b + alpha b) gamma), alpha d + (1 - alpha) (alpha c + (1 - gamma) ((-a + b) (1 - gamma) + (-a + (1 - alpha) b + alpha b) gamma) + (1 - alpha) ((1 - alpha) b + alpha b + (-a + b) (1 - gamma) + (-a + (1 - alpha) b + alpha b) gamma) + gamma (-(1 - alpha) b - alpha b + alpha c + (1 - alpha) ((1 - alpha) b + alpha b + (-a + b) (1 - gamma) + (-a + (1 - alpha) b + alpha b) gamma)))} 
+3
source share

Here is my wording:

 DEMA[data_, alpha_, gamma_] := FoldList[ Module[{x, y}, x = #[[1]] + #[[2]]; y = #2 - alpha x; {y + x, #[[2]] + gamma * y} ] &, {data[[1]], data[[2]] - data[[1]]}, alpha * Rest@data ][[All, 1]] 
+1
source share

All Articles