Datenkennzeichnung für Zeitreihenanalyse (Teil 2): Datensätze mit Trendmarkern mit Python erstellen
Einführung
Im vorigen Artikel haben wir Ihnen gezeigt, wie Sie Ihre Daten durch Beobachtung der Trends im Diagramm beschriften und die Daten in einer csv-Datei speichern können. In diesem Teil wollen wir anders denken: Wir beginnen mit den Daten selbst.
Wir werden die Daten mit Python verarbeiten. Warum Python? Nur weil es bequem und schnell ist, heißt das nicht, dass es auch schnell läuft, aber die umfangreiche Python-Bibliothek kann uns helfen, den Entwicklungszyklus erheblich zu verkürzen.
Also, los geht's!
Inhaltsverzeichnis
- Welche Python-Bibliothek soll ich wählen?
- Daten vom MT5-Client mit der MetaTrader5-Bibliothek abrufen
- Konvertierung von Datenformaten
- Datenkennzeichnung
- Manuelles Korrekturlesen
- Zusammenfassung
Welche Python-Bibliothek soll ich wählen?
Wir alle wissen, dass es in Python viele hervorragende Entwickler gibt, die eine Vielzahl von Bibliotheken zur Verfügung stellen, die uns die Entwicklung erleichtern und uns viel Entwicklungszeit sparen. Im Folgenden habe ich einige verwandte Python-Bibliotheken zusammengestellt, von denen einige auf unterschiedlichen Architekturen basieren, einige für den Handel und einige für das Backtesting verwendet werden können. Es ist einschließlich, aber nicht beschränkt auf gekennzeichnete Daten. Interessierte, können versuchen, es zu studieren, aber dieser Artikel bietet keine detaillierte Einführung.
- statsmodels - Python-Modul, mit dem Nutzer Daten untersuchen, statistische Modelle schätzen und statistische Tests durchführen können: http://statsmodels.sourceforge.net
- dynts - Python-Paket für die Analyse und Manipulation von Zeitreihen: https://github.com/quantmind/dynts
- PyFlux - Python-Bibliothek für Zeitreihenmodellierung und Inferenz (frequentistisch und Bayesianisch) auf Modelle: https://github.com/RJT1990/pyflux
- tsfresh - Automatische Extraktion von relevanten Merkmalen aus Zeitreihen: https://github.com/blue-yonder/tsfresh
- hasura/quandl-metabase - Hasura Schnellstart zur Visualisierung von Quandl's Zeitreihen-Datensätzen mit Metabase: https://platform.hasura.io/hub/projects/anirudhm/quandl-metabase-time-series
- Facebook Prophet - Tool zur Erstellung qualitativ hochwertiger Prognosen für Zeitreihendaten, die eine mehrfache Saisonalität mit linearem oder nicht linearem Wachstum aufweisen: https://github.com/facebook/prophet
- tsmoothie - Eine Python-Bibliothek zur Glättung von Zeitreihen und zur Erkennung von Ausreißern in vektorisierter Form: https://github.com/cerlymarco/tsmoothie
- pmdarima - Eine statistische Bibliothek, die entwickelt wurde, um die Lücke in Pythons Fähigkeiten zur Zeitreihenanalyse zu füllen, einschließlich des Äquivalents der auto.arima-Funktion von R: https://github.com/alkaline-ml/pmdarima
- gluon-ts - Probabilistische Zeitreihenmodellierung in Python: https://github.com/awslabs/gluon-ts
- gs-quant - Python-Toolkit für die quantitative Finanzwirtschaft: https://github.com/goldmansachs/gs-quant
- willowtree - Robuste und flexible Python-Implementierung des Weidenbaum-Gitters für die Preisbildung von Derivaten: https://github.com/federicomariamassari/willowtree
- financial-engineering - Anwendungen von Monte-Carlo-Methoden für Finanz-Engineering-Projekte, in Python: https://github.com/federicomariamassari/financial-engineering
- optlib - Eine in Python geschriebene Bibliothek für die Preisgestaltung von Finanzoptionen: https://github.com/dbrojas/optlib
- tf-quant-finance - Leistungsstarke TensorFlow-Bibliothek für quantitative Finanzen: https://github.com/google/tf-quant-finance
- Q-Fin - Eine Python-Bibliothek für die Finanzmathematik: https://github.com/RomanMichaelPaolucci/Q-Fin
- Quantsbin - Tools für die Preisermittlung und das Plotten von Vanilla-Optionspreisen, Greeks und verschiedene andere Analysen rund um sie: https://github.com/quantsbin/Quantsbin
- finoptions - Vollständige Python-Implementierung des R-Pakets fOptions mit teilweiser Implementierung von fExoticOptions zur Preisgestaltung verschiedener Optionen: https://github.com/bbcho/finoptions-dev
- pypme - PME (Public Market Equivalent) Berechnung: https://github.com/ymyke/pypme
- Blankly - Vollständig integriertes Backtesting, Papierhandel und Live-Einsatz: https://github.com/Blankly-Finance/Blankly
- TA-Lib - Python-Wrapper für TA-Lib (http://ta-lib.org/): https://github.com/mrjbq7/ta-lib
- zipline - Pythonische algorithmische Handelsbibliothek: https://github.com/quantopian/zipline
- QuantSoftware Toolkit - Python-basiertes Open-Source-Software-Framework zur Unterstützung der Portfoliokonstruktion und -verwaltung: https://github.com/QuantSoftware/QuantSoftwareToolkit
- finta - Gemeinsame Indikatoren für die technische Finanzanalyse, implementiert in Pandas: https://github.com/peerchemist/finta
- Tulipy - Finanztechnische Analyse Indikator Bibliothek (Python Bindungen für tulipindicators): https://github.com/cirla/tulipy
- lppls - Ein Python-Modul zur Anpassung des Models Power Law Singularity (LPPLS): https://github.com/Boulder-Investment-Technologies/lppls
Daten vom MT5-Client mit der MetaTrader5-Bibliothek abrufen
Das Wichtigste ist natürlich, dass Python bereits auf Ihrem PC installiert ist. Falls nicht, empfiehlt der Autor nicht die Installation der offiziellen Python-Version, sondern zieht es vor, Anaconda zu verwenden, das einfach zu warten ist. Aber die normale Version von Anaconda ist riesig, integriert reiche Inhalte, einschließlich der visuellen Verwaltung, Editor, etc. Peinlicherweise nutze ich sie kaum, sodass ich sehr Miniconda empfehle, kurz und prägnant, einfach und praktisch. Miniconda offizielle Website-Adresse: Miniconda :: Anaconda.org.
1. Grundlegende Initialisierung der Umgebung
Beginnen Sie mit der Erstellung einer virtuellen Umgebung und öffnen Sie den Anaconda Promote-Typ:
conda create -n Data_label python=3.10
Geben Sie „y“ ein und warten Sie, bis die Umgebung erstellt wurde, dann geben Sie ein:
conda activate Data_label
Hinweis:Wenn wir die virtuelle Umgebung von conda erstellen, denken Sie daran, python=x.xx hinzuzufügen, da wir sonst unerklärliche Probleme bei der Nutzung haben werden. Dies ist ein Ratschlag von einer Person, die darunter gelitten hat!
2. Installation der erforderlichen Bibliothek
Installieren Sie unsere wichtige Bibliothek MetaTrader 5, geben Sie die conda ein:
pip install MetaTrader5
Installieren Sie pytrendseries, geben Sie dazu in der conda ein:
pip install pytrendseries
3. Eine Python-Datei erstellen
Öffnen Sie MetaEditor, suchen Sie Tools->Optionen, tragen Sie Ihren Python-Pfad in der Python-Spalte der Compiler-Option ein, mein eigener Pfad ist „G:miniconda3\envs\Data_label“:
Nach der Fertigstellung wählen Sie Datei->Neu (oder Strg + N), um eine neue Datei zu erstellen, und wählen Sie im Pop-up-Fenster Python-Skript, etwa so:
Klicken Sie auf Weiter und geben Sie einen Dateinamen ein, z. B. so:
Nachdem Sie auf OK geklickt haben, wird das folgende Fenster angezeigt:
4. Verbinden des Clients und Abrufen von Daten
Löschen Sie den ursprünglichen, automatisch generierten Code und ersetzen Sie ihn durch den folgenden Code:
# Copyright 2021, MetaQuotes Ltd. # https://www.mql5.com import MetaTrader5 as mt if not mt.initialize(): print('initialize() failed!') else: print(mt.version()) mt.shutdown()
Kompilieren und ausführen, um zu sehen, ob ein Fehler gemeldet wird, und wenn es kein Problem gibt, wird die folgende Ausgabe erscheinen:
Wenn Sie die Meldung „initialize() failed!“ erhalten, fügen Sie bitte den Parameter path in der Funktion initialize() hinzu, der den Pfad zur ausführbaren Datei des Clients angibt, wie im folgenden farblich hervorgehobenen Code dargestellt:
# Copyright 2021, MetaQuotes Ltd. # https://www.mql5.com import MetaTrader5 as mt if not mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"): print('initialize() failed!') else: print(mt.version()) mt.shutdown()Alles ist bereit, holen wir uns die Daten:
# Copyright 2021, MetaQuotes Ltd. # https://www.mql5.com import MetaTrader5 as mt if not mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"): print('initialize() failed!') else: sb=mt.symbols_total() rts=None if sb > 0: rts=mt.copy_rates_from_pos("GOLD_micro",mt.TIMEFRAME_M15,0,10000) mt.shutdown() print(rts[0:5])
Im obigen Code haben wir „sb=mt.symbols_total()“ hinzugefügt, um zu verhindern, dass der Fehler gemeldet wird, weil keine Symbole erkannt wurden, und „copy_rates_from_pos("GOLD_micro", mt, TIMEFRAME_M15,0,10000)“ bedeutet, dass 10.000 Balken aus der M15-Periode von GOLD_micro kopiert werden, und die folgende Ausgabe wird nach der Kompilierung erzeugt:
Bislang haben wir die Daten erfolgreich vom Client erhalten.
Konvertierung von Datenformaten
Obwohl wir die Daten vom Client erhalten haben, ist das Datenformat nicht das, was wir brauchen. Die Daten sind „numpy.ndarray“,wie dieses:
"[(1692368100, 1893.51, 1893.97,1893.08,1893.88,548, 35, 0)
(1692369000, 1893.88, 1894.51, 1893.41, 1894.51, 665, 35, 0)
(1692369900, 1894.5, 1894.91, 1893.25, 1893.62, 755, 35, 0)
(1692370800, 1893.68, 1894.7 , 1893.16, 1893.49, 1108, 35, 0)
(1692371700, 1893.5 , 1893.63, 1889.43, 1889.81, 1979, 35, 0)
(1692372600, 1889.81, 1891.23, 1888.51, 1891.04, 2100, 35, 0)
(1692373500, 1891.04, 1891.3 , 1889.75, 1890.07, 1597, 35, 0)
(1692374400, 1890.11, 1894.03, 1889.2, 1893.57, 2083, 35, 0)
(1692375300, 1893.62, 1894.94, 1892.97, 1894.25, 1692, 35, 0)
(1692376200, 1894.25, 1894.88, 1890.72, 1894.66, 2880, 35, 0)
(1692377100, 1894.67, 1896.69, 1892.47, 1893.68, 2930, 35, 0)
...(1693822500, 1943.97, 1944.28, 1943.24, 1943.31, 883, 35, 0)
(1693823400, 1943.25, 1944.13, 1942.95, 1943.4 , 873, 35, 0)
(1693824300, 1943.4, 1944.07, 1943.31, 1943.64, 691, 35, 0)
(1693825200, 1943.73, 1943.97, 1943.73, 1943.85, 22, 35, 0)]"
Verwenden wir also Pandas, um es umzuwandeln, der hinzugefügte Code ist grün markiert:
# Copyright 2021, MetaQuotes Ltd. # https://www.mql5.com import MetaTrader5 as mt import pandas as pd if not mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"): print('initialize() failed!') else: print(mt.version()) sb=mt.symbols_total() rts=None if sb > 0: rts=mt.copy_rates_from_pos("GOLD_micro",mt.TIMEFRAME_M15,0,1000) mt.shutdown() rts_fm=pd.DataFrame(rts)
Schauen wir uns nun folgendes Datenformat an:
print(rts_fm.head(10))
Die Eingabedaten müssen Pandas sein. Das Format DataFrame mit einer Spalte als Beobachtungsdaten (im Format float oder int), daher müssen wir die Daten in das von pytrendseries angeforderte Format umwandeln:
td_data=rts_fm[['time','close']].set_index('time')
Schauen wir uns an, wie die ersten 10 Zeilen der Daten aussehen:
print(td_data.head(10))
Anmerkung: „td_data“ ist nicht unser letzter Datenstil, sondern nur ein Übergangsprodukt, mit dem wir Datentrends erhalten.
Jetzt sind unsere Daten vollständig nutzbar, aber für die nachfolgenden Operationen ist es besser, unser Datumsformat in einen Datenrahmen umzuwandeln, also sollten wir den folgenden Code vor dem „td_data=rts_fm[['time','close']].set_index('time')“ hinzufügen:
rts_fm['time']=pd.to_datetime(rts_fm['time'], unit='s')
Unsere Ausgabe sieht dann wie folgt aus:
time | close |
---|---|
2023-08-18 20:45:00 | 1888.82000 |
2023-08-18 21:00:00 | 1887.53000 |
2023-08-18 21:15:00 | 1888.10000 |
2023-08-18 21:30:00 | 1888.98000 |
2023-08-18 21:45:00 | 1888.37000 |
2023-08-18 22:00:00 | 1887.51000 |
2023-08-18 22:15:00 | 1888.21000 |
2023-08-18 22:30:00 | 1888.73000 |
2023-08-18 22:45:00 | 1889.12000 |
2023-08-18 23:00:00 | 1889.20000 |
Der vollständige Code für diesen Abschnitt:
# Copyright 2021, MetaQuotes Ltd. # https://www.mql5.com import MetaTrader5 as mt import pandas as pd if not mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"): print('initialize() failed!') else: print(mt.version()) sb=mt.symbols_total() rts=None if sb > 0: rts=mt.copy_rates_from_pos("GOLD_micro",mt.TIMEFRAME_M15,0,1000) mt.shutdown() rts_fm=pd.DataFrame(rts) rts_fm['time']=pd.to_datetime(rts_fm['time'], unit='s') td_data=rts_fm[['time','close']].set_index('time') print(td_data.head(10))
Datenkennzeichnung
1. Trenddaten abrufen
Importieren Sie zunächst das Paket „pytrendseries“:
import pytrendseries as pts
Wir verwenden die Funktion „pts.detecttrend()“, um den Trend zu ermitteln, und definieren dann die Variable „td“ für diese Funktion, für die es zwei Optionen gibt - „Abwärtstrend“ oder „Aufwärtstrend“:
td='downtrend' # or "uptrend"
Wir benötigen einen weiteren Parameter „wd“ als maximale Periode eines Trends:
wd=120
Es gibt auch einen Parameter, der definiert werden kann oder auch nicht, aber ich persönlich denke, dass es besser ist, ihn zu definieren, dieser Parameter gibt die Mindestperiode des Trends an:
limit=6
Jetzt können wir die Parameter in die Funktion eingeben, um den Trend: zu erhalten:
trends=pts.detecttrend(td_data,trend=td,limit=limit,window=wd)
Prüfen Sie dann das Ergebnis:
print(trends.head(15))
from | bis | Preis0 | Preis1 | index_from | index_to | time_span | drawdown | |
---|---|---|---|---|---|---|---|---|
1 | 2023-08-21 01:00:00 | 2023-08-21 02:15:00 | 1890.36000 | 1889.24000 | 13 | 18 | 5 | 0.00059 |
2 | 2023-08-21 03:15:00 | 2023-08-21 04:45:00 | 1890.61000 | 1885.28000 | 22 | 28 | 6 | 0.00282 |
3 | 2023-08-21 08:00:00 | 2023-08-21 13:15:00 | 1893.30000 | 1886.86000 | 41 | 62 | 21 | 0.00340 |
4 | 2023-08-21 15:45:00 | 2023-08-21 17:30:00 | 1896.99000 | 1886.16000 | 72 | 79 | 7 | 0.00571 |
5 | 2023-08-21 20:30:00 | 2023-08-21 22:30:00 | 1894.77000 | 1894.12000 | 91 | 99 | 8 | 0.00034 |
6 | 2023-08-22 04:15:00 | 2023-08-22 05:45:00 | 1896.19000 | 1894.31000 | 118 | 124 | 6 | 0.00099 |
7 | 2023-08-22 06:15:00 | 2023-08-22 07:45:00 | 1896.59000 | 1893.80000 | 126 | 132 | 6 | 0.00147 |
8 | 2023-08-22 13:00:00 | 2023-08-22 16:45:00 | 1903.38000 | 1890.17000 | 153 | 168 | 15 | 0.00694 |
9 | 2023-08-22 19:00:00 | 2023-08-22 21:15:00 | 1898.08000 | 1896.25000 | 177 | 186 | 9 | 0.00096 |
10 | 2023-08-23 04:45:00 | 2023-08-23 06:00:00 | 1901.46000 | 1900.25000 | 212 | 217 | 5 | 0.00064 |
11 | 2023-08-23 11:30:00 | 2023-08-23 13:30:00 | 1904.84000 | 1901.42000 | 239 | 247 | 8 | 0.00180 |
12 | 2023-08-23 19:45:00 | 2023-08-23 23:30:00 | 1919.61000 | 1915.05000 | 272 | 287 | 15 | 0.00238 |
13 | 2023-08-24 09:30:00 | 2023-08-25 09:45:00 | 1921.91000 | 1912.93000 | 323 | 416 | 93 | 0.00467 |
14 | 2023-08-25 15:00:00 | 2023-08-25 16:30:00 | 1919.88000 | 1913.30000 | 437 | 443 | 6 | 0.00343 |
15 | 2023-08-28 04:15:00 | 2023-08-28 07:15:00 | 1916.92000 | 1915.07000 | 486 | 498 | 12 | 0.00097 |
Sie können das Ergebnis auch mit der Funktion „pts.vizplot.plot_trend()“ visualisieren:
pts.vizplot.plot_trend(td_data,trends)
In ähnlicher Weise können wir den Aufwärtstrend mit dem Code: betrachten.
td="uptrend" wd=120 limit=6 trends=pts.detecttrend(td_data,trend=td,limit=limit,window=wd) print(trends.head(15)) pts.vizplot.plot_trend(td_data,trends)
Das Ergebnis ist folgendes:
from | bis | Preis0 | Preis1 | index_from | index_to | time_span | drawup | |
---|---|---|---|---|---|---|---|---|
1 | 2023-08-18 22:00:00 | 2023-08-21 03:15:00 | 1887.51000 | 1890.61000 | 5 | 22 | 17 | 0.00164 |
2 | 2023-08-21 04:45:00 | 2023-08-22 10:45:00 | 1885.28000 | 1901.35000 | 28 | 144 | 116 | 0.00852 |
3 | 2023-08-22 11:15:00 | 2023-08-22 13:00:00 | 1898.78000 | 1903.38000 | 146 | 153 | 7 | 0.00242 |
4 | 2023-08-22 16:45:00 | 2023-08-23 19:45:00 | 1890.17000 | 1919.61000 | 168 | 272 | 104 | 0.01558 |
5 | 2023-08-23 23:30:00 | 2023-08-24 09:30:00 | 1915.05000 | 1921.91000 | 287 | 323 | 36 | 0.00358 |
6 | 2023-08-24 15:30:00 | 2023-08-24 17:45:00 | 1912.97000 | 1921.24000 | 347 | 356 | 9 | 0.00432 |
7 | 2023-08-24 23:00:00 | 2023-08-25 01:15:00 | 1916.41000 | 1917.03000 | 377 | 382 | 5 | 0.00032 |
8 | 2023-08-25 03:15:00 | 2023-08-25 04:45:00 | 1915.20000 | 1916.82000 | 390 | 396 | 6 | 0.00085 |
9 | 2023-08-25 09:45:00 | 2023-08-25 17:00:00 | 1912.93000 | 1920.03000 | 416 | 445 | 29 | 0.00371 |
10 | 2023-08-25 17:45:00 | 2023-08-28 18:30:00 | 1904.37000 | 1924.86000 | 448 | 543 | 95 | 0.01076 |
11 | 2023-08-28 20:00:00 | 2023-08-29 06:30:00 | 1917.74000 | 1925.41000 | 549 | 587 | 38 | 0.00400 |
12 | 2023-08-29 10:00:00 | 2023-08-29 12:45:00 | 1922.00000 | 1924.21000 | 601 | 612 | 11 | 0.00115 |
13 | 2023-08-29 15:30:00 | 2023-08-30 17:00:00 | 1914.98000 | 1947.79000 | 623 | 721 | 98 | 0.01713 |
14 | 2023-08-30 23:45:00 | 2023-08-31 04:45:00 | 1942.09000 | 1947.03000 | 748 | 764 | 16 | 0.00254 |
15 | 2023-08-31 09:30:00 | 2023-08-31 15:00:00 | 1943.52000 | 1947.00000 | 783 | 805 | 22 | 0.00179 |
2. Kennzeichnen der Daten
1). Parsen des Datenformats
① bedeutet den Beginn der Daten bis zum Beginn des ersten Abwärtstrends, wobei wir davon ausgehen, dass es sich um einen Aufwärtstrend handelt;
② bedeutet den Abwärtstrend;
③ bedeutet den Aufwärtstrend in der Mitte der Daten;
④ bedeutet das Ende des letzten Abwärtstrends.
Wir müssen also die Logik der Kennzeichnung für diese vier Teile implementieren.
2). Logik der Kennzeichnung
Beginnen wir mit der Definition einiger grundlegender Variablen:
rts_fm['trend']=0 rts_fm['trend_index']=0 max_len_rts=len(rts_fm) max_len=len(trends) last_start=0 last_end=0
Wir durchlaufen die Variable „trends“ mit einer for-Schleife, um den Anfang und das Ende der einzelnen Daten zu ermitteln:
for trend in trends.iterrows():
pass
Ermittlung der Start- und Endindizes für jedes Segment:
for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to']
Da rts_fm["trend"] selbst auf 0 initialisiert wurde, muss die Spalte „trend“ des Aufwärtstrends nicht geändert werden, aber wir müssen sehen, ob der Beginn der Daten ein Abwärtstrend ist, wenn es kein Abwärtstrend ist, gehen wir davon aus, dass es ein Aufwärtstrend ist:
for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to'] if trend[0]==1 and start!=0: # Since the rts_fm["trend"] itself has been initialized to 0, there is no need to change the "trend" column rts_fm['trend_index'][0:start]=list(range(0,start))
Wie zu Beginn der Daten müssen wir auch am Ende der Daten sehen, ob sie in einem Abwärtstrend enden:
for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to'] if trend[0]==1 and start!=0: # Since the rts_fm["trend"] itself has been initialized to 0, there is no need to change the "trend" column rts_fm['trend_index'][0:start]=list(range(0,start)) elif trend[0]==max_len and end!=max_len_rts-1: #we need to see if it ends in a downtrend at the end of the data rts_fm['trend_index'][last_end+1:len(rts_fm)]=list(range(0,max_len_rts-last_end-1))
Verarbeiten wir die Aufwärtssegmente, die nicht den Anfang und das Ende der Daten darstellen:
for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to'] if trend[0]==1 and start!=0: # Since the rts_fm["trend"] itself has been initialized to 0, there is no need to change the "trend" column rts_fm['trend_index'][0:start]=list(range(0,start)) elif trend[0]==max_len and end!=max_len_rts-1: #we need to see if it ends in a downtrend at the end of the data rts_fm['trend_index'][last_end+1:len(rts_fm)]=list(range(0,max_len_rts-last_end-1)) else: #Process the uptrend segments other than the beginning and end of the data rts_fm["trend_index"][last_end+1:start]=list(range(0,start-last_end-1))
Jedes Segment des Abwärtstrends verarbeiten:
for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to'] if trend[0]==1 and start!=0: # Since the rts_fm["trend"] itself has been initialized to 0, there is no need to change the "trend" column rts_fm['trend_index'][0:start]=list(range(0,start)) elif trend[0]==max_len and end!=max_len_rts-1: #we need to see if it ends in a downtrend at the end of the data rts_fm['trend_index'][last_end+1:len(rts_fm)]=list(range(0,max_len_rts-last_end-1)) else: #Process the uptrend segments other than the beginning and end of the data rts_fm["trend_index"][last_end+1:start]=list(range(0,start-last_end-1)) #Process each segments of the downtrend rts_fm["trend"][start:end+1]=1 rts_fm["trend_index"][start:end+1]=list(range(0,end-start+1)) last_start=start last_end=end
3). Ergänzungen
Wir gehen davon aus, dass der Anfang und das Ende der Daten einen Aufwärtstrend aufweisen. Wenn Sie der Meinung sind, dass dies nicht präzise genug ist, können Sie auch den Anfang und das Ende entfernen. Fügen Sie dazu den folgenden Code nach dem Ende der for-Schleife ein:
rts_fm['trend']=0 rts_fm['trend_index']=0 max_len_rts=len(rts_fm) max_len=len(trends) last_start=0 last_end=0 for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to'] if trend[0]==1 and start!=0: # Since the rts_fm["trend"] itself has been initialized to 0, there is no need to change the "trend" column rts_fm['trend_index'][0:start]=list(range(0,start)) elif trend[0]==max_len and end!=max_len_rts-1: #we need to see if it ends in a downtrend at the end of the data rts_fm['trend_index'][last_end+1:len(rts_fm)]=list(range(0,max_len_rts-last_end-1)) else: #Process the uptrend segments other than the beginning and end of the data rts_fm["trend_index"][last_end+1:start]=list(range(0,start-last_end-1)) #Process each segments of the downtrend rts_fm["trend"][start:end+1]=1 rts_fm["trend_index"][start:end+1]=list(range(0,end-start+1)) last_start=start last_end=end rts_fm=rts_fm.iloc[trends.iloc[0,:]['index_from']:end,:]
3. Prüfung
Nachdem wir das getan haben, wollen wir sehen, ob unsere Daten unseren Erwartungen entsprechen (das Beispiel betrachtet nur die ersten 25 Daten) :
rts_fm.head(25)
time | open | high | low | close | tick_volume | spread | real_volume | trend | trend_index | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 2023-08-22 11:30:00 | 1898.80000 | 1899.72000 | 1898.22000 | 1899.30000 | 877 | 35 | 0 | 0 | 0 |
1 | 2023-08-22 11:45:00 | 1899.31000 | 1899.96000 | 1898.84000 | 1899.81000 | 757 | 35 | 0 | 0 | 1 |
2 | 2023-08-22 12:00:00 | 1899.86000 | 1900.50000 | 1899.24000 | 1900.01000 | 814 | 35 | 0 | 0 | 2 |
3 | 2023-08-22 12:15:00 | 1900.05000 | 1901.26000 | 1899.99000 | 1900.48000 | 952 | 35 | 0 | 0 | 3 |
4 | 2023-08-22 12:30:00 | 1900.48000 | 1902.44000 | 1900.17000 | 1902.19000 | 934 | 35 | 0 | 0 | 4 |
5 | 2023-08-22 12:45:00 | 1902.23000 | 1903.59000 | 1902.21000 | 1902.64000 | 891 | 35 | 0 | 0 | 5 |
6 | 2023-08-22 13:00:00 | 1902.69000 | 1903.94000 | 1902.24000 | 1903.38000 | 873 | 35 | 0 | 1 | 0 |
7 | 2023-08-22 13:15:00 | 1903.40000 | 1904.29000 | 1901.71000 | 1902.08000 | 949 | 35 | 0 | 1 | 1 |
8 | 2023-08-22 13:30:00 | 1902.10000 | 1903.37000 | 1902.08000 | 1902.63000 | 803 | 35 | 0 | 1 | 2 |
9 | 2023-08-22 13:45:00 | 1902.64000 | 1902.75000 | 1901.75000 | 1901.80000 | 1010 | 35 | 0 | 1 | 3 |
10 | 2023-08-22 14:00:00 | 1901.79000 | 1902.47000 | 1901.33000 | 1901.96000 | 800 | 35 | 0 | 1 | 4 |
11 | 2023-08-22 14:15:00 | 1901.94000 | 1903.04000 | 1901.72000 | 1901.73000 | 785 | 35 | 0 | 1 | 5 |
12 | 2023-08-22 14:30:00 | 1901.71000 | 1902.62000 | 1901.66000 | 1902.38000 | 902 | 35 | 0 | 1 | 6 |
13 | 2023-08-22 14:45:00 | 1902.38000 | 1903.23000 | 1901.96000 | 1901.96000 | 891 | 35 | 0 | 1 | 7 |
14 | 2023-08-22 15:00:00 | 1901.94000 | 1903.25000 | 1901.64000 | 1902.41000 | 1209 | 35 | 0 | 1 | 8 |
15 | 2023-08-22 15:15:00 | 1902.39000 | 1903.00000 | 1898.97000 | 1899.87000 | 1971 | 35 | 0 | 1 | 9 |
16 | 2023-08-22 15:30:00 | 1899.86000 | 1901.17000 | 1896.72000 | 1896.85000 | 2413 | 35 | 0 | 1 | 10 |
17 | 2023-08-22 15:45:00 | 1896.85000 | 1898.15000 | 1896.12000 | 1897.26000 | 2010 | 35 | 0 | 1 | 11 |
18 | 2023-08-22 16:00:00 | 1897.29000 | 1897.45000 | 1895.52000 | 1895.97000 | 2384 | 35 | 0 | 1 | 12 |
19 | 2023-08-22 16:15:00 | 1895.96000 | 1896.31000 | 1893.87000 | 1894.48000 | 1990 | 35 | 0 | 1 | 13 |
20 | 2023-08-22 16:30:00 | 1894.43000 | 1894.60000 | 1892.64000 | 1893.38000 | 2950 | 35 | 0 | 1 | 14 |
21 | 2023-08-22 16:45:00 | 1893.48000 | 1894.17000 | 1888.94000 | 1890.17000 | 2970 | 35 | 0 | 1 | 15 |
22 | 2023-08-22 17:00:00 | 1890.19000 | 1894.53000 | 1889.94000 | 1894.20000 | 2721 | 35 | 0 | 0 | 0 |
23 | 2023-08-22 17:15:00 | 1894.18000 | 1894.73000 | 1891.51000 | 1891.71000 | 1944 | 35 | 0 | 0 | 1 |
24 | 2023-08-22 17:30:00 | 1891.74000 | 1893.70000 | 1890.91000 | 1893.59000 | 2215 | 35 | 0 | 0 | 2 |
Sie können sehen, dass wir den Daten erfolgreich Trendtypen und die Indices der markierten Trends hinzugefügt haben.
4. Speichern wir die Datei
Wir können die Daten in den meisten Dateiformaten speichern, die wir wollen, Sie können als JSON-Datei mit der to_json()-Methode speichern, Sie können als HTML-Datei mit der to_html()-Methode speichern, und so weiter. Nur das Speichern als CSV-Datei wird hier als Demonstration verwendet, am Ende des Codes hinzufügen:
rts_fm.to_csv('GOLD_micro_M15.csv')
Manuelles Korrekturlesen
An diesem Punkt haben wir die grundlegende Arbeit getan, aber wenn wir genauere Daten erhalten wollen, brauchen wir weitere menschliche Eingriffe, wir werden hier nur ein paar Richtungen aufzeigen und keine detaillierte Demonstration machen.
1. die Überprüfung der Datenintegrität
Die Vollständigkeit bezieht sich auf das Fehlen von Dateninformationen, d. h. das Fehlen der gesamten Daten oder das Fehlen eines Feldes in den Daten. Datenintegrität ist eines der grundlegendsten Bewertungskriterien für die Datenqualität. Wenn beispielsweise die vorherigen Daten in der M15-Periode Börsendaten um 2 Stunden von den nächsten Daten abweichen, dann müssen wir die entsprechenden Tools verwenden, um die Daten zu vervollständigen. Natürlich ist es im Allgemeinen schwierig, Devisen- oder Börsendaten über unser Kundenterminal zu erhalten, aber wenn Sie Zeitreihen aus anderen Quellen wie Verkehrsdaten oder Wetterdaten erhalten, müssen Sie dieser Situation besondere Aufmerksamkeit schenken.
Die Integrität der Datenqualität ist relativ leicht zu beurteilen und kann im Allgemeinen anhand der erfassten und eindeutigen Werte in den Datenstatistiken bewertet werden. Wenn z. B. der Schlusskurs einer Aktie in der vorangegangenen Periode 1000 beträgt, der Eröffnungskurs in der nächsten Periode aber auf 10 steigt, müssen Sie prüfen, ob die Daten fehlen.
2. Prüfung der Genauigkeit der Datenkennzeichnung
Aus der Perspektive dieses Artikels kann die Methode zur Kennzeichnung von Daten, die wir oben implementiert haben, bestimmte Schwachstellen haben. Wir müssen uns nicht nur auf die Methoden in der Bibliothek pytrendseries verlassen, um genaue gekennzeichnete Daten zu erhalten, sondern auch, um die Daten zu visualisieren und zu beobachten, ob die Trend-Klassifizierung der Daten zu anfällig oder nicht nutzbar ist, weil einige wichtige Informationen verpasst wird. Zu diesem Zeitpunkt müssen wir die Daten analysieren. Wenn sie aufgeteilt werden müssten, müssen sie aufgeteilt werden, und wenn sie zusammengeführt werden müssten, müssen sie zusammengeführt werden. Diese Arbeit ist sehr mühsam und zeitaufwendig, und konkrete Beispiele werden hier vorerst nicht angeführt.
Die Genauigkeit bezieht sich darauf, ob die in den Daten gespeicherten Informationen richtig sind und ob die in den Daten gespeicherten Informationen anormal oder falsch sind. Anders als bei der Konsistenz handelt es sich bei Daten mit Genauigkeitsproblemen nicht nur um Inkonsistenzen in den Regeln. Konsistenzprobleme können durch inkonsistente Regeln für die Datenprotokollierung verursacht werden, aber nicht unbedingt durch Fehler.
3. Durchführung einiger grundlegender statistischen Überprüfungen, um festzustellen, ob die Kennzeichnungen angemessen sind
- Integritätsverteilung: Die Vollständigkeit des Datensatzes lässt sich schnell und intuitiv erkennen.
- Heatmap: Mit Heatmaps lässt sich die Korrelation zwischen zwei Variablen leicht beobachten.
- Hierarchisches Clustering: Sie können sehen, ob die verschiedenen Klassen Ihrer Daten eng miteinander verbunden oder verstreut sind.
Zusammenfassung
Referenz: GitHub - rafa-rod/pytrendseries
Der vollständige Code ist unten dargestellt:
# Copyright 2021, MetaQuotes Ltd. # https://www.mql5.com import MetaTrader5 as mt import pandas as pd import pytrendseries as pts if not mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"): print('initialize() failed!') else: print(mt.version()) sb=mt.symbols_total() rts=None if sb > 0: rts=mt.copy_rates_from_pos("GOLD_micro",mt.TIMEFRAME_M15,0,1000) mt.shutdown() rts_fm=pd.DataFrame(rts) rts_fm['time']=pd.to_datetime(rts_fm['time'], unit='s') td_data=rts_fm[['time','close']].set_index('time') # print(td_data.head(10)) td='downtrend' # or "uptrend" wd=120 limit=6 trends=pts.detecttrend(td_data,trend=td,limit=limit,window=wd) # print(trends.head(15)) # pts.vizplot.plot_trend(td_data,trends) rts_fm['trend']=0 rts_fm['trend_index']=0 max_len_rts=len(rts_fm) max_len=len(trends) last_start=0 last_end=0 for trend in trends.iterrows(): start=trend[1]['index_from'] end=trend[1]['index_to'] if trend[0]==1 and start!=0: # Since the rts_fm["trend"] itself has been initialized to 0, there is no need to change the "trend" column rts_fm['trend_index'][0:start]=list(range(0,start)) elif trend[0]==max_len and end!=max_len_rts-1: #we need to see if it ends in a downtrend at the end of the data rts_fm['trend_index'][last_end+1:len(rts_fm)]=list(range(0,max_len_rts-last_end-1)) else: #Process the uptrend segments other than the beginning and end of the data rts_fm["trend_index"][last_end+1:start]=list(range(0,start-last_end-1)) #Process each segments of the downtrend rts_fm["trend"][start:end+1]=1 rts_fm["trend_index"][start:end+1]=list(range(0,end-start+1)) last_start=start last_end=end #rts_fm=rts_fm.iloc[trends.iloc[0,:]['index_from']:end,:] rts_fm.to_csv('GOLD_micro_M15.csv')
Anmerkung:
1. Denken Sie daran, dass Sie, wenn Sie den Pfad in die Funktion mt.initialize() wie folgt eingeben: mt.initialize("D:\\Project\\mt\\MT5\\terminal64.exe"), diesen durch den Speicherort Ihrer eigenen ausführbaren Client-Datei ersetzen müssen, nicht durch meine.
Wenn Sie die Datei „GOLD_micro_M15.csv“ nicht finden können, suchen Sie sie im Stammverzeichnis des Clients, z. B. befindet sich meine Datei im Pfad: „D:\\Projekt\\mt\\MT5\\“.
Ich danke Ihnen für Ihre Geduld beim Lesen, ich hoffe, Sie haben etwas davon und wünsche Ihnen ein glückliches Leben, und wir sehen uns im nächsten Kapitel!
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/13253
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.