English Русский 中文 Español 日本語 Português
preview
Datenkennzeichnung für Zeitreihenanalyse (Teil 2): Datensätze mit Trendmarkern mit Python erstellen

Datenkennzeichnung für Zeitreihenanalyse (Teil 2): Datensätze mit Trendmarkern mit Python erstellen

MetaTrader 5Experten | 13 Dezember 2023, 10:06
380 0
Yuqiang Pan
Yuqiang Pan

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

  1. Welche Python-Bibliothek soll ich wählen?
  2. Daten vom MT5-Client mit der MetaTrader5-Bibliothek abrufen
  3. Konvertierung von Datenformaten
  4. Datenkennzeichnung
  5. Manuelles Korrekturlesen
  6. 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.

  1. statsmodels - Python-Modul, mit dem Nutzer Daten untersuchen, statistische Modelle schätzen und statistische Tests durchführen können: http://statsmodels.sourceforge.net
  2. dynts - Python-Paket für die Analyse und Manipulation von Zeitreihen: https://github.com/quantmind/dynts
  3. PyFlux - Python-Bibliothek für Zeitreihenmodellierung und Inferenz (frequentistisch und Bayesianisch) auf Modelle: https://github.com/RJT1990/pyflux
  4. tsfresh - Automatische Extraktion von relevanten Merkmalen aus Zeitreihen: https://github.com/blue-yonder/tsfresh
  5. 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
  6. 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
  7. tsmoothie - Eine Python-Bibliothek zur Glättung von Zeitreihen und zur Erkennung von Ausreißern in vektorisierter Form: https://github.com/cerlymarco/tsmoothie
  8. 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
  9. gluon-ts - Probabilistische Zeitreihenmodellierung in Python: https://github.com/awslabs/gluon-ts
  10. gs-quant - Python-Toolkit für die quantitative Finanzwirtschaft: https://github.com/goldmansachs/gs-quant
  11. willowtree - Robuste und flexible Python-Implementierung des Weidenbaum-Gitters für die Preisbildung von Derivaten: https://github.com/federicomariamassari/willowtree
  12. financial-engineering - Anwendungen von Monte-Carlo-Methoden für Finanz-Engineering-Projekte, in Python: https://github.com/federicomariamassari/financial-engineering
  13. optlib - Eine in Python geschriebene Bibliothek für die Preisgestaltung von Finanzoptionen: https://github.com/dbrojas/optlib
  14. tf-quant-finance - Leistungsstarke TensorFlow-Bibliothek für quantitative Finanzen: https://github.com/google/tf-quant-finance
  15. Q-Fin - Eine Python-Bibliothek für die Finanzmathematik: https://github.com/RomanMichaelPaolucci/Q-Fin
  16. 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
  17. finoptions - Vollständige Python-Implementierung des R-Pakets fOptions mit teilweiser Implementierung von fExoticOptions zur Preisgestaltung verschiedener Optionen: https://github.com/bbcho/finoptions-dev
  18. pypme - PME (Public Market Equivalent) Berechnung: https://github.com/ymyke/pypme
  19. Blankly - Vollständig integriertes Backtesting, Papierhandel und Live-Einsatz: https://github.com/Blankly-Finance/Blankly
  20. TA-Lib - Python-Wrapper für TA-Lib (http://ta-lib.org/): https://github.com/mrjbq7/ta-lib
  21. zipline - Pythonische algorithmische Handelsbibliothek: https://github.com/quantopian/zipline
  22. QuantSoftware Toolkit - Python-basiertes Open-Source-Software-Framework zur Unterstützung der Portfoliokonstruktion und -verwaltung: https://github.com/QuantSoftware/QuantSoftwareToolkit
  23. finta - Gemeinsame Indikatoren für die technische Finanzanalyse, implementiert in Pandas: https://github.com/peerchemist/finta
  24. Tulipy - Finanztechnische Analyse Indikator Bibliothek (Python Bindungen für tulipindicators): https://github.com/cirla/tulipy
  25. lppls - Ein Python-Modul zur Anpassung des Models Power Law Singularity (LPPLS): https://github.com/Boulder-Investment-Technologies/lppls
Dort verwenden wir die Bibliothek „pytrendseries“, um Daten zu verarbeiten, Trends zu kennzeichnen und Datensätze zu erstellen, da diese Bibliothek die Vorteile einer einfachen Bedienung und bequemen Visualisierung bietet. Beginnen wir mit der Erstellung unserer Datensätze!


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

    env

    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“:

    Einstellung

    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:

    f0

    Klicken Sie auf Weiter und geben Sie einen Dateinamen ein, z. B. so:

    f1

    Nachdem Sie auf OK geklickt haben, wird das folgende Fenster angezeigt:

    f3

    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:

    aus

    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:

    o0

    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))

    d

    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))


    o2


    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)

    f1

    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

    f2


    2. Kennzeichnen der Daten

    1). Parsen des Datenformats
      ds

    ① 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.
    Natürlich geht es nicht nur um die oben genannten Methoden.


    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

    Beigefügte Dateien |
    Label_data.py (1.84 KB)
    Verständnis der Auftragsvergabe in MQL5 Verständnis der Auftragsvergabe in MQL5
    Bei der Entwicklung jedes Handelssystems gibt es eine Aufgabe, die wir effektiv bewältigen müssen. Diese Aufgabe besteht darin, Aufträge zu erteilen oder das erstellte Handelssystem automatisch mit Aufträgen umgehen zu lassen, da dies in jedem Handelssystem von entscheidender Bedeutung ist. Daher finden Sie in diesem Artikel die meisten Themen, die Sie über diese Aufgabe verstehen müssen, um Ihr Handelssystem in Bezug auf die Auftragsvergabe effektiv zu gestalten.
    Datenkennzeichnung für Zeitreihenanalyse (Teil 1):Erstellen eines Datensatzes mit Trendmarkierungen durch den EA auf einem Chart Datenkennzeichnung für Zeitreihenanalyse (Teil 1):Erstellen eines Datensatzes mit Trendmarkierungen durch den EA auf einem Chart
    In dieser Artikelserie werden verschiedene Methoden zur Kennzeichnung von Zeitreihen vorgestellt, mit denen Daten erstellt werden können, die den meisten Modellen der künstlichen Intelligenz entsprechen. Eine gezielte und bedarfsgerechte Kennzeichnung von Daten kann dazu führen, dass das trainierte Modell der künstlichen Intelligenz besser mit dem erwarteten Design übereinstimmt, die Genauigkeit unseres Modells verbessert wird und das Modell sogar einen qualitativen Sprung machen kann!
    Das Preisbewegungsmodell und seine wichtigsten Aspekte. (Teil 3): Berechnung der optimalen Parameter des Börsenhandels Das Preisbewegungsmodell und seine wichtigsten Aspekte. (Teil 3): Berechnung der optimalen Parameter des Börsenhandels
    Im Rahmen des vom Autor entwickelten technischen Ansatzes, der auf der Wahrscheinlichkeitstheorie basiert, werden die Bedingungen für die Eröffnung einer profitablen Position gefunden und die optimalen (gewinnmaximierenden) Take-Profit- und Stop-Loss-Werte berechnet.
    Kategorientheorie in MQL5 (Teil 20): Ein Abstecher über die Selbstaufmerksamkeit (Self-Attention) und den Transformer Kategorientheorie in MQL5 (Teil 20): Ein Abstecher über die Selbstaufmerksamkeit (Self-Attention) und den Transformer
    Wir schweifen in unserer Serie ab, indem wir über einen Teil des Algorithmus zu chatGPT nachdenken. Gibt es Ähnlichkeiten oder Konzepte, die den natürlichen Transformationen entlehnt sind? Wir versuchen, diese und andere Fragen in einem unterhaltsamen Stück zu beantworten, mit unserem Code in einem Signalklassenformat.