English Русский 中文 Español 日本語 Português
preview
Entwicklung eines Handelsroboters in Python (Teil 3): Implementierung eines modellbasierten Handelsalgorithmus

Entwicklung eines Handelsroboters in Python (Teil 3): Implementierung eines modellbasierten Handelsalgorithmus

MetaTrader 5Handelssysteme | 19 Dezember 2024, 09:50
412 0
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Im ersten Artikel dieser Reihe haben wir den Datensatz geladen, Kennzeichen platziert, den Datensatz angereichert und auch die Kennzeichnung des Datensatzes durchgeführt. Der zweite Artikel befasste sich mit der Erstellung und dem Training des Modells sowie der Implementierung von Kreuzvalidierung und Bagging. 

Nun, da unser Modell trainiert und getestet ist, ist es an der Zeit, mit dem echten Handel unter Verwendung der MetaTrader 5-Bibliothek für Python zu beginnen. Diese leistungsstarke Bibliothek ermöglicht es uns, den Handel direkt über Python zu automatisieren, indem wir die von der MetaTrader 5-Plattform bereitgestellten Funktionen und Klassen nutzen.


Implementierung eines modellbasierten Handelsalgorithmus

Um einen Handelsalgorithmus auf der Grundlage unseres Modells zu implementieren, werden wir den folgenden Ansatz verwenden. Der grundlegende Algorithmus besteht darin, Geschäfte mit voreingestellten Stop-Loss zu eröffnen und Gewinne mitzunehmen, die mit den vom Modell generierten Kennzeichen übereinstimmen. Wenn das Modell einen Kursanstieg vorhersagt, eröffnen wir eine Kaufposition mit festgelegten Stop-Loss- und Take-Profit. Wenn das Modell einen Kursrückgang vorhersagt, eröffnen wir eine Verkaufsposition mit ähnlichen Parametern für Stop-Loss und Take-Profit.

Die MetaTrader 5-Bibliothek für Python bietet die notwendigen Werkzeuge für die Verwaltung der Eröffnung und Schließung von Handelsgeschäfte sowie für die Festlegung von Stop-Loss- und Take-Profit-Levels. Dies ermöglicht uns, den Handel auf der Grundlage der Modellprognosen vollständig zu automatisieren.

Anhand der in den vorangegangenen Analyse- und Schulungsphasen gewonnenen Daten können wir Signale zum Öffnen und Schließen von Positionen auf der MetaTrader 5-Plattform in Echtzeit übermitteln und so die Kontinuität und Genauigkeit unseres Handelsalgorithmus gewährleisten.

Durch die Integration unseres trainierten Modells in die MetaTrader 5-Bibliothek für Python können wir einen effizienten und automatisierten Handelsalgorithmus erstellen, der auf der Grundlage der Modellvorhersagen handelt und dabei Risiken mit voreingestellten Stop-Loss verwaltet und Gewinne mit Take-Profits schützt.


Einrichten der Umgebung, des Handelsterminals und Ausführen des Algorithmus

Zunächst müssen wir die Umgebung und das MetaTrader 5-Terminal einrichten. Dazu führen wir folgende Schritte aus:

Installiere die Python-Bibliotheken mit dem Befehl pip:

pip install numpy pandas MetaTrader5 scikit-learn xgboost

Gib den Pfad zur ausführbaren Datei des Terminals in den Links zum Terminal an:

terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"


Implementieren eines Online-Handels

Um den Online-Handel zu implementieren, fügen wir die Funktion online_trading hinzu, die den Handel entsprechend unserer Modellprognose eröffnet.

Die Funktion online_trading benötigt die folgenden Argumente:

  • symbol - gehandeltes Symbol
  • features - Liste der Merkmale, die für die Prognosen verwendet werden sollen
  • model - trainiertes Modell für die Erstellung von Prognosen

Innerhalb der Funktion online_trading stellen wir zunächst eine Verbindung zum MetaTrader 5-Terminal her, indem wir den in terminal_path angegebenen Pfad verwenden. Dann erhalten wir die aktuellen Symbolpreise mit der Funktion mt5.symbol_info_tick(symbol).

Als Nächstes verwenden wir unser Modell, um das Signal auf der Grundlage der übergebenen Merkmale vorherzusagen. Ist die Prognose positiv (über 0,5), eröffnen wir eine Kaufposition, ist die Prognose negativ (unter 0,5), eröffnen wir eine Verkaufsposition.

Wir legen auch Stop-Loss und Take-Profit für jedes Handelsgeschäft fest, um das Risiko zu minimieren.

Wenn wir bereits die maximale Anzahl offener Handelsgeschäfte erreicht haben (festgelegt in der Konstante MAX_OPEN_TRADES), eröffnen wir keine neuen und warten, bis eines der offenen Handelsgeschäfte geschlossen wird.

Wenn die Vorhersage uns nicht erlaubt, ein neues Handelsgeschäft zu eröffnen, warten wir ebenfalls, bis ein neues Signal erscheint.

Am Ende der Funktion geben wir das Ergebnis der Handelsausführung zurück, wenn der Handel erfolgreich platziert wurde, oder None, wenn der Handel nicht platziert wurde.

def online_trading(symbol, features, model):
    terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"

    if not mt5.initialize(path=terminal_path):
        print("Error: Failed to connect to MetaTrader 5 terminal")
        return

    open_trades = 0
    e = None
    attempts = 30000

    while True:
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is not None:
            break
        else:
            print("Error: Instrument not found. Attempt {} of {}".format(_ + 1, attempts))
            time.sleep(5)

    while True:
        price_bid = mt5.symbol_info_tick(symbol).bid
        price_ask = mt5.symbol_info_tick(symbol).ask

        signal = model.predict(features)

        positions_total = mt5.positions_total()

        for _ in range(attempts):
            if positions_total < MAX_OPEN_TRADES and signal[-1] > 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": 0.3,
                    "type": mt5.ORDER_TYPE_BUY,
                    "price": price_ask,
                    "sl": price_ask - 150 * symbol_info.point,
                    "tp": price_ask + 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            elif positions_total < MAX_OPEN_TRADES and signal[-1] < 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": 0.3,
                    "type": mt5.ORDER_TYPE_SELL,
                    "price": price_bid,
                    "sl": price_bid + 150 * symbol_info.point,
                    "tp": price_bid - 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            else:
                print("No signal to open a position")
                return None

            result = mt5.order_send(request)

            if result.retcode == mt5.TRADE_RETCODE_DONE:
                if signal[-1] < 0.5:
                    print("Buy position opened")
                    open_trades += 1
                elif signal[-1] > 0.5:
                    print("Sell position opened")
                    open_trades += 1
                return result.order
            else:
                print("Error: Trade request not executed, retcode={}. Attempt {}/{}".format(result.retcode, _ + 1, attempts))
                time.sleep(3)

        time.sleep(4000)

def process_symbol(symbol):
    try:
        # Retrieve data for the specified symbol
        raw_data = retrieve_data(symbol)
        if raw_data is None:
            print("No data found for symbol {}".format(symbol))
            return None

        # Augment data
        augmented_data = augment_data(raw_data)

        # Markup data
        marked_data = markup_data(augmented_data.copy(), 'close', 'label')

        # Label data
        labeled_data = label_data(marked_data, symbol)

        # Generate new features
        labeled_data_generate = generate_new_features(labeled_data, num_features=100, random_seed=1)

        # Cluster features by GMM
        labeled_data_clustered = cluster_features_by_gmm(labeled_data_generate, n_components=4)

        # Feature engineering
        labeled_data_engineered = feature_engineering(labeled_data_clustered, n_features_to_select=10)

        # Train XGBoost classifier
        train_data = labeled_data_engineered[labeled_data_engineered.index <= FORWARD]


Einführung eines Online-Handelsalgorithmus

Um den Online-Handelsalgorithmus zu starten, rufen wir die Funktion process_symbol auf und übergeben ihr das gehandelte Symbol.

Innerhalb der Funktion process_symbol rufen wir die Funktion online_trading auf, übergeben ihr die erforderlichen Argumente und starten eine Schleife, die so lange läuft, bis sie unterbrochen wird.

Am Ende der Schleife machen wir eine Pause von 6 Sekunden, um das MetaTrader 5 Terminal nicht zu überlasten.

Wenn während der Ausführung des Algorithmus ein Fehler auftritt, wird eine Fehlermeldung ausgegeben und die Ausführung abgebrochen.


Intelligentes Management für das Risiko und den Drawdown

Das Risikomanagement ist der Eckpfeiler einer erfolgreichen Handelsstrategie. Eines der Hauptrisiken, mit denen Händler konfrontiert sind, ist das Risiko eines Drawdowns, wenn die Preise von Vermögenswerten unter ein bestimmtes Niveau fallen. Um dieses Risiko zu minimieren, ist ein wirksames Risikomanagementsystem erforderlich, das in der Lage ist, sich an veränderte Marktbedingungen anzupassen.

Wir werden ein System entwickeln, das automatisch das Handelsvolumen reduziert, wenn der Kontostand sinkt, indem wir die Tools der MetaTrader 5-Bibliothek für Python verwenden.

Die Grundregeln des Systems:

  1. Täglicher Abruf des aktuellen Kontostands - das System ruft täglich den aktuellen Kontostand ab, um die Veränderungen zu analysieren.

  2. Reduzierung des Handelsvolumens während eines Drawdowns - wenn der Saldo an einem Tag um mehr als 2% gefallen ist, reduziert das System automatisch das Volumen der eröffneten Geschäfte um 10%. Dies geschieht in Schritten von 0,01 Lots, um das Risiko schrittweise zu verringern.

  3. Zusätzliche Volumenreduzierung bei weiterem Rückgang des Saldos - wenn der Saldo weiter sinkt, wird das Volumen der Geschäfte jeden Tag um weitere 10 % und um 0,01 Lots reduziert, was einen weiteren Kapitalschutz gewährleistet.

  4. Wiederherstellung des ursprünglichen Volumens nach Wiederherstellung des Saldos - wenn der aktuelle Kontostand den vorherigen Höchststand übersteigt, setzt das System das Handelsvolumen automatisch auf den ursprünglichen Wert zurück. Dies trägt dazu bei, dass nach einem vorübergehenden Rückgang des Handelsvolumens aufgrund eines Drawdowns die volle Handelsaktivität wiederhergestellt wird.

Der Funktion online_trading wurden neue Variablen hinzugefügt: account_balance - zur Speicherung des aktuellen Kontostands, peak_balance - zur Speicherung des vorherigen Höchststands und daily_drop - zur Erfassung des täglichen Drawdowns. Diese Variablen werden zur Umsetzung der Risikomanagementlogik verwendet.

Beispiel-Code:

def online_trading(symbol, features, model):
    terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"

    if not mt5.initialize(path=terminal_path):
        print("Error: Failed to connect to MetaTrader 5 terminal")
        return

    open_trades = 0
    e = None
    attempts = 30000

    # Get the current account balance
    account_info = mt5.account_info()
    account_balance = account_info.balance

    # Set the initial volume for opening trades
    volume = 0.3

    # Set the initial peak balance
    peak_balance = account_balance

    while True:
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is not None:
            break
        else:
            print("Error: Instrument not found. Attempt {} of {}".format(_ + 1, attempts))
            time.sleep(5)

    while True:
        price_bid = mt5.symbol_info_tick(symbol).bid
        price_ask = mt5.symbol_info_tick(symbol).ask

        signal = model.predict(features)

        positions_total = mt5.positions_total()

        # Calculate the daily drop in account balance
        account_info = mt5.account_info()
        current_balance = account_info.balance
        daily_drop = (account_balance - current_balance) / account_balance

        # Reduce the volume for opening trades by 10% with a step of 0.01 lot for each day of daily drop
        if daily_drop > 0.02:
            volume -= 0.01
            volume = max(volume, 0.01)
        elif current_balance > peak_balance:
            volume = 0.3
            peak_balance = current_balance

        for _ in range(attempts):
            if positions_total < MAX_OPEN_TRADES and signal[-1] > 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_BUY,
                    "price": price_ask,
                    "sl": price_ask - 150 * symbol_info.point,
                    "tp": price_ask + 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            elif positions_total < MAX_OPEN_TRADES and signal[-1] < 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_SELL,
                    "price": price_bid,
                    "sl": price_bid + 150 * symbol_info.point,
                    "tp": price_bid - 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            else:
                print("No signal to open a position")
                return None

            result = mt5.order_send(request)

            if result.retcode == mt5.TRADE_RETCODE_DONE:
                if signal[-1] < 0.5:
                    print("Buy position opened")
                    open_trades += 1
                elif signal[-1] > 0.5:
                    print("Sell position opened")
                    open_trades += 1
                return result.order
            else:
                print("Error: Trade request not executed, retcode={}. Attempt {}/{}".format(result.retcode, _ + 1, attempts))
                time.sleep(3)

        time.sleep(4000)


Umsetzung der Losgrößenverwaltung nach dem Kelly-Kriterium

Die Verwaltung der Losgröße ist ein weiterer wichtiger Aspekt des Risikomanagements im Handel. Eine der beliebtesten Methoden zur Kontrolle der Losgröße ist das Kelly-Kriterium. Das Kelly-Kriterium ist eine mathematische Gleichung, mit deren Hilfe die optimale Einsatzgröße auf der Grundlage der Gewinnwahrscheinlichkeit und des Verhältnisses zwischen Gewinnen und Verlusten bestimmt werden kann.

Im Folgenden werden wir uns ansehen, wie wir das Kelly-Losgrößenmanagement in unser Risikomanagementsystem integrieren können. Wir verwenden den Abstand zwischen der Vorhersage des Modells und 0,5 als Gewinnwahrscheinlichkeit. Je näher die Vorhersage des Modells bei 0,5 liegt, desto geringer ist die Gewinnwahrscheinlichkeit und desto kleiner sollte der Einsatz sein.

So sieht die geänderte Funktion online_trading aus:

def online_trading(symbol, features, model):
    terminal_path = "C:/Program Files/RoboForex - MetaTrader 5/Arima/terminal64.exe"

    if not mt5.initialize(path=terminal_path):
        print("Error: Failed to connect to MetaTrader 5 terminal")
        return

    open_trades = 0
    e = None
    attempts = 30000

    # Get the current account balance
    account_info = mt5.account_info()
    account_balance = account_info.balance

    # Set the initial volume for opening trades
    volume = 0.1

    # Set the initial peak balance
    peak_balance = account_balance

    while True:
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is not None:
            break
        else:
            print("Error: Instrument not found. Attempt {} of {}".format(_ + 1, attempts))
            time.sleep(5)

    while True:
        price_bid = mt5.symbol_info_tick(symbol).bid
        price_ask = mt5.symbol_info_tick(symbol).ask

        signal = model.predict(features)

        positions_total = mt5.positions_total()

        # Calculate the daily drop in account balance
        account_info = mt5.account_info()
        current_balance = account_info.balance
        daily_drop = (account_balance - current_balance) / account_balance

        # Calculate the probability of winning based on the distance between the model's prediction and 0.5
        probability_of_winning = abs(signal[-1] - 0.5) * 2

        # Calculate the optimal volume for opening trades using the Kelly criterion
        optimal_volume = (probability_of_winning - (1 - probability_of_winning) / risk_reward_ratio) / risk_reward_ratio * account_balance / price_ask

        # Reduce the volume for opening trades by 10% with a step of 0.01 lot for each day of daily drop
        if daily_drop > 0.02:
            optimal_volume -= 0.01
            optimal_volume = max(optimal_volume, 0.01)
        elif current_balance > peak_balance:
            optimal_volume = (probability_of_winning - (1 - probability_of_winning) / risk_reward_ratio) / risk_reward_ratio * account_balance / price_ask
            peak_balance = current_balance

        # Set the volume for opening trades
        volume = optimal_volume

        for _ in range(attempts):
            if positions_total < MAX_OPEN_TRADES and signal[-1] > 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_BUY,
                    "price": price_ask,
                    "sl": price_ask - 150 * symbol_info.point,
                    "tp": price_ask + 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            elif positions_total < MAX_OPEN_TRADES and signal[-1] < 0.5:
                request = {
                    "action": mt5.TRADE_ACTION_DEAL,
                    "symbol": symbol,
                    "volume": volume,
                    "type": mt5.ORDER_TYPE_SELL,
                    "price": price_bid,
                    "sl": price_bid + 150 * symbol_info.point,
                    "tp": price_bid - 800 * symbol_info.point,
                    "deviation": 20,
                    "magic": 123456,
                    "comment": "Test deal",
                    "type_time": mt5.ORDER_TIME_GTC,
                    "type_filling": mt5.ORDER_FILLING_FOK,
                }
            else:
                print("No signal to open a position")
                return None

            result = mt5.order_send(request)

            if result.retcode == mt5.TRADE_RETCODE_DONE:
                if signal[-1] < 0.5:
                    print("Buy position opened")
                    open_trades += 1
                elif signal[-1] > 0.5:
                    print("Sell position opened")
                    open_trades += 1
                return result.order
            else:
                print("Error: Trade request not executed, retcode={}. Attempt {}/{}".format(result.retcode, _ + 1, attempts))
                time.sleep(3)

        time.sleep(4000)

In dieser Funktion habe ich die Variablen probability_of_winning und optimal_volume hinzugefügt. probability_of_winning speichert die Gewinnwahrscheinlichkeit, die als Abstand zwischen der Modellprognose und 0,5 multipliziert mit 2 berechnet wird. optimal_volume enthält die optimale Wettgröße, die anhand des Kelly-Kriteriums berechnet wird.

Im Block „if daily_drop > 0.05:“ verringere ich optimal_volume um 10% in Schritten von 0.01 lot. Außerdem habe ich die Bedingung „elif current_balance > peak_balance:“ hinzugefügt, die prüft, ob der aktuelle Kontostand den vorherigen Höchststand überschritten hat. Wenn ja, berechne ich optimal_volume für den aktuellen Saldo und das Gewinn/Verlust-Verhältnis neu, während peak_balance aktualisiert wird.

Dieses System zur Verwaltung der Losgröße von Kelly ermöglicht es mir, die Größe meiner Einsätze automatisch auf der Grundlage der Gewinnwahrscheinlichkeit und des Gewinn/Verlust-Verhältnisses zu optimieren. Auf diese Weise kann ich die Gewinne maximieren und das Risiko eines Drawdowns minimieren.


Implementierung von Mehrwährungsbetrieb und paralleler Datenverarbeitung

Der Multiwährungsbetrieb ermöglicht es dem Algorithmus, mehrere Währungspaare gleichzeitig zu handeln und so die Risiken zu diversifizieren. Sie wird über die Liste „Symbole“ mit Paaren implementiert.

Paralleles Rechnen beschleunigt die Arbeit durch die gleichzeitige Ausführung von Aufgaben. Wir verwenden die „threading“-Bibliothek - für jedes Paar wird mit der Funktion process_symbol ein eigener Thread erstellt.

process_symbol lädt die Paardaten herunter, wandelt sie um, trainiert das XGBoost-Modell, testet es und handelt es dann online, wobei die Daten regelmäßig aktualisiert werden.

Für alle Paare aus „Symbole“ werden Threads erstellt. Nachdem alle Threads abgeschlossen sind, wartet das Programm mit thread.join() auf sie.

Auf diese Weise wird ein leistungsfähiges Multi-Threaded-Mehrwährungshandelssystem auf der Grundlage von XGBoost implementiert.

import threading

def process_symbol(symbol):
    try:
        # Retrieve data for the specified symbol
        raw_data = retrieve_data(symbol)
        if raw_data is None:
            print("No data found for symbol {}".format(symbol))
            return None

        # Augment data
        augmented_data = augment_data(raw_data)

        # Markup data
        marked_data = markup_data(augmented_data.copy(), 'close', 'label')

        # Label data
        labeled_data = label_data(marked_data, symbol)

        # Generate new features
        labeled_data_generate = generate_new_features(labeled_data, num_features=100, random_seed=1)

        # Cluster features by GMM
        labeled_data_clustered = cluster_features_by_gmm(labeled_data_generate, n_components=4)

        # Feature engineering
        labeled_data_engineered = feature_engineering(labeled_data_clustered, n_features_to_select=10)

        # Train XGBoost classifier
        train_data = labeled_data_engineered[labeled_data_engineered.index <= FORWARD]
        test_data = labeled_data_engineered[labeled_data_engineered.index > FORWARD]
        xgb_clf = train_xgboost_classifier(train_data, num_boost_rounds=1000)

        # Test XGBoost classifier
        test_features = test_data.drop(['label', 'labels'], axis=1)
        test_labels = test_data['labels']
        initial_balance = 10000.0
        markup = 0.00001
        test_model(xgb_clf, test_features, test_labels, markup, initial_balance)

        # Online trading
        position_id = None
        while True:
            # Get the last 2000 data points for online trading
            features = raw_data[-6000:].drop(['label', 'labels'], axis=1).values.tolist()

            # Update features every 6 seconds
            time.sleep(6)
            new_data = retrieve_data(symbol)
            if new_data is not None:
                raw_data = pd.concat([raw_data, new_data])
                raw_data = raw_data.dropna()

            # Online trading
            position_id = online_trading(symbol, features, xgb_clf, position_id)

    except Exception as e:
        print("Error processing {} symbol: {}".format(symbol, e))
        return None

symbols = ["EURUSD", "GBPUSD", "USDJPY", "AUDUSD", "USDCAD"]

# Create a list of threads for each symbol
threads = []
for symbol in symbols:
    thread = threading.Thread(target=process_symbol, args=(symbol,))
    thread.start()
    threads.append(thread)

# Wait for all threads to complete
for thread in threads:
    thread.join()

Nachdem wir den Code ausgeführt hatten, stießen wir auf ein Problem mit sich überschneidenden Bildschirmausgaben (Ausdrucken) von verschiedenen Threads. Dies macht die Ausgabe auf dem Bildschirm unleserlich und erschwert die Fehlersuche und Überwachung des Algorithmusbetriebs. Trotz zahlreicher Versuche, dieses Problem zu lösen, ist es bisher nicht gelungen, eine Überschneidung der Ausgaben zu vermeiden.

Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31




No data for symbol USDCAD yet (attempt 1)No data for symbol NZDUSD yet (attempt 1)No data for symbol AUDUSD yet (attempt 1)
No data for symbol GBPUSD yet (attempt 1)


Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31Instruments in terminal: 31



No data for symbol USDCAD yet (attempt 2)No data for symbol AUDUSD yet (attempt 2)No data for symbol GBPUSD yet (attempt 2)


Instruments in terminal: 31Instruments in terminal: 31

Instruments in terminal: 31
No data for symbol GBPUSD yet (attempt 3)
Instruments in terminal: 31

Trotz dieses Problems arbeitet der Algorithmus selbst korrekt und erfüllt seine Aufgaben. Es verarbeitet die Daten erfolgreich, trainiert das Modell und führt den Handel für jedes Währungspaar aus der Liste „Symbole“ durch. Durch parallele Berechnungen lässt sich die Geschwindigkeit des Algorithmus erheblich steigern und seine Effizienz verbessern.

Wir sehen also, dass der Algorithmus den Handel korrekt eröffnet:



Mögliche weitere Verbesserung des Systems

Quantum Machine Learning

Derzeit verwenden wir klassisches Modelltraining, aber in Zukunft planen wir den Übergang zu maschinellem Quantenlernen mit Qubits, um die Genauigkeit und Geschwindigkeit zu verbessern. Trotz der derzeitigen Schwierigkeiten mit Quantencomputern werden bereits spezielle Software und Algorithmen entwickelt. Ich plane, das Quantenlernen zu erforschen und in unser System zu implementieren, was einen bedeutenden Durchbruch darstellen könnte.

Markt-Feedback: Verstärkungslernen

Um das Handelssystem zu verbessern, können wir Verstärkungslernen (reinforcement learning) einsetzen. Das System agiert als Agent, der mit dem Markt interagiert und Belohnungen für gewinnbringende Geschäfte und Strafen für unrentable Geschäfte erhält. Mit Hilfe von Algorithmen wie dem DQN lernt das System und passt sich an, um seine Prognosen zu verbessern.

Schwarmintelligenz für die Auswahl von Stopps und Takes

Um die Effizienz unseres Systems zu verbessern, können wir die Schwarmintelligenz mit dem Algorithmus der Partikelschwarmoptimierung (PSO) einsetzen. Das System generiert verschiedene Stop-Loss- und Take-Profit-Parameter und bewertet deren Effizienz anhand historischer Daten. PSO wird uns helfen, die optimalen Parameter auszuwählen, die Anpassungsfähigkeit zu verbessern und die Risiken zu verringern.


Schlussfolgerung

Unser maschinelles Lernmodell für den Handel verwendet Datenvorverarbeitung, Datenanalyse und Algorithmen vom Typ XGBoost. Wir wenden auch Rauschaddition, Zeitverschiebung, Merkmalsberechnung, Klassenausgleich und Kreuzvalidierung an. Die Genauigkeit liegt bei Testdaten bei etwa 60 %.

Quantum Computing, Reinforcement Learning sowie Schwarmintelligenz für die Auswahl von Stop-Loss und Take-Profits sollen später implementiert werden. Dies wird die Qualität der Ausbildung, die Effizienz auf der Grundlage realer Daten und das Risikomanagement verbessern.

Die Sache hat jedoch einen Haken: Diese Technologien werden einen harten Wettbewerb zwischen den Algorithmen auf dem Markt hervorrufen. Früher konkurrierten die Händler miteinander, jetzt geht es eher darum, wessen Algorithmus besser ist.


Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/15127

Der Body im Connexus (Teil 4): Hinzufügen des HTTP-Hauptteils Der Body im Connexus (Teil 4): Hinzufügen des HTTP-Hauptteils
In diesem Artikel werden wir das Konzept des Body in HTTP-Anfragen untersuchen, das für das Senden von Daten wie JSON und Klartext unerlässlich ist. Wir besprechen und erklären, wie man es richtig mit den entsprechenden Kopfzeilen verwendet. Wir haben auch die Klasse ChttpBody eingeführt, die Teil der Connexus-Bibliothek ist und die Arbeit mit dem Body von Anfragen vereinfacht.
Datenwissenschaft und ML (Teil 31): CatBoost AI-Modelle für den Handel verwenden Datenwissenschaft und ML (Teil 31): CatBoost AI-Modelle für den Handel verwenden
CatBoost-KI-Modelle haben in letzter Zeit aufgrund ihrer Vorhersagegenauigkeit, Effizienz und Robustheit gegenüber verstreuten und schwierigen Datensätzen in der Community des maschinellen Lernens stark an Popularität gewonnen. In diesem Artikel werden wir im Detail erörtern, wie man diese Art von Modellen in einem Versuch, den Forex-Markt zu schlagen zu implementieren.
Wie man ein interaktives MQL5 Dashboard/Panel mit Hilfe der Controls-Klasse erstellt (Teil 1): Einrichten des Panels Wie man ein interaktives MQL5 Dashboard/Panel mit Hilfe der Controls-Klasse erstellt (Teil 1): Einrichten des Panels
In diesem Artikel erstellen wir ein interaktives Handels-Dashboard mit der Klasse Controls in MQL5, das zur Rationalisierung von Handelsvorgängen dient. Das Panel enthält einen Titel, Navigationsschaltflächen für Handel, Schließen und Informationen sowie spezielle Aktionsschaltflächen für die Ausführung von Geschäften und die Verwaltung von Positionen. Am Ende dieses Artikels werden Sie über ein Grundgerüst verfügen, das Sie in den nächsten Kapiteln weiter ausbauen können.
Algorithmus zur chemischen Reaktionsoptimierung (CRO) (Teil II): Zusammenstellung und Ergebnisse Algorithmus zur chemischen Reaktionsoptimierung (CRO) (Teil II): Zusammenstellung und Ergebnisse
Im zweiten Teil werden wir die chemischen Operatoren in einem einzigen Algorithmus zusammenfassen und eine detaillierte Analyse seiner Ergebnisse präsentieren. Wir wollen herausfinden, wie die Methode der chemischen Reaktionsoptimierung (CRO) mit der Lösung komplexer Probleme bei Testfunktionen zurechtkommt.