Article précédent
Implémentez le LWMA de MetaTrader avec la fonction de filtre FIR de scipy
Donc, j'ai essayé de réécrire LWMA (Linear Weighted Moving Average) avec la fonction lfilter ()
, mais je ne suis pas reconnaissant que cela soit juste, j'ai donc comparé le temps de calcul.
Je pensais qu'il n'y aurait pas beaucoup de différence comme prévu, alors j'ai essayé d'ajouter un peu plus de données de séries chronologiques pour prendre la moyenne mobile. J'ai lu les données d'une minute pour un an d'EUR / USD en me référant à ce qui suit (mon article de blog).
Lire les données historiques FX avec Python
import numpy as np
import pandas as pd
dataM1 = pd.read_csv('DAT_ASCII_EURUSD_M1_2015.csv', sep=';',
names=('Time','Open','High','Low','Close', ''),
index_col='Time', parse_dates=True)
Il y a environ 370 000 chacun des prix d'ouverture, prix élevé, prix bas et prix de clôture.
J'ai essayé d'utiliser la commande % time
dans le bloc-notes Jupyter pour mesurer le temps. Tout d'abord, l'ancienne version de LWMA. Calculez la sortie un par un.
def LWMA(s, ma_period):
y = pd.Series(0.0, index=s.index)
for i in range(len(y)):
if i<ma_period-1: y[i] = 'NaN'
else:
y[i] = 0
for j in range(ma_period):
y[i] += s[i-j]*(ma_period-j)
y[i] /= ma_period*(ma_period+1)/2
return y
%time MA = LWMA(dataM1['Close'], 10)
Par conséquent
Wall time: 3min 35s
Quelles trois minutes et demie. Même s'il y a beaucoup de données, cela coûte 370000 tellement, n'est-il pas possible d'utiliser Python? .. ..
Jetez un second coup d'œil et testez une nouvelle version de LWMA. Utilisation de la fonction de filtre de scipy.
from scipy.signal import lfilter
def LWMAnew(s, ma_period):
h = np.arange(ma_period, 0, -1)*2/ma_period/(ma_period+1)
y = lfilter(h, 1, s)
y[:ma_period-1] = 'NaN'
return pd.Series(y, index=s.index)
%time MA = LWMAnew(dataM1['Close'], 10)
Par conséquent
Wall time: 6 ms
Quoi! 6 millisecondes. Est-ce 35 000 fois plus rapide? L'original est-il trop tard? Vous pouvez utiliser scipy.
Au fait, si vous l'exécutez avec % timeit
au lieu de% time
,
100 loops, best of 3: 3.4 ms per loop
Terminé en 1 seconde même si exécuté 100 fois. Il semble qu'il puisse être exécuté en environ 3 millisecondes lorsqu'il est rapide.
Puisque scipy est rapide, je l'ai comparé à la fonction pandas. SMA peut être écrit comme une fonction de méthode des pandas comme suit.
def SMA(s, ma_period):
return s.rolling(ma_period).mean()
%timeit MA = SMA(dataM1['Close'], 10)
Par conséquent
100 loops, best of 3: 16 ms per loop
Exécutez 100 fois et c'est rapide en 16 millisecondes. C'est assez rapide. Maintenant, écrivons ceci en utilisant la fonction de filtre de scipy.
def SMAnew(s, ma_period):
h = np.ones(ma_period)/ma_period
y = lfilter(h, 1, s)
y[:ma_period-1] = 'NaN'
return pd.Series(y, index=s.index)
%timeit MA = SMAnew(dataM1['Close'], 10)
Par conséquent
100 loops, best of 3: 3.44 ms per loop
vite. Environ 5 fois plus que les pandas. Après tout, scipy est rapide, il peut donc être préférable de réécrire d'autres moyennes mobiles en utilisant lfilter ()
.