Vorheriger Artikel Implementieren Sie MetaTraders LWMA mit der FIR-Filterfunktion von scipy Also habe ich versucht, LWMA (Linear Weighted Moving Average) mit der Funktion "lfilter ()" neu zu schreiben, aber ich bin nicht dankbar, dass es nur ordentlich ist, also habe ich die Berechnungszeit verglichen.
Ich dachte, dass es nicht wie erwartet einen großen Unterschied geben würde, also versuchte ich, ein wenig mehr Zeitreihendaten hinzuzufügen, um den gleitenden Durchschnitt zu ermitteln. Ich habe die 1-Minuten-Daten für ein Jahr EUR / USD unter Bezugnahme auf Folgendes gelesen (mein Blog-Beitrag).
FX-Verlaufsdaten mit Python lesen
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)
Der Eröffnungspreis, der hohe Preis, der niedrige Preis und der Schlusskurs betragen jeweils etwa 370.000.
Ich habe versucht, den Befehl % time
im Jupyter-Notizbuch zu verwenden, um die Zeit zu messen. Erstens die ältere Version von LWMA. Berechnen Sie die Ausgabe nacheinander.
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)
Als Ergebnis
Wall time: 3min 35s
Was für dreieinhalb Minuten. Selbst wenn es viele Daten gibt, kostet es 370.000 so viel, ist es nicht möglich, Python zu verwenden? .. ..
Werfen Sie einen zweiten Blick und testen Sie eine neue Version von LWMA. Verwenden der Filterfunktion von 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)
Als Ergebnis
Wall time: 6 ms
Was! 6 Millisekunden. Ist es 35.000 mal schneller? Ist das Original zu spät? Sie können scipy verwenden.
Übrigens, wenn Sie es mit "% timeit" anstelle von "% time" ausführen,
100 loops, best of 3: 3.4 ms per loop
Innerhalb von 1 Sekunde abgeschlossen, auch wenn es 100 Mal ausgeführt wurde. Es scheint, dass es in ungefähr 3 Millisekunden ausgeführt werden kann, wenn es schnell ist.
Da scipy schnell ist, habe ich es mit der Pandas-Funktion verglichen. SMA kann wie folgt als Methodenfunktion von Pandas geschrieben werden.
def SMA(s, ma_period):
return s.rolling(ma_period).mean()
%timeit MA = SMA(dataM1['Close'], 10)
Als Ergebnis
100 loops, best of 3: 16 ms per loop
Laufen Sie 100 Mal und es ist schnell in 16 Millisekunden. Es ist ziemlich schnell. Schreiben wir dies nun mit der Filterfunktion von 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)
Als Ergebnis
100 loops, best of 3: 3.44 ms per loop
schnell. Etwa fünfmal so viel wie Pandas. Nachdem alle scipy schnell sind, ist es möglicherweise besser, andere gleitende Durchschnitte mit lfilter ()
neu zu schreiben.