English
preview
Aufbau des Kerzenmodells Trend-Constraint (Teil 5): Nachrichtensystem (Teil II)

Aufbau des Kerzenmodells Trend-Constraint (Teil 5): Nachrichtensystem (Teil II)

MetaTrader 5Handel | 30 Juli 2024, 10:25
42 0
Clemence Benjamin
Clemence Benjamin

Inhalt


Einführung

Im vorigen Artikel haben wir den Integrationsprozess kurz vorgestellt. Durch die Aufteilung in Unterabschnitte wollten wir das Verständnis des Prozesses Schritt für Schritt vereinfachen. Eine solide Grundlage ist von entscheidender Bedeutung, und wir hoffen, dass die von uns gelegte Basis solide ist, wenn wir uns eingehender damit befassen, dass diese Integrationen nahtlos funktionieren, insbesondere innerhalb unseres Trend Constraint-Modells. Letztendlich ist es unser Ziel, bis zum Abschluss des Projekts Benachrichtigungen sowohl auf Telegram als auch auf WhatsApp bequem zu empfangen. So können wir sicherstellen, dass wir über Indikatoren auf dem Laufenden bleiben und keine Signale verpassen, während wir uns gleichzeitig mit Freunden und Familie in den sozialen Medien austauschen. Die Weitergabe von Signalen direkt auf der sozialen Plattform wird mühelos sein, sodass man nicht mehr zwischen den Anwendungen wechseln muss.

Ziel dieses Artikels ist es, uns umfassend durch die einzelnen Schritte zu führen, bis wir die gewünschten Ergebnisse erzielen. Mit dem im vorangegangenen Artikel erworbenen Grundwissen ist nun alles klar. Ich werde jede einzelne Codezeile des integrierten Programms erläutern. Es gibt vier Schlüsselkomponenten in diesem Projekt, die im Zusammenhang mit der Telegrammintegration stehen und die konsequent beachtet werden müssen.

  • Telegram Bot API.
  • Python-Skript.
  • Dedizierter Server für das Hosting des Skripts bei der Bearbeitung von Webanfragen.
  • Unser Indikatorprogramm ist für Telegramm konfiguriert.

Dies ist ein grundlegender Überblick über die am Hauptintegrationsprozess beteiligten Komponenten. Ich habe zwar speziell Telegram und WhatsApp erwähnt, aber es sei darauf hingewiesen, dass auch andere Social-Media-Plattformen integriert werden können, sofern eine Programmiersprache zur Verfügung steht, die diesen Prozess erleichtert. Da wir die Bedeutung der Sprachkompatibilität bei der Programmierung erkannt haben, haben wir Python und MQL5 in ein einziges Projekt integriert. Dies unterstreicht den Vorteil, mit verschiedenen Sprachen wie Python, C++, ONNX und C# vertraut zu sein. Dieses Wissen kann MQL5-Programmierern bei der Entwicklung von Funktionalitäten innerhalb der Plattform und der Integration mit anderen sozialen APIs sehr helfen.

Die praktische Integration von Telegram wird uns zum dritten Unterabschnitt von Teil 5 der Artikelserie führen, in dem WhatsApp weiter integriert wird, wobei eine ähnliche Struktur wie bei Telegram verfolgt wird, aber eine Nachrichten-API anstelle der Bot-API verwendet wird. Auf der Grundlage des von uns geschaffenen Fundaments wird diese Aufgabe leichter sein, da wir nun die Grundsätze im Kopf haben.


Integration von Telegram in Trend Constraint

Fahren wir mit unserem bedeutenden Projekt fort: An diesem Punkt machen wir praktisch dort weiter, wo wir aufgehört haben. Nach meinen Recherchen gibt es mehrere Methoden, um dies zu erreichen, solange die Codelogik verstanden wird. Ich habe mich jedoch für eine Methode entschieden, die die Verwendung eines Python-Skripts und der Funktion ShellExecuteW beinhaltet, um die Interaktion zwischen einem MetaTrader 5-Indikator und dem Telegram-Telebot zu erleichtern. Ich werde auf diese Aspekte noch näher eingehen. Dieser Ansatz hat den Vorteil, dass er für diejenigen, die mit Python und MQL5 vertraut sind, relativ einfach zu handhaben ist. Es sind keine umfangreichen Änderungen am MQL5-Indikator erforderlich. Der einzige Nachteil ist, dass es externe Abhängigkeiten wie Python-Skripte und Bibliotheken benötigt.

Ziel ist es, die Zugänglichkeit von MetaTrader 5-Signalen auf Telegram für ein breiteres Publikum zu verbessern und das einfache Teilen und Weiterleiten durch die Implementierung von Telebots zu erleichtern.

In einem früheren Artikel (Teil I) habe ich die Integrationsmethode besprochen, die die Funktion WebRequest verwendet. Bei der Überprüfung der MQL5-Dokumentation wurde jedoch festgestellt, dass diese Methode nicht ideal für die Integration von Indikatoren ist, aber gut mit Robotern funktioniert. 

Bei der Verwendung von Shell-DLL-Dateien ist Vorsicht geboten, da sie bei der Verwendung mit nicht vertrauenswürdigen Anwendungen ernsthafte Risiken bergen können. Es ist von entscheidender Bedeutung, dass Sie die Funktionsweise dieser Systeme auf Ihrem Computer vollständig verstehen und ihnen vertrauen, um Angriffe und Hackerangriffe zu verhindern.


Die Telegram BOT API verstehen

Ich gehe davon aus, dass Sie bereits ein aktiver Telegram-Nutzer sind. Das Projekt erfordert mehr Personalisierung und Privatsphäre, einschließlich Details, die ich für mich behalten werde. Folgen Sie den Anweisungen, um Ihren Telegram-Bot mit einem einzigartigen Namen zu erstellen, wie ich es mit @Botfather getan habe. Ich habe den Bot Trend Constraint genannt, mit dem Nutzernamen @trend_constraint_bot. Sie können Ihren eigenen Bot auf ähnliche Weise mit einem eindeutigen Namen erstellen. Hier ist eine kurze Übersicht, wie Sie mit Botfather beginnen können. Folgen Sie den Anweisungen von Botfather, um den Vorgang abzuschließen. Danach erhalten Sie ein Bot-Token für den Zugriff auf die Bot-API. Danach können Sie eine Unterhaltung mit dem Bot beginnen, ihn zu einer Gruppe oder einem Kanal hinzufügen, um mit dem Chat zu beginnen. Jeder Chat hat eine eindeutige ID, die der Bot zur Interaktion mit einem bestimmten Nutzer verwendet. Dieser Chat wird auch verwendet, um Signale vom MetaTrader 5 Indikator an einen Telegram-Nutzer weiterzuleiten.

Telegram-Bot mit botfather erstellen

Nachdem ich alles eingestellt hatte, besuchte ich die Bot-API mit dem Chrome-Browser. Erinnern Sie sich an das Bot-Token, das Sie vom BotFather erhalten haben, und verwenden Sie den Link zu API https://api.telegram.org/bot<Ihr Bot-Token>/getUpdates. Ersetzen Sie das hervorgehobene Text durch Ihren Bot-Token, damit es funktioniert.

Typisches Beispiel hier: https://api.telegram.org/bot9004946256:shTUYuq52f8CHLt8BLdYGHYJi2QM6H3donA/getUpdates

Anmerkung: Das hervorgehobene API-Token wurde zu Schulungszwecken zufällig generiert. Bitte verwenden Sie die von @BotFather bereitgestellte Version für Ihren Roboter. Stellen Sie sicher, dass Sie einen Chat mit dem Bot führen, damit die API anzeigt, was wir wollen. Aktualisieren Sie auch die Registerkarte des API-Browsers, damit neue Chat-Aktualisierungen angezeigt werden können. Aktivieren Sie das Kontrollkästchen Pretty-Print auf der API-Browser-Registerkarte, um ein übersichtliches Layout zu erhalten.

Die API wird einen JSON-Code für die laufende Kommunikation mit dem Bot anzeigen. Definieren wir zunächst JSON (JavaScript Object Notation) als ein einfaches Datenaustauschformat, das für Menschen leicht zu lesen und zu schreiben und für Maschinen leicht zu parsen und zu generieren ist. Es wird häufig für die Übertragung von Daten in Webanwendungen (z. B. zwischen einem Server und einem Client) und für die Konfiguration von Anwendungen und Datenspeichern verwendet. Es ist durch Objekte und Arrays strukturiert.

Nachfolgend sehen Sie ein API JSON, das nach dem Senden einer „Hey“-Nachricht an den Bot angezeigt wurde:

{
  "ok": true,
  "result": [
    {
      "update_id": 464310132,
      "message": {
        "message_id": 12,
        "from": {
          "id": 7049213628,
          "is_bot": false,
          "first_name": "Clemence",
          "last_name": "Benjamin",
          "username": "benjc_trade_advisor",
          "language_code": "en"
        },
        "chat": {
          "id": 7049213628,
          "first_name": "Clemence",
          "last_name": "Benjamin",
          "username": "benjc_trade_advisor",
          "type": "private"
        },
        "date": 1719044625,
        "text": "hey"
      }

Hier finden Sie eine ausführliche Erläuterung des JSON-Codes:

Top-Level-Struktur:

  • OK: Dies ist ein boolescher Wert, der den Erfolg der API-Anfrage angibt. In diesem Fall ist sie wahr, was bedeutet, dass die Anfrage erfolgreich war.
  • result: Dies ist ein Array, das ein oder mehrere Update-Objekte enthält. In diesem Beispiel gibt es ein Update-Objekt.

Innerhalb des Ergebnis-Arrays

Jedes Element im Ergebnisfeld stellt eine Aktualisierung dar. Hier haben wir eine einzige Aktualisierung:
  • update_id: Dies ist ein eindeutiger Bezeichner für die Aktualisierung. Es hilft, den Überblick über die Aktualisierungen zu behalten und sicherzustellen, dass keine verpasst oder mehrfach verarbeitet werden. In diesem Fall lautet die update_id 
  • 464310132.

Das Nachrichten-Objekt

Dieses Objekt enthält Informationen über die Nachricht, die die Aktualisierung ausgelöst hat:

  • message_id: Dies ist ein eindeutiger Bezeichner für die Nachricht innerhalb des Chats. Hier sind es 12.
  • from: Dieses Objekt enthält Informationen über den Absender der Nachricht:
  • id: Der eindeutige Bezeichner für den Nutzer, der die Nachricht gesendet hat. Hier ist er 7049213628.
  • is_bot: Dieser boolesche Wert zeigt an, ob der Absender ein Bot ist. In diesem Fall ist sie falsch, was bedeutet, dass der Absender ein Mensch ist.
  • first_name: Den Vornamen des Absenders, also Clemence.
  • last_name: Der Nachname des Absenders, d.h. Benjamin.
  • language_code: Der Sprachcode, der die Spracheinstellungen des Absenders angibt. Hier ist er en für Englisch.
  • chat: Dieses Objekt enthält Informationen über den Chat, in dem die Nachricht gesendet wurde.
  • id: Der eindeutige Bezeichner für den Chat. Da es sich um einen privaten Chat handelt, entspricht er der ID des Nutzers ( 7049213628 ).
  • first_name: Den Vornamen des Chat-Teilnehmers, also Clemence.
  • last_name: Der Nachname des Chat-Teilnehmers, d.h. Benjamin.
  • type: Die Art des Chats. Hier ist er privat, d. h. es handelt sich um einen persönlichen Chat zwischen dem Nutzer und dem Bot.
  • date: Das Datum und die Uhrzeit, zu der die Nachricht gesendet wurde, dargestellt als Unix-Zeitstempel (Sekunden seit dem 1. Januar 1970). In diesem Fall lautet der Zeitstempel 1719044625.
  • text: Der eigentliche Textinhalt der Nachricht, nämlich „hey“.

Ich habe beschlossen, den Chat-Abschnitt des JSON beiseite zu legen, damit wir uns auf den wichtigsten Teil konzentrieren können, nämlich die Chat-ID, die wir in unserem Indikatorprogramm benötigen. Sehen Sie sich den JSON-Ausschnitt unten an:

"chat": {
          "id": 7049213628,
          "first_name": "Clemence",
          "last_name": "Benjamin",
          "username": "benjc_trade_advisor",
          "type": "private"
        }

Das Objekt „chat“ enthält detaillierte Informationen über den Chat, in dem die Nachricht gesendet wurde, einschließlich der eindeutigen Kennung des Chats, des Vor- und Nachnamens der Teilnehmer und der Art des Chats. In diesem Fall handelt es sich um einen privaten Chat mit einem Nutzer namens Clemence Benjamin. Schauen wir uns eine detaillierte Erklärung des Objekts „chat“ an:

id:

  • Beschreibung: Dies ist der eindeutige Bezeichner für den Chat.
  • Wert: 7049213628
  • Bedeutung: Im Rahmen privater Chats entspricht diese ID in der Regel der Nutzer-ID des Chat-Teilnehmers.

first_name:

  • Beschreibung: Der Vorname des Teilnehmers im Chat.
  • Wert: Clemence
  • Bedeutung: Dies hilft, den Nutzer anhand seines Vornamens im Chat zu identifizieren.

last_name:

  • Beschreibung: Der Nachname des Teilnehmers im Chat.
  • Wert: Benjamin
  • Bedeutung: Dies ergänzt den Vornamen, um den Nutzer im Chat vollständig zu identifizieren.

„username“

  • Beschreibung: Das ist der Schlüssel, 
  • Wert: „benjc_trade_advisor“ 
  • Bedeutung: Diese Zeile gibt an, dass der mit dem Objekt (z. B. einem Nutzer, Bot oder Chat) verbundene Nutzername „benjc_trade_advisor“ lautet. Dieser Nutzername wird normalerweise verwendet, um die Entität in einem erkennbaren Format innerhalb von Anwendungen oder Systemen zu identifizieren, die die JSON-Daten verwenden.

type:

  • Beschreibung: Die Art des Chats.
  • Wert: privat
  • Bedeutung: Zeigt an, dass es sich bei diesem Chat um ein persönliches Gespräch zwischen dem Nutzer und dem Bot handelt (im Gegensatz zu einem Gruppenchat oder einem Kanal).

Zusammenfassung:

Ziel des oben genannten Abschnitts war es, einen funktionierenden Telegram-Bot zu entwickeln und das Bot-Token und die Chat-ID zu erwerben, beides entscheidende Elemente für das Hauptprojekt. Wir haben uns in die API vertieft, um ein besseres Verständnis der einzelnen Komponenten zu erlangen. Wenn wir das Bot-Token und die Chat-ID haben, können wir mit dem Integrationsprozess fortfahren, bei dem wir auch verschiedene Programmiersprachen erkunden werden.

Installation der Telegram-Python-Module unter Windows

Wir müssen Python auf Ihrem Computer installiert haben. Vergewissern Sie sich, dass Ihr Computer über einen Internetzugang verfügt. Sie können es von Python.org herunterladen. Ich habe diese Anleitung praktisch auf einem Windows-Computer erstellt. Auf Mac, Linux und anderen Frameworks kann es anders aussehen. Wenn die Python-Installation abgeschlossen ist, ist der nächste Schritt die Installation der Python-Telegram-API-Module, damit die Python-Skripte für Telegram gut laufen. Öffnen Sie die cmd.exe (Eingabeaufforderung) und führen Sie den unten stehenden Codeausschnitt aus. Kopieren Sie den Code und fügen Sie ihn in die Windows-Eingabeaufforderung ein. Drücken Sie die Eingabetaste auf der Tastatur, damit der Code heruntergeladen wird, und warten Sie kurz, bis die Installation des Moduls abgeschlossen ist.

pip install pyTelegramBotAPI

Nachfolgend sehen Sie einen Ausschnitt der Eingabeaufforderung als Screenshot.

Windows-Eingabeaufforderung zur Installation von Python-Telegramm-Api-Modulen

Wenn Sie fertig sind, können Sie das Fenster schließen und den Computer neu starten.

Nach Abschluss dieses Schritts ist Ihr Computer nun gut vorbereitet, um die Python-Skripte für die Interaktion mit der Telegram Bot API auszuführen. In der folgenden Phase werden wir den Code genau untersuchen, um unser System für die Aufgabe einzurichten.


Das Python-Skript send_telegram_messages verstehen

Schauen wir uns den Aufbau des Skripts an. Und dann werde ich den endgültigen Code in einem Schnipsel wiedergeben. Die Datei sollte den Namen send_telegram_message.py tragen

Das Skript beginnt mit dem Import der erforderlichen Module wie folgt:

  • import telebot: Importiert das Telebot-Modul, das die Funktionen bereitstellt, die für die Interaktion mit der Telegram Bot API benötigt werden.
  • import sys: Importiert das Modul sys, das es dem Skript ermöglicht, Befehlszeilenargumente zu verwenden.

import telebot
import sys

    Wir fahren fort mit der Deklaration des API_TOKEN und der Chat-ID:

    • API_TOKEN: Diese Variable speichert das API-Token des Bots, das zur Authentifizierung des Bots bei den Telegram-Servern verwendet wird.
    • CHAT_ID: Ein eindeutiger Wert für die Identität jedes Chats entweder zwischen dem Nutzer und dem Telebot oder zwischen dem Kanal und den Gruppen.
    Vergewissern Sie sich, dass die Werte für API_TOKEN und CHAT_ID wie unten gezeigt in einfachen Anführungszeichen stehen

    API_TOKEN = '9004946256:shTUYuq52f8CHLt8BLdYGHYJi2QM6H3donA' #Replace the API TOKEN with your bot tokrn from @BotFather
    CHAT_ID = '7049213628'  #Replace the ID with your actual Chat ID from the telebot API
    


      Wir müssen das Objekt TeleBot mit dem bereitgestellten API-Token initialisieren, um die Interaktion mit der Telegram Bot API zu ermöglichen.

      bot = telebot.TeleBot(API_TOKEN)
      


      Der nächste Python-Codeausschnitt definiert eine Funktion zum Senden einer Nachricht über Telegram, als Fehlerbehandlung von Ausnahmen im Zusammenhang mit der API und dem System.

      def send_telegram_message(message):
          try:
              bot.send_message(CHAT_ID, message)
              print("Message sent successfully!")
          except telebot.apihelper.ApiTelegramException as e:
              print(f"Failed to send message: {e}")
          except Exception as e:
              print(f"An error occurred: {e}")


      Der letzte Teil des Codes ist eine Bedingung, die sicherstellt, dass dieser Codeblock nur ausgeführt wird, wenn das Skript direkt ausgeführt wird, nicht wenn es als Modul importiert wird. Es ruft die Nachricht aus den Befehlszeilenargumenten ab oder setzt eine Standardnachricht, wenn keine Argumente angegeben werden.

      if __name__ == "__main__":
          message = sys.argv[1] if len(sys.argv) > 1 else "Test message"
          send_telegram_message(message)
      


      Zusammengefasst haben wir unseren endgültigen Code, speichern Sie die Datei als send_telegram_message.py und in Ihrem Python-Skripte-Ordner. Ich habe festgestellt, dass der Zugriff auf den Skriptordner gut funktioniert.

      import telebot
      import sys
      
      API_TOKEN = '9004946256:shTUYuq52f8CHLt8BLdYGHYJi2QM6H3donA'#Replace with your API_TOKEN given by BotFather
      CHAT_ID = '7049213628' #Replace with your CHAT_ID
      
      bot = telebot.TeleBot(API_TOKEN)
      
      def send_telegram_message(message):
          try:
              bot.send_message(CHAT_ID, message)
              print("Message sent successfully!")
          except telebot.apihelper.ApiTelegramException as e:
              print(f"Failed to send message: {e}")
          except Exception as e:
              print(f"An error occurred: {e}")
      
      if __name__ == "__main__":
         message = sys.argv[1] if len(sys.argv) > 1 else "Test message"
          send_telegram_message(message)
      

      Der nächste wichtige Schritt ist die Einrichtung des MQL5-Indikators zum Aufruf des Python-Skripts.


      Konfigurieren des Trend Constraint Indicator für Telegramm

      Hier müssen wir die Funktion myAlert im MQL5-Indikator ändern, um das Python-Skript mit der Funktion ShellExecuteW aufzurufen. Diese Funktion führt das Python-Skript aus und übergibt die Warnmeldung als Argument.

      Hier ist, wie wir es in Trend Constraint ändern, habe ich die beiden Code-Schnipsel vor der Änderung und nach der Änderung enthalten:

      Vor der Modifizierung:

      void myAlert(string type, string message)
        {
         if(type == "print")
            Print(message);
         else if(type == "error")
           {
            Print(type+" | Trend Constraint V1.05 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
           }
         else if(type == "order")
           {
           }
         else if(type == "modify")
           {
           }
         else if(type == "indicator")
           {
            if(Audible_Alerts) Alert(type+" | Trend Constraint V1.05 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
            if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.05 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
           }
        }

      Nach der Änderung:

      //--- ShellExecuteW declaration ----------------------------------------------
      #import "shell32.dll"
      int ShellExecuteW(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
      #import
      
      
      datetime last_alert_time;
      input int alert_cooldown_seconds = 60; // Cooldown period in seconds, this helps to avoid instant continuous alerting depending on indicator conditions
      
      //Modify the myAlert Function for telegram notification
      void myAlert(string type, string message) {
          datetime current_time = TimeCurrent();
          if (current_time - last_alert_time < alert_cooldown_seconds) {
              // Skip alert if within cooldown period
              return;
          }
      
          last_alert_time = current_time;
          string full_message = type + " | Trend Constraint V1.04 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
          if (type == "print") {
              Print(message);
          } else if (type == "error") {
              Print(type + " | Trend Constraint V1.04 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message);
          } else if (type == "order") {
              // Add order alert handling if needed
          } else if (type == "modify") {
              // Add modify alert handling if needed
          } else if (type == "indicator") {
              if (Audible_Alerts) {
                  Alert(full_message);
              }
              if (Push_Notifications) {
                  SendNotification(full_message);
              }
      
              // Send to Telegram
              string python_path = "C:\\Users\\Pro_tech\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
              string script_path = "C:\\Users\\Pro_tech\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
              string command = python_path + " \"" + script_path + "\" \"" + full_message + "\"";
              
              Print("Executing command to send Telegram message: ", command);
      
              // Use cmd.exe to execute the command and then wait for 5 seconds
              string final_command = "/c " + command + " && timeout 5";
              int result = ShellExecuteW(0, "open", "cmd.exe", final_command, NULL, 1);
              if (result <= 32) {
                  int error_code = GetLastError();
                  Print("Failed to execute Python script. Error code: ", error_code);
              } else {
                  Print("Successfully executed Python script. Result code: ", result);
              }
          }
      }
      
      
      //--- End of Telegram Integration functions ---------------------------------------

      Ich werde kurz erklären, was die Änderung bewirkt.

      Zunächst müssen wir die Funktion ShellExecuteW aus der Windows-Bibliothek shell32.dll importieren, damit das MQL5-Programm externe Befehle ausführen kann, in diesem Fall das Skript send_telegram_message.py. Ohne die Deklaration der Funktion ShellExecuteW wird das Programm nicht funktionieren. Wir haben auch die Abklingzeit eingeführt, um die ständige sofortige Ausführung von cmd.exe aufgrund einiger falsch konfigurierter Indikatorbedingungen zu verhindern. In meinem Fall gab es, wie im vorherigen Artikel erwähnt, eine Alarmbedingung in Puffer 5 und 6 des Trend Constraints V1.04, die mehrere Signalwarnungen in kurzer Zeit verursachte. Das Ergebnis war noch schlimmer, als ich die Telegram-Funktion integrierte, die cmd.exe wurde mehrmals auf einmal gestartet und der Computer fror ein. Um dies zu vermeiden, durfte ich den Indikator nur ohne myAlert() zeichnen lassen. Mit anderen Worten: Ich habe ihn stummgeschaltet, indem ich sie in Kommentare umgewandelt habe, denn Kommentare werden im Programm bekanntlich nicht ausgeführt.

      //--- ShellExecuteW declaration ----------------------------------------------
      #import "shell32.dll"
      int ShellExecuteW(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
      #import
      


      Der andere entscheidende Teil des Codes ist:

      // Send to Telegram
      string python_path = "C:\\Users\\Pro_tech\\AppData\\Local\\Programs\\Python\\Python312\\python.exe"; 
      string script_path = "C:\\Users\\Pro_tech\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
      string command = python_path + " \"" + script_path + "\" \"" + full_message + "\"";
      

      Der obige Code konstruiert einen Befehl zur Ausführung eines Python-Skripts aus einem MetaTrader 5-Indikatorprogramm heraus, wobei die Pfade zum Python-Interpreter und zum Skript sowie die zu sendende Nachricht angegeben werden. Den hervorgehobenen Text müssen Sie je nach Computer durch einen eigenen Text für den Pfad ersetzen. Dies habe ich als Beispiel von meinem Computer aus gegeben.


      Endgültiger Code

      Nachdem wir alles erklärt und erfolgreich integriert haben, haben wir nun eine neue Funktion und wir aktualisieren auf Trend Constraint V1.05

      //+------------------------------------------------------------------+
      //|                                       Trend Constraint V1.05.mq5 |
      //|                                Copyright 2024, Clemence Benjamin |
      //|                                             https://www.mql5.com |
      //+------------------------------------------------------------------+
      #property copyright "Copyright 2024, Clemence Benjamin"
      #property link      "https://www.mql5.com"
      #property version   "1.05"
      #property description "A model that seeks to produce sell signals when D1 candle is Bearish only and buy signals when it is Bullish"
      
      
      //--- indicator settings
      #property indicator_chart_window
      #property indicator_buffers 6
      #property indicator_plots 6
      
      #property indicator_type1 DRAW_ARROW
      #property indicator_width1 5
      #property indicator_color1 0xFF3C00
      #property indicator_label1 "Buy"
      
      #property indicator_type2 DRAW_ARROW
      #property indicator_width2 5
      #property indicator_color2 0x0000FF
      #property indicator_label2 "Sell"
      
      #property indicator_type3 DRAW_ARROW
      #property indicator_width3 2
      #property indicator_color3 0xE8351A
      #property indicator_label3 "Buy Reversal"
      
      #property indicator_type4 DRAW_ARROW
      #property indicator_width4 2
      #property indicator_color4 0x1A1AE8
      #property indicator_label4 "Sell Reversal"
      
      #property indicator_type5 DRAW_LINE
      #property indicator_style5 STYLE_SOLID
      #property indicator_width5 2
      #property indicator_color5 0xFFAA00
      #property indicator_label5 "Buy"
      
      #property indicator_type6 DRAW_LINE
      #property indicator_style6 STYLE_SOLID
      #property indicator_width6 2
      #property indicator_color6 0x0000FF
      #property indicator_label6 "Sell"
      
      #define PLOT_MAXIMUM_BARS_BACK 5000
      #define OMIT_OLDEST_BARS 50
      
      //--- indicator buffers
      double Buffer1[];
      double Buffer2[];
      double Buffer3[];
      double Buffer4[];
      double Buffer5[];
      double Buffer6[];
      
      input double Oversold = 30;
      input double Overbought = 70;
      input int Slow_MA_period = 200;
      input int Fast_MA_period = 100;
      datetime time_alert; //used when sending alert
      input bool Audible_Alerts = true;
      input bool Push_Notifications = true;
      double myPoint; //initialized in OnInit
      int RSI_handle;
      double RSI[];
      double Open[];
      double Close[];
      int MA_handle;
      double MA[];
      int MA_handle2;
      double MA2[];
      int MA_handle3;
      double MA3[];
      int MA_handle4;
      double MA4[];
      double Low[];
      double High[];
      int MA_handle5;
      double MA5[];
      int MA_handle6;
      double MA6[];
      int MA_handle7;
      double MA7[];
      
      //--- ShellExecuteW declaration ----------------------------------------------
      #import "shell32.dll"
      int ShellExecuteW(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
      #import
      
      //--- functions for telegram integration -----------------------------------------------
      datetime last_alert_time;
      input int alert_cooldown_seconds = 60; // Cooldown period in seconds
      
      void myAlert(string type, string message) {
          datetime current_time = TimeCurrent();
          if (current_time - last_alert_time < alert_cooldown_seconds) {
              // Skip alert if within cooldown period
              return;
          }
      
          last_alert_time = current_time;
          string full_message = type + " | Trend Constraint V1.05 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
          if (type == "print") {
              Print(message);
          } else if (type == "error") {
              Print(type + " | Trend Constraint V1.05 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message);
          } else if (type == "order") {
              // Add order alert handling if needed
          } else if (type == "modify") {
              // Add modify alert handling if needed
          } else if (type == "indicator") {
              if (Audible_Alerts) {
                  Alert(full_message);
              }
              if (Push_Notifications) {
                  SendNotification(full_message);
              }
      
              // Send to Telegram //Remember to replace the storages path with your actual path.
              string python_path = "C:\\Users\\Pro_tech\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
              string script_path = "C:\\Users\\Pro_tech\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
              string command = python_path + " \"" + script_path + "\" \"" + full_message + "\"";
              
              // Debugging: Print the command being executed
              Print("Executing command to send Telegram message: ", command);
      
              // Use cmd.exe to execute the command and then wait for 5 seconds
              string final_command = "/c " + command + " && timeout 5";
              int result = ShellExecuteW(0, "open", "cmd.exe", final_command, NULL, 1);
              if (result <= 32) {
                  int error_code = GetLastError();
                  Print("Failed to execute Python script. Error code: ", error_code);
              } else {
                  Print("Successfully executed Python script. Result code: ", result);
              }
          }
      }
      
      //+------------------------------------------------------------------+
      //| Custom indicator initialization function                         |
      //+------------------------------------------------------------------+
      int OnInit()
        {   
         SetIndexBuffer(0, Buffer1);
         PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(0, PLOT_ARROW, 241);
         SetIndexBuffer(1, Buffer2);
         PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(1, PLOT_ARROW, 242);
         SetIndexBuffer(2, Buffer3);
         PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(2, PLOT_ARROW, 236);
         SetIndexBuffer(3, Buffer4);
         PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(3, PLOT_ARROW, 238);
         SetIndexBuffer(4, Buffer5);
         PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         SetIndexBuffer(5, Buffer6);
         PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(5, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         //initialize myPoint
         myPoint = Point();
         if(Digits() == 5 || Digits() == 3)
           {
            myPoint *= 10;
           }
         RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE);
         if(RSI_handle < 0)
           {
            Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, PRICE_CLOSE);
         if(MA_handle < 0)
           {
            Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle2 = iMA(NULL, PERIOD_CURRENT, 400, 0, MODE_SMA, PRICE_CLOSE);
         if(MA_handle2 < 0)
           {
            Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle3 < 0)
           {
            Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE);
         if(MA_handle4 < 0)
           {
            Print("The creation of iMA has failed: MA_handle4=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle5 = iMA(NULL, PERIOD_CURRENT, Fast_MA_period, 0, MODE_SMA, PRICE_CLOSE);
         if(MA_handle5 < 0)
           {
            Print("The creation of iMA has failed: MA_handle5=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle6 = iMA(NULL, PERIOD_CURRENT, Slow_MA_period, 0, MODE_SMA, PRICE_CLOSE);
         if(MA_handle6 < 0)
           {
            Print("The creation of iMA has failed: MA_handle6=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle7 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle7 < 0)
           {
            Print("The creation of iMA has failed: MA_handle7=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         return(INIT_SUCCEEDED);
        }
      
      //+------------------------------------------------------------------+
      //| Custom indicator iteration function                              |
      //+------------------------------------------------------------------+
      int OnCalculate(const int rates_total,
                      const int prev_calculated,
                      const datetime& time[],
                      const double& open[],
                      const double& high[],
                      const double& low[],
                      const double& close[],
                      const long& tick_volume[],
                      const long& volume[],
                      const int& spread[])
        {
         int limit = rates_total - prev_calculated;
         //--- counting from 0 to rates_total
         ArraySetAsSeries(Buffer1, true);
         ArraySetAsSeries(Buffer2, true);
         ArraySetAsSeries(Buffer3, true);
         ArraySetAsSeries(Buffer4, true);
         ArraySetAsSeries(Buffer5, true);
         ArraySetAsSeries(Buffer6, true);
         //--- initial zero
         if(prev_calculated < 1)
           {
            ArrayInitialize(Buffer1, EMPTY_VALUE);
            ArrayInitialize(Buffer2, EMPTY_VALUE);
            ArrayInitialize(Buffer3, EMPTY_VALUE);
            ArrayInitialize(Buffer4, EMPTY_VALUE);
            ArrayInitialize(Buffer5, EMPTY_VALUE);
            ArrayInitialize(Buffer6, EMPTY_VALUE);
           }
         else
            limit++;
         datetime Time[];
         
         datetime TimeShift[];
         if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total);
         ArraySetAsSeries(TimeShift, true);
         int barshift_M1[];
         ArrayResize(barshift_M1, rates_total);
         int barshift_D1[];
         ArrayResize(barshift_D1, rates_total);
         for(int i = 0; i < rates_total; i++)
           {
            barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]);
            barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]);
         }
         if(BarsCalculated(RSI_handle) <= 0) 
            return(0);
         if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total);
         ArraySetAsSeries(RSI, true);
         if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total);
         ArraySetAsSeries(Open, true);
         if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total);
         ArraySetAsSeries(Close, true);
         if(BarsCalculated(MA_handle) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
         ArraySetAsSeries(MA, true);
         if(BarsCalculated(MA_handle2) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
         ArraySetAsSeries(MA2, true);
         if(BarsCalculated(MA_handle3) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total);
         ArraySetAsSeries(MA3, true);
         if(BarsCalculated(MA_handle4) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total);
         ArraySetAsSeries(MA4, true);
         if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
         ArraySetAsSeries(Low, true);
         if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
         ArraySetAsSeries(High, true);
         if(BarsCalculated(MA_handle5) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle5, 0, 0, rates_total, MA5) <= 0) return(rates_total);
         ArraySetAsSeries(MA5, true);
         if(BarsCalculated(MA_handle6) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle6, 0, 0, rates_total, MA6) <= 0) return(rates_total);
         ArraySetAsSeries(MA6, true);
         if(BarsCalculated(MA_handle7) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle7, 0, 0, rates_total, MA7) <= 0) return(rates_total);
         ArraySetAsSeries(MA7, true);
         if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
         ArraySetAsSeries(Time, true);
         //--- main loop
         for(int i = limit-1; i >= 0; i--)
           {
            if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
            
            if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue;
            if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue;
            
            //Indicator Buffer 1
            if(RSI[i] < Oversold
            && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value
            && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close
            && MA[i] > MA2[i] //Moving Average > Moving Average
            && MA3[i] > MA4[i] //Moving Average > Moving Average
            )
              {
               Buffer1[i] = Low[1+i]; //Set indicator value at Candlestick Low
               if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
               time_alert = Time[1];
              }
            else
              {
               Buffer1[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 2
            if(RSI[i] > Overbought
            && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value
            && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close
            && MA[i] < MA2[i] //Moving Average < Moving Average
            && MA3[i] < MA4[i] //Moving Average < Moving Average
            )
              {
               Buffer2[i] = High[1+i]; //Set indicator value at Candlestick High
               if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
               time_alert = Time[1];
              }
            else
              {
               Buffer2[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 3
            if(MA5[i] > MA6[i]
            && MA5[i+1] < MA6[i+1] //Moving Average crosses above Moving Average
            )
              {
               Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
               if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
               time_alert = Time[1];
              }
            else
              {
               Buffer3[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 4
            if(MA5[i] < MA6[i]
            && MA5[i+1] > MA6[i+1] //Moving Average crosses below Moving Average
            )
              {
               Buffer4[i] = High[i]; //Set indicator value at Candlestick High
               if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
               time_alert = Time[1];
              }
            else
              {
               Buffer4[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 5, Alert muted by turning it into a comment
            if(MA3[i] > MA7[i] //Moving Average > Moving Average
            )
              {
               Buffer5[i] = MA3[i]; //Set indicator value at Moving Average
               //if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
               //time_alert = Time[1];
              }
            else
              {
               Buffer5[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 6, Alert muted by turning it into a comment
            if(MA3[i] < MA7[i] //Moving Average < Moving Average
            )
              {
               Buffer6[i] = MA3[i]; //Set indicator value at Moving Average
               //if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
               //time_alert = Time[1];
              }
            else
              {
               Buffer6[i] = EMPTY_VALUE;
              }
           }
         return(rates_total);
        }
      //+------------------------------------------------------------------+


      Fehlerbehandlung

      Failed to send message: A request to the Telegram API was unsuccessful. Error code: 401. Description: Unauthorized

      Meinen Tests zufolge wurde der obige Fehlercode durch einen dysfunktionalen API_TOKEN verursacht, wie der, den wir zuvor als Beispiel verwendet haben. Sie müssen einen funktionierenden API_TOKEN-Wert verwenden. Die meisten der Fehler löschte ich, um zu einem sauberen Arbeitscode für diesen Leitfaden zu kommen, Sie könnten jedoch Fehler beim Bearbeiten oder Ändern Ihres Codes machen, daher müssen Sie sorgfältig jeden Schritt kontrollieren, den Sie machen.


      Ergebnisse der Tests

      Nachdem ich den Indikator zum Chart hinzugefügt hatte, aktivierte ich die Option DLL zulassen, damit unser Indikator Skripte über die Eingabeaufforderung ausführen kann. Das animierte Bild zeigt, wie der Indikator hinzugefügt wird und wie er im Chart erscheint.

        Starten des Indikators


      Sie können testen, ob das Skript funktioniert, indem Sie die Datei in ihrem Pfad über die Eingabeaufforderung ausführen (siehe Abbildung unten). Geben Sie bei geöffneter Eingabeaufforderung in den Ordner mit Ihrem Skript python send_telegram_message.py ein. Eine erfolgreich gesendete Nachricht und die Antwort zeigen, dass das Skript funktioniert und die Testnachricht wird ebenfalls an den Chat weitergeleitet.

      Testnachricht cmd


      Das Ergebnisbild unten zeigt den Beginn einer Konversation mit dem Bot, die es uns ermöglicht hat, die Chat-ID in der Bot-API zu erhalten. Es zeigt auch das eingehende Signal, das der Bot von Trend Constraint V1.05 sendet. Die Signale kamen sofort an, da sie in der MetaTrader 5 Plattform generiert wurden.

      Telegramm-Chat mit Trend Contraint telebot


      Schlussfolgerung

      Wir haben Telegramm erfolgreich in unser Modell integriert. Trend Constraint V1.05 wurde erheblich weiterentwickelt und ist nun in der Lage, Signale intern und extern weiterzuleiten, wovon Händler weltweit mit Telegram-Zugang profitieren. Die Signalübertragung erfolgt schnell und ohne Verzögerungen aufgrund der effizienten Ausführung des Algorithmus. Das System ist auf einen bestimmten Indikator innerhalb der Plattform ausgerichtet, sodass andere Funktionen nicht beeinträchtigt werden. Die Signale werden sicher und direkt an eine bestimmte ID übertragen. Diese Systeme können für einen kontinuierlichen Betrieb auf einem Virtual Private Server gehostet werden und bieten den Nutzern eine stabile Signalversorgung. Bei solchen Projekten können während der Entwicklung Fehler auftreten, aber ich freue mich, dass ich sie erfolgreich beheben konnte.

      Ich hoffe, dieses Projekt hat Sie in irgendeiner Weise inspiriert. Wenn Sie an einem Projekt arbeiten und bei dieser Art der Integration auf Probleme gestoßen sind, können Sie uns Ihre Gedanken im untenstehenden Diskussionsbereich mitteilen. Im Anhang finden Sie die Quelldateien, die Sie für Ihre Projekte abändern und mit Hilfe der Kommentare, die zu Lehrzwecken bereitgestellt werden, einige Ideen erkunden können. Als Nächstes planen wir die Integration einer weiteren beliebten sozialen Plattform, WhatsApp.


      Anhänge Beschreibung
      send_telegram_message.py Das Skript, mit dem der Indikator Benachrichtigungen an Telegram weitergibt, enthält API_Token und Chat ID
      Trend Constraint V1.05.mq5 Der Quellcode des Hauptprogramms des MQL5-Indikators
      Telebot_API.txt Telegram Bot API Struktur


      Übersetzt aus dem Englischen von MetaQuotes Ltd.
      Originalartikel: https://www.mql5.com/en/articles/14968

      Beigefügte Dateien |
      Telebot_API.txt (0.61 KB)
      Erstellung von Zeitreihenvorhersagen mit neuronalen LSTM-Netzen: Normalisierung des Preises und Tokenisierung der Zeit Erstellung von Zeitreihenvorhersagen mit neuronalen LSTM-Netzen: Normalisierung des Preises und Tokenisierung der Zeit
      In diesem Artikel wird eine einfache Strategie zur Normalisierung der Marktdaten anhand der täglichen Spanne und zum Training eines neuronalen Netzes zur Verbesserung der Marktprognosen beschrieben. Die entwickelten Modelle können in Verbindung mit einem bestehenden technischen Analysesystem oder auf eigenständiger Basis verwendet werden, um die allgemeine Marktrichtung vorherzusagen. Der in diesem Artikel skizzierte Rahmen kann von jedem technischen Analysten weiter verfeinert werden, um Modelle zu entwickeln, die sowohl für manuelle als auch für automatisierte Handelsstrategien geeignet sind.
      Datenwissenschaft und maschinelles Lernen (Teil 24): Zeitreihenprognose im Forex mit regulären AI-Modellen Datenwissenschaft und maschinelles Lernen (Teil 24): Zeitreihenprognose im Forex mit regulären AI-Modellen
      Auf den Devisenmärkten ist es sehr schwierig, den zukünftigen Trend vorherzusagen, ohne eine Vorstellung von der Vergangenheit zu haben. Nur sehr wenige maschinelle Lernmodelle sind in der Lage, Vorhersagen zu treffen, indem sie vergangene Werte berücksichtigen. In diesem Artikel werden wir erörtern, wie wir klassische (Nicht-Zeitreihen-) Modelle der Künstlichen Intelligenz nutzen können, um den Markt zu schlagen
      Entwicklung einer Zone Recovery Martingale Strategie in MQL5 Entwicklung einer Zone Recovery Martingale Strategie in MQL5
      In diesem Artikel werden die Schritte, die für die Erstellung eines auf dem Zone Recovery-Handelsalgorithmus basierenden Expert Advisors erforderlich sind, ausführlich beschrieben. Dies hilft, das System zu automatisieren und spart den Algotradern Zeit.
      Integrieren Sie Ihr eigenes LLM in EA (Teil 4): Trainieren Sie Ihr eigenes LLM mit GPU Integrieren Sie Ihr eigenes LLM in EA (Teil 4): Trainieren Sie Ihr eigenes LLM mit GPU
      Angesichts der rasanten Entwicklung der künstlichen Intelligenz sind Sprachmodelle (language models, LLMs) heute ein wichtiger Bestandteil der künstlichen Intelligenz, sodass wir darüber nachdenken sollten, wie wir leistungsstarke LLMs in unseren algorithmischen Handel integrieren können. Für die meisten Menschen ist es schwierig, diese leistungsstarken Modelle auf ihre Bedürfnisse abzustimmen, sie lokal einzusetzen und sie dann auf den algorithmischen Handel anzuwenden. In dieser Artikelserie werden wir Schritt für Schritt vorgehen, um dieses Ziel zu erreichen.