The most commonly used moving average after the simple moving average (SMA) is the exponential moving average (EMA). In addition to MACD, which is famous as a technical index that uses EMA, there are also DEMA, TEMA, and TriX that use EMA multiple times, and adaptive moving averages such as AMA, FrAMA, and VIDyA use EMA as a calculation method. I will.
This time, Comparing IIR filter type moving averages with pandas and scipy As a continuation of, let's compare some EMA codes.
When actually using EMA, the period is entered as a parameter, but here we use the formula directly to check the performance of the EMA itself.
In other words, the parameter of EMA is $ \ alpha $ in the above formula.
First, input data to be multiplied by EMA About Python code for simple moving average assuming Numba use Make it as a random walk as well.
import numpy as np
import pandas as pd
dn = np.random.randint(2, size=100000)*2-1
gwalk = np.cumprod(np.exp(dn*0.01))*100
In pandas, you can easily convert to Series class and execute EMA with ʻewmand
mean methods. You can also directly assign ʻalpha
as a parameter of ʻewm. ʻAlpha
is in the range of 0 to 1, and there is no particular difference depending on the value, so enter 0.15 here.
def EMA1(x, alpha):
return pd.Series(x).ewm(alpha=alpha).mean()
%timeit y1 = EMA1(gwalk, 0.15)
The execution time is as follows.
100 loops, best of 3: 8.62 ms per loop
Comparing IIR filter type moving averages with pandas and scipy It is an implementation using scipy's filter function lfilter in the same way as.
from scipy.signal import lfilter
def EMA2(x, alpha):
y,zf = lfilter([alpha], [1,alpha-1], x, zi=[x[0]*(1-alpha)])
return y
%timeit y2 = EMA2(gwalk, 0.15)
The execution time is as follows.
1000 loops, best of 3: 631 µs per loop
So far in the previous article, it was said that scipy is fast, but this time there is a continuation.
Code the EMA formula directly. However, if it is left as it is, it will be very slow, so use Numba to speed it up.
from numba import jit
@jit(nopython=True)
def EMA3(x, alpha):
y = np.empty_like(x)
y[0] = x[0]
for i in range(1,len(x)):
y[i] = alpha*x[i] + (1-alpha)*y[i-1]
return y
%timeit y3 = EMA3(gwalk, 0.15)
If you add nopython = True
to the argument of @ jit
and no error occurs, you can expect speedup. In fact, the execution time is
1000 loops, best of 3: 227 µs per loop
And faster than scipy.
In the case of EMA as well, using Numba resulted in the fastest direct coding.
Recommended Posts