Dans l'article, j'ai présenté DEMA et TEMA, mais cette fois,
Comparaison du code de moyenne mobile exponentielle (EMA) écrit en Python
De même, comparons plusieurs types d'implémentations, comme l'utilisation du filtre de scipy, codant directement mais accélérant avec Numba.
Une marche aléatoire de 100 000 échantillons est utilisée comme données d'entrée.
import numpy as np
dn = np.random.randint(2, size=100000)*2-1
gwalk = np.cumprod(np.exp(dn*0.01))*100
Comparaison du code de moyenne mobile exponentielle (EMA) écrit en Python C'est le code EMA le plus rapide.
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
Utilisez ceci pour implémenter la formule DEMA telle quelle.
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
Je n'ai utilisé l'EMA que deux fois, mais c'est environ cinq fois plus lent que l'EMA seule.
C'est une implémentation utilisant la fonction lfilter de scipy. Le coefficient de filtre est
Comme demandé dans.
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
C'est un peu plus rapide.
@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
C'est encore plus rapide, la mise en œuvre directe étant la plus rapide. Cependant, la différence est moindre qu'en EMA. Et le prochain TEMA?
La première est la mise en œuvre à l'aide de l'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
Tout d'abord, il s'agit de.
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
C'est presque la même vitesse que 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
Dans le cas de TEMA également, la mise en œuvre directe est restée la plus rapide. Cependant, comme le temps de calcul de lfilter ne change pas beaucoup même si l'ordre augmente, je pense qu'il sera inversé lorsqu'il deviendra 4e ou 5e ordre. Si vous avez besoin ou non d'un filtre d'ordre supérieur pour analyser le marché. .. ..
Pour le moment, DEMA et TEMA implémenteront directement en utilisant Numba. → GitHub
Recommended Posts