
Integration von MQL5 in Datenverarbeitungspakete (Teil 1): Fortgeschrittene Datenanalyse und statistische Verarbeitung
Einführung
Die Finanzmärkte generieren riesige Datenmengen, deren Analyse für den alleinigen Zweck der technischen Analyse schwierig sein kann. Die technische Analyse allein, die manuell durchgeführt wird, ermöglicht es den Händlern nicht, Muster, Trends und Anomalien in den Daten zu analysieren und zu interpretieren. Mit fortschrittlichen Datenanalysepaketen wie Jupyter Lab können Händler anspruchsvolle statistische Analysen, maschinelles Lernen und Datenvisualisierung durchführen. Dies hilft bei der Identifizierung profitabler Handelsmöglichkeiten, dem Verständnis des Marktverhaltens, saisonalen Tendenzen und der Vorhersage zukünftiger Kursbewegungen.
Sammeln Sie historische Daten
Um zu beginnen, benötigen wir historische Daten aus dem MetaTrader 5, die im .csv-Format gespeichert sind. Starten Sie also einfach Ihre MetaTrader-Plattform und navigieren Sie oben in Ihrem MetaTrader 5-Fenster/Panel zu > Extras und dann > Optionen und Sie werden zu den Optionen von Diagramme gelangen. Sie müssen dann die Anzahl der Balken im Diagramm auswählen, die Sie herunterladen möchten. Am besten wählen Sie die Option „Unlimited“, da wir mit dem Datum arbeiten und nicht wissen, wie viele Balken in einem bestimmten Zeitraum vorhanden sind.
Danach müssen Sie nun die eigentlichen Daten herunterladen. Dazu müssen Sie zu > Ansicht und dann zu > Symbole navigieren. Auf der Registerkarte Spezifikation navigieren Sie einfach zu > Balken oder Ticks, je nachdem, welche Art von Daten Sie herunterladen möchten. Fahren Sie fort und geben Sie das Anfangs- und Enddatum der historischen Daten ein, die Sie herunterladen möchten. Klicken Sie anschließend auf die Schaltfläche „Anfragen“, um die Daten herunterzuladen und im .csv-Format zu speichern.
Nach all diesen Schritten haben Sie erfolgreich historische Daten von Ihrer MetaTrader-Handelsplattform heruntergeladen. Nun müssen Sie die Jupyter-Lab-Umgebung für die Analyse herunterladen und einrichten. Um Jupyter Lab herunterzuladen und einzurichten, können Sie die offizielle Website besuchen und den einfachen Schritten zum Herunterladen folgen. Je nach Art des Betriebssystems, das Sie verwenden, haben Sie verschiedene Möglichkeiten, ob Sie pip, conda oder brew für die Installation verwenden.
MetaTrader 5 Historische Daten auf Jupyter Lab laden
Um Ihre MetaTrader 5 historischen Daten erfolgreich in Jupyter Lab zu laden, müssen Sie den Ordner kennen, den Sie zum Herunterladen der Daten ausgewählt hatten, und dann in Jupyter Lab einfach zu diesem Ordner navigieren.um loszulegen, müssen Sie die Daten laden und die Spaltennamen überprüfen. Wir müssen die Spaltennamen überprüfen, damit wir die Spalten richtig behandeln und Fehler vermeiden, die bei der Verwendung eines falschen Spaltennamens auftreten könnten.
Vorverarbeitung
Bevor wir mit der Datenanalyse beginnen, müssen wir die Daten vorverarbeiten.
1. Parsing von Datum und Uhrzeit: Konvertiert die Datumsspalte in das Datum-Zeit-Format.
2. Behandlung fehlender Werte: Behandeln Sie alle fehlenden Werte.
3. Merkmalsmanagement: Erstellen Sie bei Bedarf neue Merkmale.
python code:
import pandas as pd # Load historical data file_path = '/home/int_junkie/Documents/ML/XAUUSD.m_H1_historical.csv' data = pd.read_csv(file_path) # Display the first few rows and column names print(data.head()) print(data.columns)
Ausgabe:
Anhand der Ausgabe können wir sehen, dass es einige Sonderzeichen „<>“ innerhalb der Spalten und das Vorhandensein von „\t“ gibt, was darauf hindeutet, dass die Datei durch Tabulatoren getrennt ist. Wir können nun fortfahren, historische Daten mit dem richtigen Spaltennamen zu laden.
Im folgenden Code werden wir Folgendes tun:
1. Bibliotheken importieren:
- Pandas ist eine leistungsstarke Bibliothek zur Datenverarbeitung in Python.
- Die Technical Analysis Library (TA lib) wird für die technische Analyse von Finanzmarktdaten verwendet.
2. Laden der historischen Daten:
- Der Dateipfad wird verwendet, um den Speicherort der CSV-Datei mit den historischen Daten anzugeben.
- Pd.read liest die CSV-Datei in einen Pandas Data-Frame ein. Das Trennzeichen „\t“ zeigt an, dass die Datei durch Tabulatoren getrennt ist.
3. Anzeige der Daten:
- Data.head druckt die ersten Zeilen des Datenrahmens, um den Inhalt zu überprüfen.
- Data.columns gibt die Spaltennamen aus, um die Struktur des Datenrahmens zu überprüfen
4. Sortierung der Daten nach Datum:
- Date.sort, sortiert den Datenrahmen anhand der Spalte „<DATE>“. Dadurch wird sichergestellt, dass die Daten in chronologischer Reihenfolge vorliegen.
5. Berechnung des RSI:
- TA.RSI berechnet den Relative Strength Index (RSI) anhand der Kursspalte „<CLOSE>“.
- Zeitspanne, gibt einen 14-Perioden-RSI an.
- Die berechneten Werte werden in einer neuen Spalte namens „RSI“ im Datenrahmen gespeichert.
6. Anzeige der aktualisierten Daten:
- Data.head, druckt die ersten Zeilen des aktualisierten Datenrahmens aus, um die RSI-Berechnung zu überprüfen.
import pandas as pd import talib as ta # Load historical data file_path = '/home/int_junkie/Documents/ML/XAUUSD.m_H1_historical.csv' data = pd.read_csv(file_path, delimiter='\t') # Display the first few rows and column names to verify print(data.head()) print(data.columns) # Ensure data is sorted by the correct date column data.sort_values('<DATE>', inplace=True) # Calculate RSI using the '<CLOSE>' price column data['RSI'] = ta.RSI(data['<CLOSE>'], timeperiod=14) # Display the first few rows to verify print(data.head())
Ausgabe:
Anhand der Ausgabe können wir sehen, dass wir NAN-Werte in der RSI-Spalte haben, wir müssen die NAN-Werte richtig behandeln. Die RSI-Funktion erfordert eine Mindestanzahl von Datenpunkten zur Berechnung des Indikators. Für anfängliche Zeiträume kann sie NAN-Werte liefern. Um die NAN-Werte korrekt zu behandeln, müssen wir den Datentyp der Spalte „<CLOSE>“ kennen. Stellen Sie sicher, dass der Datenrahmen und der Spaltenzugriff korrekt sind. Der folgende Python-Code zeigt, wie die NAN-Werte zu bearbeiten sind.
import pandas as pd import talib as ta # Load the historical data file_path = '/home/int_junkie/Documents/ML/XAUUSD.m_H1_historical.csv' data = pd.read_csv(file_path, delimiter='\t')data['<CLOSE>'] = data['<CLOSE>'].astype(float) # Verify the column names print(data.columns) # Convert the column to the correct data type if necessary data['<CLOSE>'] = data['<CLOSE>'].astype(float) # Calculate the RSI data['RSI'] = ta.RSI(data['<CLOSE>'], timeperiod=14) # Display the RSI values print(data[['<CLOSE>', 'RSI']].tail(20))
Ausgabe:
Wir können sehen, dass wir die NAN-Werte korrekt bearbeitet haben. Wenn Sie für die ersten Perioden einen NAN-Wert sehen (was aufgrund des Rückblickszeitraums zu erwarten ist), können Sie sie wie folgt behandeln:
data['RSI'] = ta.RSI(data['<CLOSE>'], timeperiod=14) data['RSI'] = data['RSI'].fillna(0) # or use any other method to handle NaN values
Explorative Datenanalyse
Das Hauptziel der EDA besteht darin, die zugrunde liegende Struktur der Daten zu verstehen, indem die wichtigsten Merkmale der Daten zusammengefasst werden. Bei der Durchführung von EDA entdecken wir Muster und erkennen Trends und Beziehungen in den Daten. In der EDA erkennen wir auch Anomalien und Ausreißer oder ungewöhnliche Beobachtungen, die eine weitere Untersuchung erfordern könnten. Wir überprüfen auch Annahmen über die Daten, die sich auf die spätere Analyse auswirken könnten. Anschließend führen wir eine Datenbereinigung durch, indem wir nach fehlenden Werten, Fehlern und Unstimmigkeiten in den Daten suchen, die behoben werden müssen.
Wir verwenden die folgenden python-Skripte zur Durchführung der EDA:
import seaborn as sns import matplotlib.pyplot as plt import warnings warnings.filterwarnings("ignore") for i in data.select_dtypes(include="number").columns: sns.histplot(data=data, x=i) plt.show()
Im obigen Code werden nach dem Importieren aller erforderlichen Bibliotheken zunächst die Warnungen ignoriert, um eine saubere Ausgabe zu erhalten. Anschließend werden die numerischen Spalten durchlaufen, und „data.select_dtypes(include="number")“ liefert den Datenrahmen, der nur die numerischen Spalten enthält, und „columns“ liefert die Namen dieser Spalten. Anschließend wird das Histogramm aus den Daten erstellt. Hier sind die Histogramme, die mit dem obigen Code erstellt wurden.
Nach der statistischen Verarbeitung können wir das Modell anhand der gesammelten Daten trainieren. Ziel ist es, aus den von uns gesammelten historischen Daten Vorhersagen zu treffen. Wir werden Vorhersagen nur mit dem RSI-Indikator treffen. Bevor wir das tun, müssen wir wissen, welche Art von Beziehung zwischen den Daten selbst besteht, und das tun wir, indem wir die Korrelationsmatrix durchführen. Wir sollten in der Lage sein zu interpretieren, ob die bestehende Beziehung positiv, negativ oder gar nicht korreliert ist.
- Positive Korrelation: Werte nahe bei 1 weisen auf eine starke positive Korrelation zwischen zwei Variablen hin. Wenn zum Beispiel die Korrelation zwischen „Open“ und „Close“ nahe bei 1 liegt, bedeutet dies, dass sie sich in die gleiche Richtung bewegen.
- Negative Korrelation: Werte in der Nähe von -1 deuten auf eine starke negative Korrelation hin. Wenn zum Beispiel die Korrelation zwischen „Volumen“ und „Preis“ nahe bei -1 liegt, bedeutet dies, dass der Preis bei steigendem Volumen tendenziell sinkt.
- Keine Korrelation: Werte nahe bei 0 bedeuten, dass keine Korrelation zwischen den Variablen besteht.
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import r2_score, mean_squared_error import talib as ta # Technical Analysis library # Load the data file_path = '/home/int_junkie/Documents/ML/XAUUSD.m_H1_historical.csv' data = pd.read_csv(file_path, delimiter='\t') # Exploratory Data Analysis (EDA) print(data.info()) print(data.describe()) # Visualize the closing price plt.figure(figsize=(12, 6)) plt.plot(data['<CLOSE>']) plt.title('XAUUSD Closing Price') plt.xlabel('<DATE>') plt.ylabel('Price') plt.show() # Feature Engineering data['RSI'] = ta.RSI(data['<CLOSE>'], timeperiod=14) # Drop rows with missing values data.dropna(inplace=True) # Define target variable data['Target'] = data['<CLOSE>'].shift(-1) data.dropna(inplace=True) # Split the data X = data[['RSI']] # Only use RSI as the feature y = data['Target'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False) # Model Development model = RandomForestRegressor(n_estimators=100, random_state=42) model.fit(X_train, y_train) # Predictions y_pred = model.predict(X_test) # Evaluate the model mse = mean_squared_error(y_test, y_pred) print(f'Mean Squared Error: {mse}') # Visualize the predictions plt.figure(figsize=(12, 6)) plt.plot(y_test.index, y_test, label='Actual Values') plt.plot(y_test.index, y_pred, label='Predicted Values') plt.xlabel('Samples') plt.ylabel('TARGET_CLOSE') plt.title('Actual vs Predicted Values') plt.legend() plt.show()
Dies ist die Ausgabe, die wir beim Training des Modells erhalten:
Aus der Datenanalyse geht jedoch hervor, dass die vorhergesagten Werte nicht mit den tatsächlichen Werten übereinstimmen. Dies deutet darauf hin, dass das Modell das zugrunde liegende Muster nicht richtig erfasst. Dazu könnten mehrere Faktoren beitragen.
1. Unzureichende Trainingsdaten: Wenn der Datensatz zu klein ist, verfügt das Modell möglicherweise nicht über genügend Informationen, um die volle Bedeutung zu erlernen.
2. Überanpassung: Es kann sein, dass sich das Modell die Lerndaten gemerkt hat, anstatt zu lernen, daraus zu verallgemeinern. Dies ist häufig der Fall, wenn das Modell zu komplex ist oder nicht richtig verallgemeinert wurde.
3. Unteranpassung: Das Modell kann zu einfach sein, um das zugrunde liegende Muster in den Daten zu erfassen. Das kann passieren, wenn das Modell nicht komplex genug ist oder wichtige Merkmale fehlen.
4. Merkmalsmanagement: Eine schlechte Auswahl von Merkmalen oder eine unzureichende Konstruktion kann dazu führen, dass das Modell nicht über genügend relevante Informationen verfügt, um Vorhersagen zu treffen.
Schritte zur Diagnose und Behebung des Problems:
1. Überprüfen Sie die Daten: Stellen Sie sicher, dass die Daten sauber, konsistent und ordnungsgemäß vorverarbeitet sind.
2. Bewerten Sie die Leistung des Modells: Verwenden Sie eine Matrix wie den mittleren quadratischen Fehler (MSE) und den mittleren absoluten Fehler (MAB).
3. Verbessern Sie die Merkmalsmanagement: Experimentieren Sie mit verschiedenen Merkmalen, einschließlich technischer Indikatoren, verzögerter Werte und anderer relevanter Finanzkennzahlen.
4. Abstimmung der Hyper-Parameter: Verwenden Sie Techniken wie die Gittersuche oder die Zufallssuche, um optimale Hyperparameter für Ihr Modell zu finden.
Alles zusammen auf MQL5
Nachdem wir das Modell gespeichert haben, müssen wir ein Python-Skript für die Vorhersagen erstellen. Dieses Skript lädt das Modell und macht Vorhersagen.
import joblib import sys import os
- Joblib: Wird zum Laden des serialisierten maschinellen Lernmodells verwendet.
- Sys: Das ist die Abkürzung für „system“ und ermöglicht den Zugriff auf Befehlszeilenargumente.
- OS: Die Abkürzung steht für „Operating System“ und wird verwendet, um das Vorhandensein von Dateien zu überprüfen und Dateioperationen durchzuführen.
model_path = sys.argv[/home/int_junkie/Documents/ML/random_forest_model.pkl] features_path = sys.argv[/home/int_junkie/Documents/ML/features.txt]
- Sys.argv[1]: Das erste Befehlszeilenargument ist der Pfad zur Modelldatei.
- Sys.argv[2]: Das zweite Befehlszeilenargument ist der Pfad zur Merkmalsdatei.
print(f"Model path: {model_path}") print(f"Features path: {features_path}")
Drucken von Debugging-Informationen. Gibt die Pfade der Modell- und Feature-Dateien zu Debugging-Zwecken aus.
if not os.path.exists(model_path): print(f"Error: Model file not found at {model_path}") sys.exit(1) if not os.path.exists(features_path): print(f"Error: Features file not found at {features_path}") sys.exit(1)
- Prüft, ob die Modelldatei und die Merkmalsdatei vorhanden sind.
- Wenn eine der beiden Dateien nicht existiert, wird eine Fehlermeldung ausgegeben und das Skript mit einem Statuscode von 1 beendet.
model = joblib.load(model_path)
- Lädt das trainierte Modell für maschinelles Lernen aus dem angegebenen „Modellpfad“.
with open(features_path, 'r') as f: features = [float(line.strip()) for line in f]
- Öffnet die Feature-Datei zum Lesen.
- Liest jede Zeile, entfernt alle führenden/nachfolgenden Leerzeichen, konvertiert die Datei in eine Fließkommazahl und speichert sie in der Liste „features“.
prediction = model.predict([features])[0]
- Verwendet das geladene Modell, um eine Vorhersage auf der Grundlage der geladenen Merkmale zu treffen.
- Model.predict: Gibt eine Liste von Vorhersagen zurück (in diesem Fall eine einzelne Vorhersage), und „[0]“ extrahiert die erste Vorhersage.
print(prediction)
- Druckt die Vorhersage in die Standardausgabe. Diese Ausgabe kann von einem anderen Skript oder Programm, wie z. B. MQL5, erfasst werden, um Handelsentscheidungen zu treffen.
MQL5
Laden Sie das Modell in OnInit().
int OnInit(){ // Load the model and feature names string modelPath = "/home/int_junkie/Documents/ML/random_forest_model.pkl"; string featurePath = "/home/int_junkie/Documents/ML/features.txt"; // Your code to load the model (use appropriate library for pkl files) // Initialize the features double features[]; int fileHandle = FileOpen(featurePath, FILE_READ | FILE_TXT); if (fileHandle != INVALID_HANDLE) { string line; while(!FileIsEnding(fileHandle)) { line = FileReadString(fileHandle); ArrayResize(features, ArraySize(features) + 1); features[ArraySize(features) - 1] = StringToDouble(line); } FileClose(fileHandle); } return(INIT_SUCCEEDED); }
Lesen der Vorhersagen aus der Python-Datei in OnTick().
void OnTick(){ // Declare static variables to retain values across function calls static bool isNewBar = false; static int prevBars = 0; // Get the current number of bars int newbar = iBars(_Symbol, _Period); // Check if the number of bars has changed if (prevBars == newbar) { // No new bar isNewBar = false; } else { // New bar detected isNewBar = true; // Update previous bars count to current prevBars = newbar; } // Update the features based on current data double features[]; ArrayResize(features, 1); features[0] = iClose(Symbol(), 0, 0); // Write the features to a file int fileHandle = FileOpen("/home/int_junkie/Documents/ML/features.txt", FILE_WRITE | FILE_TXT); if (fileHandle != INVALID_HANDLE) { for (int i = 0; i < ArraySize(features); i++) { FileWrite(fileHandle, DoubleToString(features[i])); } FileClose(fileHandle); } else { Print("Error: Cannot open features file for writing"); return; } // Call the Python script to get the prediction string command = "python /home/int_junkie/Documents/ML/predict.py /home/int_junkie/Documents/ML/random_forest_model.pkl /home/int_junkie/Documents/ML/features.txt"; int result = ShellExecuteA(command); if(result != 0) { Print("Error: ShellExecuteA failed with code ", result); return; } // Read the prediction from a file Sleep(1000); // Wait for the Python script to complete fileHandle = FileOpen("/home/int_junkie/Documents/ML/prediction.txt", FILE_READ | FILE_TXT); if (fileHandle != INVALID_HANDLE) { string prediction = FileReadString(fileHandle); FileClose(fileHandle); double pred_value = StringToDouble(prediction); // Generate trading signals based on predictions double some_threshold = 0.0; // Define your threshold if (pred_value > some_threshold) { // Buy signal double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),Digits()); double sl = Ask - stopLoss * _Point; double tp = Ask + takeProfit * _Point; trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, lotsize, Ask, sl, tp, "ML"); } else if (pred_value < some_threshold) { // Sell signal double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),Digits()); double sl = Bid + stopLoss * _Point; double tp = Bid - takeProfit * _Point; trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, lotsize, Bid, sl, tp, "ML"); } } else { Print("Error: Cannot open prediction file for reading"); } }
Beim OnTick bereitet die Variable „command“ einen String-Befehl vor, um ein Python-Skript mit einer Feature-Datei und einer Modelldatei als Argumente auszuführen. ShellExecuteA (Befehl) führt das Python-Skript mit ShellExecuteA aus. „Sleep (1000)“, Wartet 1 Sekunde lang, bis das Python-Skript vollständig ausgeführt wurde. Danach öffnen wir die Vorhersagedatei zum Lesen. Anschließend wird geprüft, ob die Vorhersagedatei erfolgreich geöffnet wurde. Wenn ja, lesen wir die Vorhersage. Wenn nein, wird ein Fehler ausgegeben. Die Schwellenwertvariable wird verwendet, um Handelsentscheidungen zu treffen. Wenn er größer ist als der vorhergesagte Wert, wird ein Kaufsignal generiert. Liegt er unter dem vorhergesagten Wert, wird ein Verkaufssignal erzeugt.
Schlussfolgerung
Zusammenfassend haben wir Daten von der Handelsplattform MetaTrader 5 gesammelt. Dieselben Daten, die wir gesammelt haben, verwenden wir dann in Jupyter Lab, um Datenanalysen und statistische Verarbeitung durchzuführen. Nachdem wir die Analyse in Jupyter Lab durchgeführt haben, verwenden wir das Modell und integrieren es in MQL5, um Handelsentscheidungen auf der Grundlage der identifizierten Muster zu treffen. Die Integration von MQL5 mit Jupyter Lab löst das Problem der begrenzten analytischen, statistischen und Visualisierungsmöglichkeiten in MQL5. Der Prozess fördert die Strategieentwicklung, verbessert die Effizienz der Datenverarbeitung und bietet eine kollaborative, flexible und leistungsstarke Umgebung für die fortgeschrittene Datenanalyse und statistische Verarbeitung im Handel.
Zusammenfassend lässt sich sagen, dass wir durch die Integration von MQL5 mit Jupyter Lab eine fortgeschrittene Datenanalyse und statistische Verarbeitung durchführen können. Mit diesen Fähigkeiten können Sie jede Art von Handelsstrategie entwickeln und Handelsstrategien mit fortschrittlichen Techniken optimieren. Damit verschafft sie einen erheblichen Wettbewerbsvorteil im dynamischen und datenintensiven Finanzhandel.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15155





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