In dem Artikel habe ich DEMA und TEMA vorgestellt, aber diesmal
[Vergleich des in Python geschriebenen EMA-Codes (Exponential Moving Average) [http://qiita.com/toyolab/items/6872b32d9fa1763345d8)
In ähnlicher Weise werde ich verschiedene Arten von Implementierungen vergleichen, z. B. die Verwendung von scipys lfilter, die direkte Codierung, die Beschleunigung mit Numba usw.
Der Zufallslauf von 100.000 Proben wird als Eingabedaten verwendet.
import numpy as np
dn = np.random.randint(2, size=100000)*2-1
gwalk = np.cumprod(np.exp(dn*0.01))*100
[Vergleich des in Python geschriebenen EMA-Codes (Exponential Moving Average) [http://qiita.com/toyolab/items/6872b32d9fa1763345d8) Dies ist der schnellste EMA-Code.
from numba import jit
@jit(nopython=True)
def EMA(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 y = EMA(gwalk, 0.15)
1000 loops, best of 3: 227 µs per loop
Verwenden Sie diese Option, um die DEMA-Formel unverändert zu implementieren.
def DEMA1(x, period):
alpha = 2/(period+1)
ema = EMA(x, alpha)
ema2 = EMA(ema, alpha)
y = 2*ema-ema2
return y
%timeit y1 = DEMA1(gwalk, 14)
1000 loops, best of 3: 1.19 ms per loop
Ich habe EMA nur zweimal verwendet, aber es ist ungefähr fünfmal langsamer als EMA allein.
Es ist eine Implementierung, die die Filterfunktion von scipy verwendet. Der Filterkoeffizient ist
Wie in angefordert.
import scipy.signal as sp
def DEMA2(x, period):
alpha = 2/(period+1)
a = [1, 2*(alpha-1), (1-alpha)**2]
b = [alpha*(2-alpha), 2*alpha*(alpha-1)]
zi = sp.lfilter_zi(b, a)
y,zf = sp.lfilter(b, a, x, zi=zi*x[0])
return y
%timeit y2 = DEMA2(gwalk, 14)
1000 loops, best of 3: 717 µs per loop
Es ist etwas schneller.
@jit(nopython=True)
def DEMA3(x, period):
alpha = 2/(period+1)
a1 = 2*(alpha-1)
a2 = (1-alpha)**2
b0 = alpha*(2-alpha)
b1 = 2*alpha*(alpha-1)
y = np.empty_like(x)
y[0] = x[0]
y[1] = b0*x[1] + b1*x[0] - a1*y[0] - a2*y[0]
for i in range(2,len(x)):
y[i] = b0*x[i] + b1*x[i-1] - a1*y[i-1] - a2*y[i-2]
return y
%timeit y3 = DEMA3(gwalk, 14)
1000 loops, best of 3: 488 µs per loop
Es ist sogar noch schneller, wobei die direkte Implementierung am schnellsten ist. Der Unterschied ist jedoch geringer als bei EMA. Was ist mit der nächsten TEMA?
Erstens ist die Implementierung mit EMA.
def TEMA1(x, period):
alpha = 2/(period+1)
ema = EMA(x, alpha)
ema2 = EMA(ema, alpha)
ema3 = EMA(ema2, alpha)
y = 3*ema-3*ema2+ema3
return y
%timeit y1 = TEMA1(gwalk, 14)
100 loops, best of 3: 1.89 ms per loop
Zunächst geht es darum.
def TEMA2(x, period):
alpha = 2/(period+1)
a = [1, 3*(alpha-1), 3*(1-alpha)**2, (alpha-1)**3]
b = [3*alpha*(1-alpha)+alpha**3, 3*alpha*(alpha-2)*(1-alpha), 3*alpha*(1-alpha)**2]
zi = sp.lfilter_zi(b, a)
y,zf = sp.lfilter(b, a, x, zi=zi*x[0])
return y
%timeit y2 = TEMA2(gwalk, 14)
1000 loops, best of 3: 718 µs per loop
Es ist fast die gleiche Geschwindigkeit wie DEMA.
@jit(nopython=True)
def TEMA3(x, period):
alpha = 2/(period+1)
a1 = 3*(alpha-1)
a2 = 3*(1-alpha)**2
a3 = (alpha-1)**3
b0 = 3*alpha*(1-alpha)+alpha**3
b1 = 3*alpha*(alpha-2)*(1-alpha)
b2 = 3*alpha*(1-alpha)**2
y = np.empty_like(x)
y[0] = x[0]
y[1] = b0*x[1] + b1*x[0] + b2*x[0] - a1*y[0] - a2*y[0] - a3*y[0]
y[2] = b0*x[2] + b1*x[1] + b2*x[0] - a1*y[1] - a2*y[0] - a3*y[0]
for i in range(3,len(x)):
y[i] = b0*x[i] + b1*x[i-1] + b2*x[i-2] - a1*y[i-1] - a2*y[i-2] - a3*y[i-3]
return y
%timeit y3 = TEMA3(gwalk, 14)
1000 loops, best of 3: 604 µs per loop
Auch bei TEMA blieb die direkte Implementierung am schnellsten. Da sich die Berechnungszeit von lfilter jedoch nicht wesentlich ändert, selbst wenn die Reihenfolge zunimmt, denke ich, dass sie umgekehrt wird, wenn sie zur 4. oder 5. Ordnung wird. Ob Sie einen Filter höherer Ordnung benötigen, um den Markt zu analysieren. .. ..
DEMA und TEMA werden vorerst direkt mit Numba implementieren. → GitHub
Recommended Posts