English Русский 中文 Español 日本語 Português
preview
Integration von ML-Modellen mit dem Strategy Tester (Schlussfolgerung): Implementierung eines Regressionsmodells für die Preisvorhersage

Integration von ML-Modellen mit dem Strategy Tester (Schlussfolgerung): Implementierung eines Regressionsmodells für die Preisvorhersage

MetaTrader 5Beispiele | 19 März 2024, 14:12
126 0
Jonathan Pereira
Jonathan Pereira

Einleitung:

Im vorangegangenen Artikel haben wir die Implementierung einer CSV-Dateiverwaltungsklasse zum Speichern und Abrufen von Daten im Zusammenhang mit Finanzmärkten abgeschlossen. Nachdem wir die Infrastruktur geschaffen haben, sind wir nun bereit, diese Daten zu nutzen, um ein maschinelles Lernmodell zu erstellen und zu trainieren.

Unsere Aufgabe in diesem Artikel ist es, ein Regressionsmodell zu implementieren, das den Schlusskurs eines Finanzinstruments innerhalb einer Woche vorhersagen kann. Diese Prognose ermöglicht es uns, das Marktverhalten zu analysieren und fundierte Entscheidungen beim Handel mit Finanzanlagen zu treffen.

Preisprognosen sind ein nützliches Instrument für die Entwicklung von Handelsstrategien und die Entscheidungsfindung auf dem Finanzmarkt. Die Fähigkeit, Preistrends genau vorherzusagen, kann zu besseren Investitionsentscheidungen führen, die Gewinne maximieren und Verluste minimieren. Darüber hinaus können Preisprognosen helfen, Handelschancen zu erkennen und Risiken zu steuern.

Zur Umsetzung unseres Regressionsmodells führen wir die folgenden Schritte durch:

  1. Sammeln und Aufbereiten von Daten: Mithilfe eines Python-Skripts werden wir historische Kursdaten und andere erforderliche Informationen abrufen. Wir werden diese Daten verwenden, um unser Regressionsmodell zu trainieren und zu testen.

  2. Wählen und trainieren eines Modells: Wir wählen ein geeignetes Regressionsmodell für unsere Aufgabe aus und trainieren es anhand der gesammelten Daten. Es gibt verschiedene Regressionsmodelle wie die lineare Regression, die polynomiale Regression und die Support-Vector-Regression (SVR). Die Wahl des Modells hängt von seiner Eignung für die Lösung unseres Problems und von der im Trainingsprozess erzielten Leistung ab.

  3. Bewerten der Leistung des Modells: Um sicherzustellen, dass unser Regressionsmodell korrekt funktioniert, müssen wir seine Leistung durch eine Reihe von Tests bewerten. Diese Bewertung wird uns helfen, mögliche Probleme zu erkennen und das Modell gegebenenfalls anzupassen.

Am Ende dieses Artikels werden wir ein Regressionsmodell erhalten, das den Schlusskurs eines finanziellen Vermögenswertes für eine Woche vorhersagen kann. Diese Prognose wird es uns ermöglichen, effektivere Handelsstrategien zu entwickeln und fundierte Entscheidungen auf dem Finanzmarkt zu treffen.


Abschnitt 1: Auswählen eines Regressionsmodells

Vor der Anwendung unseres Regressionsmodells zur Vorhersage des Wochenschlusskurses eines finanziellen Vermögenswerts ist es notwendig, die verschiedenen Arten von Regressionsmodellen und ihre Merkmale zu verstehen. So können wir das am besten geeignete Modell zur Lösung unseres Problems auswählen. In diesem Abschnitt werden wir einige der gängigsten Regressionsmodelle erörtern:

  1. Die lineare Regression ist eines der einfachsten und beliebtesten Regressionsmodelle. Sie geht von einer linearen Beziehung zwischen den unabhängigen Variablen und der abhängigen Variable aus. Ziel ist es, eine gerade Linie zu finden, die am besten zu den Daten passt und gleichzeitig die Summe der quadratischen Fehler minimiert. Obwohl die lineare Regression leicht zu verstehen und umzusetzen ist, eignet sie sich möglicherweise nicht für Probleme, bei denen die Beziehung zwischen den Variablen nicht linear ist.

  2. Die polynomiale Regression ist eine Erweiterung der linearen Regression, bei der nichtlineare Beziehungen zwischen Variablen berücksichtigt werden. Verwendet Polynome unterschiedlichen Grades, um eine Kurve an die Daten anzupassen. Die polynomiale Regression kann eine bessere Annäherung für komplexere Probleme bieten; es ist jedoch wichtig, eine Überanpassung zu vermeiden, die auftritt, wenn das Modell zu eng an die Trainingsdaten angepasst wird, wodurch seine Fähigkeit zur Verallgemeinerung auf ungesehene Daten verringert wird.

  3. Die Entscheidungsbaum-Regression ist ein entscheidungsbaumbasiertes Modell, das den Merkmalsraum in verschiedene, sich nicht überschneidende Regionen unterteilt. In jeder Region wird die Prognose auf der Grundlage des Durchschnitts der beobachteten Werte erstellt. Die Entscheidungsbaumregression ist in der Lage, komplexe nichtlineare Beziehungen zwischen Variablen zu erfassen, kann aber zu einer Überanpassung führen, insbesondere wenn der Baum sehr groß wird. Pruning und Kreuzvalidierungstechniken können verwendet werden, um eine Überanpassung zu verhindern.

  4. Support Vector Regression (SVR) ist eine Erweiterung des Algorithmus‘ der Support Vector Machine (SVM) zur Lösung von Regressionsproblemen. SVR versucht, die beste Funktion für die Daten zu finden und dabei eine maximale Spanne zwischen der Funktion und den Trainingspunkten zu erhalten. SVR ist in der Lage, nichtlineare und komplexe Beziehungen mithilfe von Kernel-Funktionen wie der Radial Basis Function (RBF) zu modellieren. Das SVR-Training kann jedoch im Vergleich zu anderen Regressionsmodellen sehr rechenintensiv sein.

Um das am besten geeignete Regressionsmodell für die Vorhersage des Schlusskurses einer Finanzanlage für eine Woche auszuwählen, müssen wir die Komplexität des Problems und die Beziehung zwischen den Variablen berücksichtigen. Darüber hinaus müssen wir das Gleichgewicht zwischen Modellleistung und Rechenaufwand berücksichtigen. Generell empfehle ich, mit verschiedenen Modellen zu experimentieren und ihre Einstellungen anzupassen, um die beste Leistung zu erzielen.

Bei der Auswahl eines Modells ist es wichtig, mehrere Kriterien zu berücksichtigen, die die Qualität und Anwendbarkeit des Modells beeinflussen. In diesem Abschnitt geht es um die wichtigsten Kriterien, die bei der Auswahl eines Regressionsmodells berücksichtigt werden müssen:

  1. Die Leistung eines Regressionsmodells ist sehr wichtig, um die Genauigkeit und Nützlichkeit der Vorhersagen zu gewährleisten. Wir können die Leistung unter anderem anhand des mittleren quadratischen Fehlers (MSE) und des mittleren absoluten Fehlers (MAE) bewerten. Beim Vergleich verschiedener Modelle ist es wichtig, dasjenige zu wählen, das bei diesen Kriterien am besten abschneidet.

  2. Die Interpretierbarkeit des Modells ist die Fähigkeit, die Beziehungen zwischen den Variablen zu verstehen und zu erkennen, wie sie die Vorhersage beeinflussen. Einfachere Modelle wie die lineare Regression sind im Allgemeinen leichter zu interpretieren als komplexere Modelle wie neuronale Netze. Die Interpretierbarkeit ist besonders wichtig, wenn wir unsere Vorhersagen anderen erklären oder die Faktoren verstehen wollen, die die Ergebnisse beeinflussen.

  3. Die Komplexität eines Regressionsmodells hängt von der Anzahl der Parameter und der Struktur des Modells ab. Komplexere Modelle können subtilere und nichtlineare Beziehungen in den Daten erfassen, sind aber auch anfälliger für eine Überanpassung. Es ist wichtig, ein Gleichgewicht zwischen der Komplexität des Modells und der Fähigkeit, es auf unbekannte Daten zu verallgemeinern, zu finden.

  4. Die Trainingszeit ist ein wichtiger Punkt, der insbesondere bei der Arbeit mit großen Datensätzen oder beim iterativen Training von Modellen zu berücksichtigen ist. Einfachere Modelle wie die lineare und polynomiale Regression benötigen in der Regel weniger Trainingszeit als andere, komplexere Modelle wie neuronale Netze oder Support-Vector-Regression. Es ist wichtig, ein Gleichgewicht zwischen Modellleistung und Trainingszeit zu finden, um sicherzustellen, dass das Modell anwendbar ist.

  5. Die Robustheit eines Regressionsmodells ist seine Fähigkeit, mit Ausreißern und Rauschen in den Daten umzugehen. Robuste Modelle reagieren weniger empfindlich auf kleine Änderungen in den Daten und liefern stabilere Prognosen. Es ist wichtig, ein Modell zu wählen, das mit Ausreißern und Rauschen in den Daten umgehen kann.

Bei der Wahl des am besten geeigneten Regressionsmodells für die Prognose von Schlusskursen ist es wichtig, diese Kriterien abzuwägen und das richtige Gleichgewicht zwischen ihnen zu finden. In der Regel empfiehlt es sich, verschiedene Modelle zu testen und ihre Parameter zur Optimierung der Leistung fein abzustimmen. Auf diese Weise können Sie das beste Modell für ein bestimmtes Problem auswählen.

Auf der Grundlage der oben genannten Kriterien habe ich mich in diesem Artikel für die Verwendung des Entscheidungsbaum-Regressionsmodells zur Vorhersage des Schlusskurses entschieden. Die Wahl dieses Modells ist aus den folgenden Gründen gerechtfertigt:

  1. Leistung: Entscheidungsbäume eignen sich in der Regel gut für Regressionsprobleme, da sie in der Lage sind, nichtlineare Beziehungen und Wechselwirkungen zwischen Variablen zu erfassen. Durch die richtige Abstimmung von Modellhyperparametern, wie z. B. der Baumtiefe und der Mindestanzahl von Stichproben pro Blatt, können wir ein Gleichgewicht zwischen Fitness und Verallgemeinerung erreichen.

  2. Interpretierbarkeit: Einer der Hauptvorteile von Entscheidungsbäumen ist ihre Interpretierbarkeit. Entscheidungsbäume sind eine Reihe von Entscheidungen auf der Grundlage von Attributen und deren Werten, wodurch sie leicht zu verstehen sind. Dies ist nützlich, um Prognosen zu rechtfertigen und die Faktoren zu verstehen, die die Schlusskurse beeinflussen.

  3. Komplexität: Die Komplexität von Entscheidungsbäumen kann durch Abstimmung der Hyperparameter des Modells gesteuert werden. Auf diese Weise können wir ein Gleichgewicht zwischen der Fähigkeit, komplexe Beziehungen zu modellieren, und der Einfachheit des Modells finden und gleichzeitig eine Überanpassung vermeiden.

  4. Trainingszeit: Entscheidungsbäume lassen sich in der Regel relativ schnell trainieren, verglichen mit komplexeren Modellen wie neuronalen Netzen oder SVMs. Dadurch eignet sich das Entscheidungsbaum-Regressionsmodell für Fälle, in denen die Trainingszeit ein wichtiger Faktor ist.

  5. Robustheit: Entscheidungsbäume sind robust gegenüber Ausreißern und Rauschen in den Daten, da jede Entscheidung auf einer Reihe von Stichproben und nicht auf einer einzelnen Beobachtung beruht, was zur Stabilität der Vorhersagen und zur Zuverlässigkeit des Modells beiträgt.

In Anbetracht der besprochenen Kriterien und der Vorteile der Entscheidungsbaumregression bin ich der Meinung, dass dieses Modell für die Vorhersage des Wochenschlusskurses geeignet ist. Es ist jedoch zu bedenken, dass die Wahl der Modelle je nach dem spezifischen Kontext und den Anforderungen des jeweiligen Problems variieren kann. Um das am besten geeignete Modell für Ihr spezifisches Problem auszuwählen, sollten Sie daher verschiedene Regressionsmodelle testen und vergleichen.


Abschnitt 2: Vorbereitung der Daten

Datenvorbereitung und -bereinigung sind wichtige Schritte bei der Implementierung eines Regressionsmodells, da sich die Qualität der Eingabedaten direkt auf die Effizienz und Leistung des Modells auswirkt. Diese Schritte sind aus den folgenden Gründen wichtig:

  1. Eliminierung von Ausreißern und Rauschen: Rohdaten können Ausreißer, Rauschen und Fehler enthalten, die die Leistung des Modells beeinträchtigen können. Wenn Sie diese Unstimmigkeiten erkennen und korrigieren, können Sie die Qualität Ihrer Daten und damit die Genauigkeit Ihrer Prognosen verbessern.

  2. Füllen und Entfernen fehlender Werte: Unvollständige Daten sind in Datensätzen häufig anzutreffen, und fehlende Werte können die Leistung des Modells beeinträchtigen. Um die Datenintegrität und -zuverlässigkeit zu gewährleisten, können Sie in Erwägung ziehen, fehlende Werte zu ergänzen, Datensätze mit fehlenden Daten zu löschen oder spezielle Techniken zum Umgang mit solchen Daten anzuwenden. Die Entscheidung zwischen Ergänzen und Löschen hängt von der Art der Daten, der Anzahl der fehlenden Werte und den möglichen Auswirkungen dieser Werte auf die Modellleistung ab. Es ist wichtig, jede Situation sorgfältig zu analysieren und den am besten geeigneten Ansatz zur Lösung des Problems zu wählen.

  3. Auswählen von Variablen: Nicht alle im Datensatz vorhandenen Variablen sind möglicherweise wichtig oder nützlich für die Vorhersage des Schlusskurses. Durch eine geeignete Variablenauswahl kann sich das Modell auf die wichtigsten Merkmale konzentrieren, was die Leistung verbessert und die Komplexität des Modells verringert.

  4. Datenumwandlung: Manchmal müssen die Originaldaten transformiert werden, um den Annahmen des Regressionsmodells zu entsprechen oder um die Beziehung zwischen unabhängigen Variablen und der abhängigen Variable zu verbessern. Beispiele für Transformationen sind Normalisierung, Standardisierung und die Verwendung von mathematischen Funktionen wie Logarithmus oder Quadratwurzel.

  5. Teilung der Daten: Teilen Sie den Datensatz in einen Trainings- und einen Testteilsatz auf, um die Leistung des Regressionsmodells richtig zu bewerten. Durch diese Aufteilung kann das Modell auf einer Teilmenge von Daten trainiert und auf seine Fähigkeit zur Verallgemeinerung auf ungesehene Daten getestet werden, was eine Bewertung der Leistung des Modells in realen Situationen ermöglicht.

Die Phase der Datenaufbereitung und -bereinigung stellt sicher, dass das Modell anhand von Qualitätsdaten trainiert und bewertet wird, um seine Effektivität und Nützlichkeit bei der Vorhersage der Schlusskurse zu maximieren.

Wir werden uns ein grundlegendes Beispiel für die Vorbereitung von Daten für ein Regressionsmodell mit Python ansehen. Ich möchte jedoch darauf hinweisen, dass es wichtig ist, Ihre Kenntnisse zu vertiefen, da jeder spezifische Datensatz und jedes Problem spezielle Vorbereitungsansätze und -methoden erfordern kann. Daher empfehle ich Ihnen dringend, sich die Zeit zu nehmen, die verschiedenen Methoden der Datenaufbereitung zu lernen und zu verstehen.

Zur Datenerfassung wird die Funktion get_rates_between verwendet, die für die Erfassung von Finanzdaten für eine bestimmte Finanzanlage und einen bestimmten Zeitraum vorgesehen ist. Es wird die MetaTrader 5-Bibliothek verwendet, um sich mit der Handelsplattform zu verbinden und historische Kursdaten für verschiedene Zeitintervalle zu erhalten.

Die Funktion hat die folgenden Parameter:

  • symbol: eine Zeichenfolge, die das Finanzsymbol darstellt (z. B. „PETR3“, „EURUSD“).
  • period: eine ganze Zahl, die den Zeitrahmen angibt, für den die Daten gesammelt werden (z. B. mt5.TIMEFRAME_W1 für wöchentliche Daten).
  • ini: ein Datetime-Objekt, das die Startzeit und das Datum des Zeitintervalls für die Datenerfassung darstellt.
  • end: ein datetime-Objekt, das das Enddatum und die Endzeit des Zeitintervalls für die Datenerfassung darstellt.

Die Funktion beginnt mit der Überprüfung des MetaTrader 5-Boot. Wenn das Booten fehlschlägt, gibt die Funktion eine Ausnahme zurück und beendet das Programm.

Dann verwendet die Funktion mt5.copy_rates_range(), um Finanzdaten für das angegebene Symbol und den angegebenen Zeitraum zu erhalten. Die Daten werden im DataFrame Objekt von Pandas gespeichert, einer zweidimensionalen, mit Achsen beschrifteten Datenstruktur, die sich für die Speicherung von Finanzdaten eignet.

Nach dem Empfang der Daten prüft die Funktion, ob der DataFrame leer ist. Wenn die Funktion leer ist, gibt sie eine Ausnahme zurück, da dies bedeutet, dass beim Sammeln der Daten ein Fehler aufgetreten ist.

Wenn alles gut geht, konvertiert die Funktion die Spalte „time“ des DataFrame in ein lesbares Datums- und Zeitformat unter Verwendung der Funktion pd.to_datetime() Funktion. Die Spalte „Zeit“ ist als DataFrame-Index definiert, der den Datenzugriff und die Datenmanipulation erleichtert.

def get_rates_between(symbol:str, period : int, ini : datetime, end : datetime):
    if not mt5.initialize():
        print("initialize() failed")
        mt5.shutdown()
        raise Exception("Error Getting Data")

    rates = mt5.copy_rates_range(symbol, period, ini, end)
    mt5.shutdown()
    rates = pd.DataFrame(rates)

    if rates.empty:
        raise Exception("Error Getting Data")

    rates['time'] = pd.to_datetime(rates['time'], unit='s')
    rates.set_index(['time'], inplace=True)

    return rates

In diesem Beispiel werden wir Finanzdaten für das Währungspaar EURUSD für den wöchentlichen Zeitraum vom 1. Januar 2000 bis zum 31. Dezember 2022 verwenden. Hierfür verwenden wir die Funktion get_rates_between. Importieren wir zunächst die erforderlichen Bibliotheken:

import pandas as pd
from datetime import datetime, timezone
import MetaTrader5 as mt5
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

Bestimmen wir als Nächstes Informationen über das Finanzsymbol, das wir analysieren wollen:

symbol = "EURUSD"
date_ini = datetime(2000, 1, 1, tzinfo=timezone.utc)
date_end = datetime(2022, 12, 31, tzinfo=timezone.utc)
period = mt5.TIMEFRAME_W1

Nun können wir die Funktion get_rates_between mit den zuvor definierten Informationen aufrufen:

df = get_rates_between(symbol=symbol, period=period, ini=date_ini, end=date_end)

Sobald wir die Daten haben, besteht der nächste Schritt darin, sie für die Erstellung eines maschinellen Lernmodells vorzubereiten. Die Vorbereitung umfasst das Entfernen von Ausreißern und dem Rauschen, die Auswahl von Variablen, die Umwandlung der Daten und die Aufteilung in Trainings- und Testsätze. Betrachten wir die einzelnen Schritte im Detail.

Entfernen von Rauschen und der Ausreißer:

Der erste Schritt besteht darin, Ausreißer und Rauschen aus den Daten zu entfernen. Rauschen ist eine zufällige und unerwünschte Veränderung der Daten, das das Erkennen von Mustern erschweren kann. Ausreißer sind Werte, die sich signifikant von anderen Werten in unserem Datensatz unterscheiden. Beides kann sich negativ auf die Leistung des Modells auswirken.

Es gibt verschiedene Methoden zur Entfernung von Ausreißern und Rauschen. In diesem Artikel wird die Methode der exponentiellen Glättung verwendet, die den jüngsten Daten ein exponentiell abnehmendes Gewicht zuweist und so dazu beiträgt, Schwankungen zu glätten. Dazu verwenden wir die Funktion ewm von Pandas.

smoothed_df = df.ewm(alpha=0.1).mean()

Eigentlich können Sie jede Methode verwenden, die zu Ihrem Modell und Ihren Daten passt. Hier verwenden wir die exponentielle Glättung nur zur Vereinfachung des Beispiels und um zu zeigen, wie die Daten verarbeitet werden. In realen Szenarien empfiehlt es sich, verschiedene Methoden zur Entfernung von Ausreißern und Rauschen zu untersuchen und zu bewerten, um den besten Ansatz für einen bestimmten Datensatz und ein bestimmtes Problem zu finden. Andere beliebte Methoden sind die Filterung des gleitenden Durchschnitts, das Perzentil-Screening und das Clustering.


Auswahl der Variablen

Der nächste Schritt ist die Auswahl der Variablen, die wir als Merkmale und Ziele verwenden werden. In diesem Beispiel verwenden wir den Eröffnungskurs, den Indikator Moving Average Convergence Divergence (MACD) und den exponentiellen gleitenden Durchschnitt (EMA) als Merkmale. Das Ziel ist der Schlusskurs.

# Function to calculate MACD
def macd(df, fast_period=12, slow_period=26, signal_period=9):
    ema_fast = df['close'].ewm(span=fast_period).mean()
    ema_slow = df['close'].ewm(span=slow_period).mean()
    macd_line = ema_fast - ema_slow
    signal_line = macd_line.ewm(span=signal_period).mean()
    return macd_line, signal_line

# Function to calculate EMA
def ema(df, period=30):
    return df['close'].ewm(span=period).mean()

# Calculating MACD and the signal line
smoothed_df['macd'], smoothed_df['signal'] = macd(smoothed_df)

# Calculating EMA
smoothed_df['ema'] = ema(smoothed_df)

# Selecting the   variables
selected_df = smoothed_df[['open', 'macd', 'ema', 'close']].dropna()

Datenkonvertierung

Die Datentransformation ist wichtig, damit die Variablen auf der gleichen Skala liegen und wir sie richtig vergleichen können. In diesem Beispiel verwenden wir die Min-Max-Normalisierung, bei der die Daten in eine Skala von 0 bis 1 umgewandelt werden.

scaler = MinMaxScaler()
normalized_df = pd.DataFrame(scaler.fit_transform(selected_df), columns=selected_df.columns, index=selected_df.index)

Aufteilung der Daten

Schließlich werden die Daten in Trainings- und Testsätze aufgeteilt. Wir verwenden die Trainingsdaten, um das Modell zu trainieren, und die Testdaten, um die Leistung zu bewerten.

X = normalized_df[['open', 'macd', 'ema']]
y = normalized_df['close']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

In Abschnitt 2 führen wir mehrere wichtige Schritte durch, um sicherzustellen, dass die Daten für die Verwendung im maschinellen Lernmodell bereit sind.

Wir beginnen mit dem Laden von Finanzsymboldaten über die MetaTrader 5 API, konvertieren diese dann in einen Pandas DataFrame und richten anschließend eine Zeitspalte ein, die als Index verwendet wird. Anschließend werden die Daten bereinigt, indem fehlende Werte entfernt und auf Ausreißer und Inkonsistenzen geprüft werden. Diese Maßnahme ist notwendig, um sicherzustellen, dass das Modell nicht durch ungültige oder irrelevante Werte beeinflusst wird.

Für die Variablen haben wir zuvor Open, MACD und EMA als Merkmale und Close als Ziel gewählt. Bitte beachten Sie jedoch, dass diese Auswahl zufällig getroffen wurde, um ein deutliches Beispiel zu geben.

Wir haben die Daten auch normalisiert. Dies ist wichtig, um sicherzustellen, dass Unterschiede im Datenumfang das Modell nicht beeinflussen. Schließlich teilen wir die Daten in Trainings- und Testsätze auf, um die Fähigkeit des Modells zur Generalisierung auf neue Daten zu bewerten.

Diese Schritte der Datenaufbereitung sind entscheidend dafür, dass die Vorhersagen des Modells genau und effizient sind. Wenn die Daten fertig sind, können wir zum nächsten Schritt übergehen, nämlich der Erstellung und dem Training eines maschinellen Lernmodells.


Abschnitt 3: Training und Evaluierung eines Regressionsmodells mit Hilfe eines Entscheidungsbaums

Nach der Erstellung der Trainings- und Testsätze und der entsprechenden Vorbereitung der Daten können wir unser Entscheidungsbaum-Regressionsmodell erstellen, trainieren und bewerten. Der Entscheidungsbaum ist eine überwachte Lernmethode, die wir sowohl auf Klassifizierungs- als auch auf Regressionsprobleme anwenden können. In diesem Fall verwenden wir einen Entscheidungsbaum zur Vorhersage des Schlusskurses einer Finanzanlage.

  • Bibliotheken importieren und ein Modell erstellen

Beginnen wir mit dem Importieren der notwendigen Bibliotheken und dem Erstellen einer Instanz des DecisionTreeRegressor-Modells von scikit-learn.

from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error, r2_score

regressor = DecisionTreeRegressor(random_state=42)

  • Modellhaftes Training

Als Nächstes wird das Modell anhand des Trainingsdatensatzes (X_train und y_train) trainiert.

regressor.fit(X_train, y_train)

  • Vorhersagen machen

Mit dem trainierten Modell können wir Vorhersagen für den Testdatensatz (X_test) treffen und die Ergebnisse mit den tatsächlichen Werten des Testdatensatzes (y_test) vergleichen.

y_pred = regressor.predict(X_test)

  • Bewertung der Modellleistung

Die Bewertung der Leistung eines Modells ist wichtig, um zu verstehen, wie gut es zu den Daten passt und Vorhersagen macht. Neben dem mittleren quadratischen Fehler (mean square error, MSE) und dem Bestimmtheitsmaß (R²) können wir auch andere Metriken zur Bewertung der Leistung unseres Entscheidungsbaum-Regressionsmodells verwenden. Einige zusätzliche Metriken, die wir untersuchen können, sind:

  • Der mittlerer absoluter Fehler (mean absolute error, MAE) der den Durchschnitt der absoluten Differenz zwischen Prognosen und tatsächlichen Werten darstellt. Dies ist eine leicht verständliche Kennzahl, die zeigt, wie weit die Prognosen von den tatsächlichen Werten entfernt sind.
  • Der mittlere absolute prozentuale Fehler (mean absolute percentage error MAPE,) ist der Durchschnitt der absoluten prozentualen Fehler zwischen Prognosen und tatsächlichen Werten. Mit dieser Metrik lässt sich die Effizienz des Modells in Prozent bewerten, was beim Vergleich von Modellen mit unterschiedlichen Werteskalen nützlich sein kann.
  • Der mittlere quadratische Fehler (Root Mean Square Error, RMSE) ist die Quadratwurzel des MSE. Der Vorteil dieser Metrik besteht darin, dass sie dieselben Einheiten wie die Zielvariable hat, wodurch die Ergebnisse leichter zu interpretieren sind.

Wir können die Scikit-Learn-Bibliothek verwenden, um diese zusätzlichen Metriken zu berechnen. Zunächst importieren wir die erforderlichen Funktionen:

from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

dann berechnen wir die Metriken anhand der prognostizierten und tatsächlichen Werte:
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

Jetzt können wir die Ergebnisse demonstrieren:

print(f"MAE: {mae:.4f}")
print(f"MSE: {mse:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"R²: {r2:.4f}")

  • Aufbau des Modells und seine Optimierung

Je nach den erzielten Ergebnissen kann eine Anpassung und Optimierung des Modells erforderlich sein. Dies kann durch die Einstellung von Entscheidungsbaum-Hyperparametern erfolgen, wie z. B. maximale Tiefe (max_depth), Mindestanzahl von Stichproben, die erforderlich sind, um einen internen Knoten zu teilen (min_samples_split), Mindestanzahl von Stichproben, die erforderlich sind, um in einem Blattknoten zu sein (min_samples_leaf), und andere.

Zur Optimierung von Hyperparametern gibt es Methoden wie die Rastersuche (GridSearchCV) oder die randomisierte Suche (RandomizedSearchCV) aus scikit-learn. Diese Methoden ermöglichen es Ihnen, verschiedene Kombinationen von Hyperparametern zu testen und die beste Konfiguration für das Modell zu finden.

from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeRegressor


regressor = DecisionTreeRegressor(random_state=42)

param_grid = {
    'max_depth': [3, 4, 5, 6, 7, 8],
    'min_samples_split': [2, 3, 4],
    'min_samples_leaf': [1, 2, 3]
}

grid_search = GridSearchCV(estimator=regressor, param_grid=param_grid, scoring='neg_mean_squared_error', cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train)

best_params = grid_search.best_params_
print(f"Melhores hiperparâmetros: {best_params}")

best_regressor = DecisionTreeRegressor(**best_params, random_state=42)
best_regressor.fit(X_train, y_train)

y_pred_optimized = best_regressor.predict(X_test)

mae_optimized = mean_absolute_error(y_test, y_pred_optimized)
mse_optimized = mean_squared_error(y_test, y_pred_optimized)
rmse_optimized = np.sqrt(mse_optimized)
r2_optimized = r2_score(y_test, y_pred_optimized)

print(f"MAE otimizado: {mae_optimized:.4f}")
print(f"MSE otimizado: {mse_optimized:.4f}")
print(f"RMSE otimizado: {rmse_optimized:.4f}")
print(f"R² otimizado: {r2_optimized:.4f}")


  • Preise denormalisieren und ein Diagramm erstellen

Um Preise zu denormalisieren und ein Diagramm zu erstellen, können Sie inverse_transform von MinMaxScaler verwenden. Zunächst werden der tatsächliche Preis (y_test) und der erwartete Preis (y_pred_optimised) denormalisiert und dann mithilfe der Matplotlib-Bibliothek ein Diagramm erstellt. Hier ist der aktualisierte Code:

import matplotlib.pyplot as plt

# Function for denormalizing prices
def denormalize_price(scaler, normalized_price, column_name):
    dummy_df = pd.DataFrame(np.zeros((len(normalized_price), len(selected_df.columns))), columns=selected_df.columns)
    dummy_df[column_name] = normalized_price
    denormalized_df = scaler.inverse_transform(dummy_df)
    return denormalized_df[:, selected_df.columns.get_loc(column_name)]

# Denormalize actual and forecast prices
y_test_denorm = denormalize_price(scaler, y_test, 'close')
y_pred_optimized_denorm

In diesem Abschnitt wird die Implementierung eines Regressionsmodells mit einem Entscheidungsbaum zur Vorhersage des Schlusskurses einer Finanzanlage erörtert. Nach dem Training und der Bewertung des Modells wurden Leistungskennzahlen ermittelt und die Hyperparameter zur Optimierung der Leistung angepasst.

Es sei jedoch darauf hingewiesen, dass es sich bei diesem Beispiel nur um einen grundlegenden Ansatz handelt und dass es viele fortgeschrittene Techniken und Strategien zur Verbesserung der Modellgenauigkeit und -leistung gibt. Darüber hinaus kann die Wahl des Regressionsmodells und der Datenaufbereitung je nach Kontext und spezifischen Anforderungen der jeweiligen Aufgabe variieren.

Schließlich sollten Sie stets umfassende Modelltests, -validierungen und -wiederholungen in verschiedenen Szenarien und mit unterschiedlichen Datensätzen durchführen, um die Robustheit und Zuverlässigkeit des Modells bei der Vorhersage von Finanzmarktpreisen zu gewährleisten.


Abschnitt 4: Integration eines Regressionsmodells in einen Strategietester

In diesem Abschnitt werden wir einen detaillierten Blick auf die Erstellung eines Systems werfen, mit dem Sie ein Python-Modell direkt im MetaTrader Strategy Tester testen können. Dieser Ansatz bietet eine zusätzliche Ebene der Flexibilität bei der Modellerstellung und nutzt die Einfachheit von Python. Der Überprüfungsprozess findet im MetaTrader selbst statt, da wir das Modell in das ONNX-Format für MQL5 exportieren. Das bedeutet, dass wir unser Modell problemlos erstellen und verfeinern können, während es in der MetaTrader-Umgebung einer strengen Validierung unterzogen wird, um sicherzustellen, dass es für die Komplexität des Finanzmarktes geeignet ist.

Effektive Interaktion zwischen Python und MQL5

Dieses System basiert auf der dringenden Notwendigkeit, eine effektive Interaktion zwischen Python und MQL5 herzustellen. Um dies zu erreichen, wird eine Python-Klasse erstellt, die den Nachrichtenaustausch mit dem MQL5 Strategy Tester vereinfacht. Während das Python-Programm läuft, überwacht es die im Strategietester getätigten Geschäfte und überträgt die Kursdaten der Vermögenswerte umgehend an Python, sobald der Tester gestartet wird. Dieser kontinuierliche Informationsfluss versorgt das Regressionsmodell mit Echtzeitdaten, sodass es auf der Grundlage dieser Daten Entscheidungen treffen kann. Vielleicht möchten Sie auch zu diesem Artikel zurückkehren, um Informationen über die Implementierung einer MQL5-Klasse für die Arbeit mit CSV-Dateien aufzufrischen.

Erstellung von der Klasse File für die Kommunikation zwischen Python und MQL5

Die Klasse File ermöglicht die Kommunikation zwischen Python und dem MQL5-Strategie-Tester. Schauen wir uns die Hauptfunktionen dieser Klasse an. Ihr Hauptzweck ist die Durchführung von Dateioperationen.

Initialisierung der Klasse

Die Klasse File ist als Singleton konzipiert, was garantiert, dass es im gesamten Programm nur eine Instanz von ihr gibt. Dieser Punkt ist wichtig, um die Integrität der Kommunikation zwischen Python und MQL5 zu erhalten.

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


Überprüfen und Bearbeiten von Dateien

Die Klasse File bietet grundlegende Methoden zur Überprüfung des Vorhandenseins von Dateien, zur Behandlung von dateibezogenen Fehlern und zur Durchführung von Lese- und Schreiboperationen.

  • Die Methode __init_file prüft, ob die Datei existiert oder nicht. Wenn die Datei nicht existiert, wartet die Methode eine Sekunde und gibt dann False zurück. Mit dieser Prüfung kann sichergestellt werden, dass die Datei für den Zugriff bereit ist.

  • Die Methode __handle_error behandelt Ausnahmen, die bei der Arbeit mit Dateien auftreten können. Es identifiziert häufige Fehler wie PermissionError und FileNotFoundError und liefert detaillierte Informationen zu diesen Fehlern.

  • Die Methoden check_init_param und check_open_file werden benötigt, um CSV-Dateien zu lesen. Die erste prüft, ob die Datei existiert, und wenn ja, liest sie diese und gibt einen bestimmten Wert aus der Spalte typerun im DataFrame zurück. Die zweite Methode prüft, ob die Datei vorhanden ist, und liest sie als vollständigen DataFrame.

from pathlib import Path
from time import sleep
from typing import Tuple
import pandas as pd
from pandas.core.frame import DataFrame
import os
from errno import EACCES, EPERM, ENOENT
import sys

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

CSV_SEPARATOR = ';'

class File(metaclass=Singleton):

    def __init__(self) -> None:
        pass

    def __init_file(self, name_arq: str) -> bool:
        return Path(name_arq).is_file() or sleep(1) or False

    def __handle_error(self, e, name_arq: str):
        ERRORS = {
            EPERM: "PermissionError",
            EACCES: "PermissionError",
            ENOENT: "FileNotFoundError"
        }
        print(f"{ERRORS.get(e.errno, 'Unknown error')} error({e.errno}): {e.strerror} for:\n{name_arq}")

    def check_init_param(self, name_arq : str) -> Tuple[str]:
        while True:
            try:
                if self.__init_file(name_arq):
                    df = pd.read_csv(name_arq, sep=CSV_SEPARATOR)
                    return (df.typerun.values[0])
            except (IOError, OSError) as e:
                self.__handle_error(e, name_arq)
            except:
                print('Unexpected error:', sys.exc_info()[0])

    def check_open_file(self, name_arq: str) -> pd.DataFrame():
        while True:
            try:
                if self.__init_file(name_arq):
                    return pd.read_csv(name_arq, sep=CSV_SEPARATOR)
            except (IOError, OSError) as e:
                self.__handle_error(e, name_arq)
            except:
                print('Unexpected error:', sys.exc_info()[0])

    @staticmethod
    def save_file_csv(name_arq: str, dataset:DataFrame = pd.DataFrame({'col':['ok']})):
        dataset.to_csv(name_arq, sep=CSV_SEPARATOR)

    @staticmethod
    def save(name_arq:str, data:str):
        with open(name_arq, 'w') as f:
            f.write(data)

    @staticmethod
    def delete_file(name_arq: str):
        try:
            os.remove(name_arq)
        except:
            pass


Speichern und Löschen von Dateien

Die Klasse File verwaltet auch das Speichern und Löschen von Dateien.

  • Die Methode save_file_csv speichert DataFrame in einer CSV-Datei. Dies ist praktisch, wenn wir Daten in einem zugänglichen Format für eine spätere Analyse speichern müssen.

  • Mit der Methode Save können Sie Daten in einer Textdatei speichern. Die Daten in einer csv-Datei werden in einem bequem lesbaren Format gespeichert.

  • Die Methode delete_file löscht eine Datei aus dem System.

Datenverarbeitung in Python

Auf der Python-Seite empfängt das Programm Daten zu den Symbolpreisen und verarbeitet sie vor. Ziel dieser Vorverarbeitung ist es, sicherzustellen, dass die Daten für die Verwendung in einem Regressionsmodell geeignet sind. Schauen wir uns nun genauer an, wie das funktioniert:

  1. Standardisierung der Daten: In der Anfangsphase werden die Daten normalisiert. Dies bedeutet, dass Werte innerhalb eines bestimmten Bereichs, normalerweise zwischen 0 und 1, eingestellt werden. Die Normalisierung ist notwendig, um sicherzustellen, dass verschiedene Merkmale (z. B. Aktienkurse und Handelsvolumen) auf der gleichen Skala liegen. Dadurch werden Fehler im Modell vermieden.

  2. Erkennen und Entfernen von Ausreißern: Finanzdaten können instabil sein und Ausreißer können die Simulationsergebnisse beeinträchtigen. Das Python-Programm erkennt diese Abweichungen und korrigiert sie gegebenenfalls, um die Qualität der Quelldaten zu gewährleisten.

  3. Erstellen zusätzlicher Funktionen: In vielen Fällen werden auf der Grundlage der ursprünglichen Daten zusätzliche Merkmale erstellt. Dabei kann es sich z. B. um gleitende Durchschnitte, technische Indikatoren oder andere Messgrößen handeln, die das Modell nutzen kann, um fundiertere Entscheidungen zu treffen.

Erst wenn die Daten vollständig aufbereitet sind, geben wir sie in das Regressionsmodell ein.

Das Regressionsmodell in Aktion

Unser Regressionsmodell, das auf dem Entscheidungsbaum basiert, wurde auf historischen Daten trainiert. Sie werden nun in ein Python-Programm geladen und zur Erstellung von Prognosen auf der Grundlage der neuesten Preisdaten verwendet. Diese Prognosen sind für Handelsentscheidungen von grundlegender Bedeutung, da sie wertvolle Informationen über das zukünftige Verhalten eines Vermögenswerts liefern. Es sei darauf hingewiesen, dass wir in diesem Beispiel zwar ein bestimmtes Regressionsmodell verwenden, dieser Ansatz jedoch auf verschiedene Modelle angewendet werden kann, je nach den spezifischen Anforderungen unserer Handelsstrategie. Die Flexibilität dieses Systems ermöglicht es also, eine Vielzahl von Modellen einzubeziehen, um den individuellen Bedürfnissen jeder Strategie gerecht zu werden.

ONNX-Integration zur Verbesserung des MetaTrader 5

Ich möchte Ihnen einen interessanten Tipp geben, der unser System im MetaTrader 5 verbessern kann: die Integration mit ONNX (Open Neural Network Exchange). ONNX ist ein sehr praktisches Tool für künstliche Intelligenz, da es Ihnen ermöglicht, Modelle einfach auf den MetaTrader 5 zu übertragen.

Nachdem wir die Wirksamkeit unseres Modells im MetaTrader 5 gründlich getestet und bestätigt haben, können wir es in das ONNX-Format exportieren. Dies wird nicht nur die Möglichkeiten von MetaTrader 5 erweitern, sondern auch die Verwendung dieses Modells in verschiedenen Strategien und Plattformsystemen erleichtern.

Mit der nativen Integration von ONNX in den MetaTrader 5 kann die Nutzung von Modellen in unseren Handelsstrategien weiter ausgebaut werden.

Umfassende Tests vor dem Export

Die Wahl unseres derzeitigen Ansatzes, der eine Interaktion mit der MQL5-Umgebung beinhaltet, ist auf die Notwendigkeit zurückzuführen, umfangreiche Tests in einer kontrollierten Umgebung durchzuführen, bevor das Modell in das ONNX-Format exportiert wird. Das Erstellen und direkte Integrieren eines Modells in MQL5 kann ein komplexer und fehleranfälliger Prozess sein. Diese Methodik ermöglicht es uns, das Modell sorgfältig zu verfeinern und abzustimmen, um die gewünschten Ergebnisse zu erzielen, noch bevor es in das ONNX-Format exportiert wird.


Schlussfolgerung

Zusammenfassend lässt sich sagen, dass in diesem Artikel ein integrierter Ansatz zur Implementierung eines Regressionsmodells erörtert wird. In Abschnitt 1 haben wir die Auswahl eines Regressionsmodells erörtert, wobei wir uns auf die Bedeutung der Wahl des richtigen Algorithmus zur Lösung des jeweiligen Problems konzentriert haben. In Abschnitt 2 haben wir uns mit der Datenaufbereitung befasst, einschließlich der Verarbeitung und Bereinigung für das Modelltraining.

In Abschnitt 3 haben wir ein Regressionsmodell am Beispiel eines Entscheidungsbaums trainiert und bewertet. Darüber hinaus haben wir die Aufteilung der Daten in Trainings- und Testdatensätze sowie die Auswahl von Hyperparametern zur Optimierung der Modellleistung berücksichtigt.

Schließlich haben wir in Abschnitt 4 die Integration eines Regressionsmodells in den MetaTrader-Strategietester, die Interaktion zwischen Python und MQL5 und die Verwendung des ONNX-Formats zur Verbesserung der Implementierung in MetaTrader 5 untersucht.

Zusammenfassend hat dieser Artikel einen Überblick über die wichtigsten Schritte bei der Einführung von Modellen in Handelsstrategien gegeben, wobei die Bedeutung der richtigen Modellauswahl, der Datenaufbereitung, des Trainings und der Bewertung sowie der effektiven Integration in die Handelsumgebung hervorgehoben wurde. Diese Schritte bilden die Grundlage für den Aufbau robuster, datengesteuerter Handelssysteme.
Der obige Code ist im Git repository zur weiteren Verwendung verfügbar.

Übersetzt aus dem Portugiesischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/pt/articles/12471

Entwicklung eines Replay System (Teil 29): Expert Advisor Projekt — Die Klasse C_Mouse (II) Entwicklung eines Replay System (Teil 29): Expert Advisor Projekt — Die Klasse C_Mouse (II)
Nachdem wir die Klasse C_Mouse verbessert haben, können wir uns auf die Erstellung einer Klasse konzentrieren, die einen völlig neuen Rahmen für unsere Analyse schaffen soll. Wir werden weder Vererbung noch Polymorphismus verwenden, um diese neue Klasse zu erstellen. Stattdessen werden wir die Preislinie ändern, oder besser gesagt, neue Objekte hinzufügen. Genau das werden wir in diesem Artikel tun. In der nächsten Ausgabe werden wir uns ansehen, wie man die Analyse ändern kann. All dies geschieht, ohne den Code der Klasse C_Mouse zu ändern. Nun, eigentlich wäre es einfacher, dies durch Vererbung oder Polymorphismus zu erreichen. Es gibt jedoch auch andere Methoden, um das gleiche Ergebnis zu erzielen.
Erstellen von Multi-Symbol- und Multi-Perioden-Indikatoren Erstellen von Multi-Symbol- und Multi-Perioden-Indikatoren
In diesem Artikel werden wir uns mit den Grundsätzen der Erstellung von Multi-Symbol- und Multi-Perioden-Indikatoren befassen. Wir werden auch sehen, wie man auf die Daten solcher Indikatoren von Expert Advisors und anderen Indikatoren zugreifen kann. Wir werden die Hauptmerkmale der Verwendung von Multi-Indikatoren in Expert Advisors und Indikatoren besprechen und sehen, wie man sie durch nutzerdefinierte Indikatorpuffer darstellen kann.
Entwicklung eines Replay System (Teil 30): Expert Advisor Projekt — Die Klasse C_Mouse (IV) Entwicklung eines Replay System (Teil 30): Expert Advisor Projekt — Die Klasse C_Mouse (IV)
Heute werden wir eine Technik lernen, die uns in verschiedenen Phasen unseres Berufslebens als Programmierer sehr helfen kann. Oft ist es nicht die Plattform selbst, die begrenzt ist, sondern das Wissen der Person, die über die Grenzen spricht. In diesem Artikel erfahren Sie, dass Sie mit gesundem Menschenverstand und Kreativität die MetaTrader 5-Plattform viel interessanter und vielseitiger gestalten können, ohne auf verrückte Programme oder ähnliches zurückgreifen zu müssen, und einfachen, aber sicheren und zuverlässigen Code erstellen können. Wir werden unsere Kreativität nutzen, um bestehenden Code zu ändern, ohne eine einzige Zeile des Quellcodes zu löschen oder hinzuzufügen.
Entwicklung eines Replay System (Teil 28): Expert Advisor Projekt — Die Klasse C_Mouse (II) Entwicklung eines Replay System (Teil 28): Expert Advisor Projekt — Die Klasse C_Mouse (II)
Als man begann, die ersten rechenfähigen Systeme zu entwickeln, war für alles die Mitwirkung von Ingenieuren erforderlich, die das Projekt sehr gut kennen mussten. Wir sprechen von den Anfängen der Computertechnologie, einer Zeit, in der es noch nicht einmal Terminals zum Programmieren gab. Im Laufe der Entwicklung, als immer mehr Menschen daran interessiert waren, etwas zu erschaffen, entstanden neue Ideen und Wege der Programmierung, die das frühere Wechseln der Steckverbindungen ersetzten. Zu diesem Zeitpunkt erschienen die ersten Terminals.