English 日本語
preview
Aufbau des Kerzenmodells Trend-Constraint (Teil 6): Alles in einem integrieren

Aufbau des Kerzenmodells Trend-Constraint (Teil 6): Alles in einem integrieren

MetaTrader 5Handelssysteme | 3 September 2024, 10:24
54 0
Clemence Benjamin
Clemence Benjamin
  1. Einführung
  2. Wichtige Abschnitte der Integration
  3. Kombination der Integrationslogik
  4. Die Kommentarfunktion
  5. Prüfung der Auswirkungen der Kommentarfunktion
  6. Schlussfolgerung


Einführung

Unser Signalsystem hat in jeder Phase seiner Entwicklung immer wieder außergewöhnliche Leistungen gezeigt. Das derzeitige Ziel besteht darin, die bestehenden Programme zu einem einzigen, einheitlichen Signalsystem zusammenzuführen. Denken Sie daran, dass die beiden vorherigen Versionen des Trend Constraint-Indikators jeweils ihre spezifischen Integrationen in Teil 5 hatten. Diese Konsolidierung zielt darauf ab, die volle Leistung der Programmierung zu nutzen, die die menschliche Arbeitsbelastung erheblich reduziert, indem sie es Computern ermöglicht, komplexe, sich wiederholende Aufgaben mit unglaublicher Geschwindigkeit auszuführen.

Da es sich um zwei Programme mit ähnlicher Logik, aber unterschiedlichen Funktionen handelt, geht es bei der Integration um mehr als nur das Kopieren und Einfügen von Quellcode. Stattdessen werden wir strategisch bestimmte Elemente beibehalten, die in beiden Programmen einheitliche Auswirkungen haben, um eine optimale Funktionalität zu gewährleisten. Dieser Prozess, den ich als Verschmelzung bezeichne, erfordert sorgfältige Überlegung und Präzision.

In diesem Artikel werden wir die MQL5-Codeabschnitte aufschlüsseln, in denen die Integration stattfindet, und die wichtigsten Zeilen besprechen, die während des Zusammenführungsprozesses global bleiben. Diese sorgfältige Vorgehensweise ist unerlässlich, wenn mehrere Codeschnipsel zu einem zusammenhängenden und effizienten Programm kombiniert werden sollen.

Aus Teil 5 und seinen Unterabschnitten konnten wir zwei große Integrationen zusammenfassen:

  1. Integration von Telegram mit MetaTrader 5 für Benachrichtigungen.
  2. Integration von WhatsApp mit MetaTrader 5 für Benachrichtigungen.

Eine Herausforderung besteht darin, dass unsere Integration Aufgaben in der Eingabeaufforderung ausführt, wobei das Fenster ausgeblendet wird, um andere Prozesse auf dem Computerbildschirm nicht zu beeinträchtigen. Folglich gibt es keine Bestätigung, ob die Signale erfolgreich an die Zielplattformen gesendet wurden. Wir möchten, dass unser System jede erfolgreiche Signalübertragung im Chart-Fenster kommentiert oder zumindest im Plattform-Journal ausgibt.

In den nächsten Abschnitten dieses Artikels werden wir uns mit weiteren Erkenntnissen befassen.


Unsere wichtigsten Integrationsbereiche

Ich habe die wichtigsten Punkte aus dem Code extrahiert, die für die Diskussion in diesem Artikel von Interesse sind. Ausführlichere Diskussionen finden Sie in Teil 5. Hier sind die Programme, die wir vergleichen, um den Zusammenführungsprozess zu erleichtern. Werfen Sie einen Blick auf die einzelnen Programme und vergleichen Sie ihre Gemeinsamkeiten und Unterschiede. Dieser Vergleich wird uns helfen, die Schlüsselbereiche zu identifizieren, in denen eine Integration erforderlich ist, um eine nahtlose und effiziente Zusammenführung zu gewährleisten.

  • Integration von Telegram: 

/--- 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
        string python_path = "C:\\Users\\your_computer_name\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
        string script_path = "C:\\Users\\your_computer_name\\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);
        }
    }
}

  • Integration von WhatsApp:

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

//--- global variables ------------------------------------------------------
datetime last_alert_time;
input int alert_cooldown_seconds = 60; // Cooldown period in seconds


//--- myAlert function ------------------------------------------------------
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.06 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
    if (type == "print") {
        Print(message);
    } else if (type == "error") {
        Print(type + " | Trend Constraint V1.06 @ " + 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" || type == "info") {
        if (Audible_Alerts) {
            Alert(full_message);
        }
        if (Push_Notifications) {
            SendNotification(full_message);
        }

        // Send to WhatsApp
        string python_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
        string script_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_whatsapp_message.py";
        string command = python_path + " \"" + script_path + "\" \"" + full_message + "\"";
        
        // Debugging: Print the command being executed
        Print("Executing command to send WhatsApp 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);
        }
    }
}

    Kombination der Integrationslogik

    Um ein einziges Programm zu erstellen, das sowohl WhatsApp als auch Telegram mit den beiden bereitgestellten Codestücken integriert, werden wir die Logik aus jedem Schnipsel in einer zusammenhängenden Funktion kombinieren. Der Plan sieht folgendermaßen aus: 

    1. Kombinieren der globalen Variablen und Deklarationen: Wir werden die Deklarationen und globalen Variablen konsolidieren.
    2. Zusammenführen der Funktion myAlert : Wir werden die Funktion myAlert erweitern, um das Senden von Nachrichten an WhatsApp und Telegram zu ermöglichen.
    3. Anpassen der Befehlsausführungslogik: Wir werden dafür sorgen, dass beide Befehle (WhatsApp und Telegram) innerhalb derselben Funktion ausgeführt werden.
    4. Sicherstellen, dass die Abkühlphase (Cooldown Period) eingehalten wird: Wir werden die Logik beibehalten, die sicherstellt, dass die Warnmeldungen nicht zu häufig gesendet werden.

    Um Deklarationen und globale Variablen zu kombinieren, enthielten beide Codestücke die Deklaration von ShellExecuteW und eine Variable für die Abkühlphase, die am Anfang des Codes vereinigt sind, um Redundanz zu vermeiden. Die Funktion myAlert wurde um eine Logik für die Benachrichtigungen mit WhatsApp und Telegram erweitert, wobei eine Logik der Abkühlphase der Benachrichtigungen dafür sorgt, dass Nachrichten nicht zu häufig gesendet werden. Zusammenfassend lässt sich sagen, dass für WhatsApp der Pfad zur ausführbaren Python-Datei und zum WhatsApp-Skript definiert wird und ein Befehlsstring erstellt wird, um das Skript zum Senden von WhatsApp-Nachrichten auszuführen. Dieser Befehl wird mit ShellExecuteW ausgeführt, mit einer Ergebnisprüfung, um eventuelle Fehler zu protokollieren. In ähnlicher Weise wird für Telegram der Pfad zur ausführbaren Python-Datei und zum Telegram-Skript definiert, eine Befehlszeichenfolge erstellt, um das Telegram-Skript zum Versenden von Nachrichten auszuführen, und der Befehl wird mit ShellExecuteW ausgeführt, wobei eine Ergebnisprüfung erfolgt, um etwaige Fehler zu protokollieren.

    Hier ist das kombinierte Programm:

    //--- ShellExecuteW declaration ----------------------------------------------
    #import "shell32.dll"
    int ShellExecuteW(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
    #import
    
    //--- global variables ------------------------------------------------------
    datetime last_alert_time;
    input int alert_cooldown_seconds = 60; // Cooldown period in seconds
    
    //--- myAlert function ------------------------------------------------------
    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.06 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
        if (type == "print") {
            Print(message);
        } else if (type == "error") {
            Print(type + " | Trend Constraint V1.06 @ " + 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" || type == "info") {
            if (Audible_Alerts) {
                Alert(full_message);
            }
            if (Push_Notifications) {
                SendNotification(full_message);
            }
    
            // Send to WhatsApp
            string python_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
            string whatsapp_script_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_whatsapp_message.py";
            string whatsapp_command = python_path + " \"" + whatsapp_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for WhatsApp
            Print("Executing command to send WhatsApp message: ", whatsapp_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_whatsapp_command = "/c " + whatsapp_command + " && timeout 5";
            int whatsapp_result = ShellExecuteW(0, "open", "cmd.exe", final_whatsapp_command, NULL, 1);
            if (whatsapp_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute WhatsApp Python script. Error code: ", error_code);
            } else {
                Print("Successfully executed WhatsApp Python script. Result code: ", whatsapp_result);
            }
    
            // Send to Telegram
            string telegram_script_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
            string telegram_command = python_path + " \"" + telegram_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for Telegram
            Print("Executing command to send Telegram message: ", telegram_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_telegram_command = "/c " + telegram_command + " && timeout 5";
            int telegram_result = ShellExecuteW(0, "open", "cmd.exe", final_telegram_command, NULL, 1);
            if (telegram_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute Telegram Python script. Error code: ", error_code);
            } else {
                Print("Successfully executed Telegram Python script. Result code: ", telegram_result);
            }
        }
    }
    
    

    In diesem Stadium sollten wir den Code in Abschnitte unterteilen, um deren Funktionen zu erklären:

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

    Dieser Abschnitt importiert die Funktion ShellExecuteW aus der Windows-Bibliothek shell32.dll. ShellExecuteW ist eine Windows-API-Funktion, die eine Operation an einer angegebenen Datei durchführt. Durch den Import dieser Funktion kann der MQL5-Code externe Befehle oder Skripte ausführen, wie z. B. Python-Skripte zum Senden von Nachrichten über WhatsApp und Telegram.

    datetime last_alert_time;
    input int alert_cooldown_seconds = 60; // Cooldown period in seconds
    

    Der obige Codeschnipsel erstellt die globalen Variablen des Integrationsalgorithmus.

    • letzte_alarm_zeit: Eine globale Variable, die den Zeitstempel der zuletzt gesendeten Meldung speichert. Dies hilft bei der Einführung einer Abkühlungsphase zwischen den Warnmeldungen.
    • alert_cooldown_seconds: Eine (vom Nutzer konfigurierbare) Eingabevariable, die die Abkühlphase in Sekunden angibt. Damit wird festgelegt, wie häufig Warnmeldungen gesendet werden können, um Spam zu vermeiden.

    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.06 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
        if (type == "print") {
            Print(message);
        } else if (type == "error") {
            Print(type + " | Trend Constraint V1.06 @ " + 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" || type == "info") {
            if (Audible_Alerts) {
                Alert(full_message);
            }
            if (Push_Notifications) {
                SendNotification(full_message);
            }
    
            // Send to WhatsApp
            string python_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
            string whatsapp_script_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_whatsapp_message.py";
            string whatsapp_command = python_path + " \"" + whatsapp_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for WhatsApp
            Print("Executing command to send WhatsApp message: ", whatsapp_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_whatsapp_command = "/c " + whatsapp_command + " && timeout 5";
            int whatsapp_result = ShellExecuteW(0, "open", "cmd.exe", final_whatsapp_command, NULL, 1);
            if (whatsapp_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute WhatsApp Python script. Error code: ", error_code);
            } else {
                Print("Successfully executed WhatsApp Python script. Result code: ", whatsapp_result);
            }
    
            // Send to Telegram
            string telegram_script_path = "C:\\Users\\Your_Computer_Name\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
            string telegram_command = python_path + " \"" + telegram_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for Telegram
            Print("Executing command to send Telegram message: ", telegram_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_telegram_command = "/c " + telegram_command + " && timeout 5";
            int telegram_result = ShellExecuteW(0, "open", "cmd.exe", final_telegram_command, NULL, 1);
            if (telegram_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute Telegram Python script. Error code: ", error_code);
            } else {
                Print("Successfully executed Telegram Python script. Result code: ", telegram_result);
            }
        }
    }
    
    

    •  Die Funktion myAlert ist so konzipiert, dass sie Warnmeldungen auf der Grundlage des angegebenen Typs und der angegebenen Nachricht versendet. Es verwaltet die Abkühlphase, erstellt die Warnmeldung und sendet sie über externe Python-Skripte sowohl an WhatsApp als auch an Telegram. Wie Sie sehen können, ist dies der größte Abschnitt des Codes.
    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;
    
    • In diesem Abschnitt wird geprüft, ob die aktuelle Zeit abzüglich der letzten Alarmzeit kleiner ist als die Abkühlungszeit. Wenn ja, wird die Meldung nicht gesendet. Dies verhindert häufige Alarme innerhalb eines kurzen Zeitraums.

    Um sicherzustellen, dass unsere Skripte funktionieren, erhalten wir in der Eingabeaufforderung die folgenden Ergebnisse:

    C:\Users\Your_Computer_Name\AppData\Local\Programs\Python\Python312\Scripts>python send_telegram_message.py "Trend Constraint V1.07 testing"
    Message sent successfully!
    
    C:\Users\Your_Computer_Name\AppData\Local\Programs\Python\Python312\Scripts>python send_whatsapp_message.py "Trend Constraint V1.07 testing"
    Message sent successfully

    Der hervorgehobene Text ist die positive Antwort der Eingabeaufforderung, die bestätigt, dass unsere Skripte einwandfrei funktionieren. Es ist sehr wichtig, dass der Dateipfad im Hauptprogramm korrekt eingegeben wird.

    Auf der anderen Seite empfangen wir die Signale auch auf unseren sozialen Plattformen. Unten sehen Sie links ein Bild, das eine Telegram-Testnachricht aus der Eingabeaufforderung zeigt, und rechts eine WhatsApp-Testnachricht aus der Eingabeaufforderung. Jetzt sind wir sicher, dass unser Programm gut funktioniert, und wir können mit unserem Hauptprogramm fortfahren.

    Test des Telegram-Skripts Test des Whatsapp-Skripts

    In der obigen Abbildung läuft die Sandbox-Verbindung, die von der Twilio API für die WhatsApp-Integration bereitgestellt wird, innerhalb von 72 Stunden ab. Es ist wichtig, die Verbindung wiederherzustellen, indem Sie eine eindeutige Nachricht senden, um für den Empfang von API-Nachrichten wieder hinzugefügt zu werden. In diesem Fall lautet die Nachricht, um wieder verbunden zu werden, „join so-cave“. Um einen nicht auslaufenden Dienst zu erwerben, können Sie eine Twilio-Nummer kaufen.

    Lassen Sie uns fortfahren und alles in ein Programm integrieren, indem wir die Logik des Trend Constraint Indikators verwenden. Damit sind wir bei Trend Constraint V1.07 angelangt:

    //+------------------------------------------------------------------+
    //|                                       Trend Constraint V1.07.mq5 |
    //|                                Copyright 2024, Clemence Benjamin |
    //|                                             https://www.mql5.com |
    //+------------------------------------------------------------------+
    
    #property copyright "Copyright 2024, Clemence Benjamin"
    #property link      "https://www.mql5.com"
    #property version   "1.07"
    #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
    
    //--- global variables ------------------------------------------------------
    datetime last_alert_time;
    input int alert_cooldown_seconds = 60; // Cooldown period in seconds
    
    //--- myAlert function ------------------------------------------------------
    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.07 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
        if (type == "print") {
            Print(message);
        } else if (type == "error") {
            Print(type + " | Trend Constraint V1.07 @ " + 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" || type == "info") {
            if (Audible_Alerts) {
                Alert(full_message);
            }
            if (Push_Notifications) {
                SendNotification(full_message);
            }
    
            // Send to WhatsApp //Replace your_computer_name with the your actual computer name. //Make sure the path to your python and scripts is correct.
            string python_path = "C:\\Users\\Your_Computer\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
            string whatsapp_script_path = "C:\\Users\\Your_computer_name\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_whatsapp_message.py";
            string whatsapp_command = python_path + " \"" + whatsapp_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for WhatsApp
            Print("Executing command to send WhatsApp message: ", whatsapp_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_whatsapp_command = "/c " + whatsapp_command + " && timeout 5";
            int whatsapp_result = ShellExecuteW(0, "open", "cmd.exe", final_whatsapp_command, NULL, 1);
            if (whatsapp_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute WhatsApp Python script. Error code: ", error_code);
            } else {
                Print("Successfully executed WhatsApp Python script. Result code: ", whatsapp_result);
            }
    
            // Send to Telegram
            string telegram_script_path = "C:\\Users\\protech\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
            string telegram_command = python_path + " \"" + telegram_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for Telegram
            Print("Executing command to send Telegram message: ", telegram_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_telegram_command = "/c " + telegram_command + " && timeout 5";
            int telegram_result = ShellExecuteW(0, "open", "cmd.exe", final_telegram_command, NULL, 1);
            if (telegram_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute Telegram Python script. Error code: ", error_code);
            } else {
                Print("Successfully executed Telegram Python script. Result code: ", telegram_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));
       // Send test message on launch
       myAlert("info", "Thank you for subscribing. You shall be receiving Trend Constraint signal alerts via Whatsapp.");
       //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);
      }
    //+------------------------------------------------------------------+

    Wenn Sie aufmerksam beobachtet haben, haben wir den Indikator von V1.06 auf V1.07 aktualisiert. Nach dem Kompilieren des Programms traten keine Fehler auf, und unser Programm läuft jetzt reibungslos auf MetaTrader 5. Unten sehen Sie die Bilder der Testnachrichten, die beim Start des Indikators auf MT5 gesendet werden: ganz links sind Push-Benachrichtigungen auf MetaTrader 5 Android mobile, in der Mitte ist eine Telegram-Testbenachrichtigung und rechts eine WhatsApp-Testnachricht.

    MetaTrade 5 PushNotification für Android Telegram, Trend Constraint V1.07 Test Whatsapp, Trend Constraint V1.07 Test



    Die Kommentarfunktion

    Die Kommentarfunktion in MQL5 ist eine integrierte Funktion, mit der nutzerdefinierte Textmeldungen direkt im Chart angezeigt werden können. Diese Funktion hilft uns, visuelles Feedback in Echtzeit zu geben, indem Meldungen angezeigt werden, die während der Ausführung eines Indikators oder eines Expert Advisors kontinuierlich aktualisiert werden können. In diesem Fall wollen wir damit Folgendes erreichen:

    • Benachrichtigung des Nutzers über den erfolgreichen Start des Indikators.
    • Bestätigung des erfolgreichen Versands von Warnmeldungen.
    • Warnung des Nutzers bei Fehlern beim Versand von Warnmeldungen.

    Wir werden drei Bereiche in den Code aufnehmen, um die Funktion zu integrieren:

    int OnInit() {
        // Initialization code here
        Comment("Indicator successfully launched.");
        return INIT_SUCCEEDED;
    }
        
    

    Der Zweck des obigen Codeschnipsels ist es, uns zu benachrichtigen, dass der Indikator erfolgreich gestartet wurde. Nach erfolgreicher Initialisierung des Indikators zeigt die Funktion Kommentar die Meldung „Indicator successfully launched“ im Chart an. Dies gibt eine unmittelbare Rückmeldung, dass der Indikator aktiv ist und läuft.

    if (result > 32) {
        Print("Successfully executed Python script. Result code: ", result);
        Comment("Success message sent: " + message);
    }
    

    Damit wird uns mitgeteilt, dass eine Warnmeldung erfolgreich gesendet wurde. Wenn eine Warnmeldung mit der Funktion myAlert erfolgreich gesendet wurde, zeigt die Funktion die Meldung „Success message sent [message]“ auf dem Chart an, wobei [message] der eigentliche Nachrichteninhalt ist. Dadurch erhalten wir die Bestätigung, dass die Ausschreibung korrekt übermittelt wurde.

    if (result <= 32) {
        int error_code = GetLastError();
        Print("Failed to execute Python script. Error code: ", error_code);
        Comment("Failed to send message: " + message);
    }
    

    Schließlich wollen wir auch über einen fehlgeschlagenen Start informiert werden, was die Funktionalität unseres Programms verbessert. Dieser Ausschnitt benachrichtigt uns über einen Fehler beim Senden einer Warnmeldung. Wenn das Senden einer Warnmeldung fehlschlägt, wird auf dem Chart die Meldung „Failed to send message [message]“ angezeigt, wobei [message] der beabsichtigte Inhalt der Warnmeldung ist. Auf diese Weise werden wir auf den Fehler aufmerksam gemacht und können Abhilfemaßnahmen ergreifen.

    Um die neuen Möglichkeiten, die durch die Kommentar-Funktion zu nutzen, habe ich unser Programm auf Trend Constraint V1.08 aktualisiert. Durch die strategische Integration dieser Funktion in die entsprechenden Abschnitte des Codes konnte ich das Programm erfolgreich aktualisieren und seinen reibungslosen Betrieb sicherstellen. Nachfolgend finden Sie den Quellcode, in dem die geänderten Abschnitte hervorgehoben sind, um die vorgenommenen Verbesserungen zu verdeutlichen.

    //+------------------------------------------------------------------+
    //|                                       Trend Constraint V1.08.mq5 |
    //|                                Copyright 2024, Clemence Benjamin |
    //|                                             https://www.mql5.com |
    //+------------------------------------------------------------------+
    
    #property indicator_chart_window
    #property copyright "Copyright 2024, Clemence Benjamin"
    #property link      "https://www.mql5.com"
    #property version   "1.08"
    #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
    
    //--- global variables ------------------------------------------------------
    datetime last_alert_time;
    input int alert_cooldown_seconds = 60; // Cooldown period in seconds
    
    //--- myAlert function ------------------------------------------------------
    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.08 @ " + Symbol() + "," + IntegerToString(Period()) + " | " + message;
        
        string comment = "Alert triggered by Trend Constraint V1.08 | Symbol: " + Symbol() + " | Period: " + IntegerToString(Period()) + " | Message: " + message;
    
        if (type == "print") {
            Print(message);
        } else if (type == "error") {
            Print(type + " | Trend Constraint V1.08 @ " + 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" || type == "info") {
            if (Audible_Alerts) {
                Alert(full_message);
            }
            if (Push_Notifications) {
                SendNotification(full_message);
            }
    
            // Send to WhatsApp
            string python_path = "C:\\Users\\protech\\AppData\\Local\\Programs\\Python\\Python312\\python.exe";
            string whatsapp_script_path = "C:\\Users\\protech\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_whatsapp_message.py";
            string whatsapp_command = python_path + " \"" + whatsapp_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for WhatsApp
            Print("Executing command to send WhatsApp message: ", whatsapp_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_whatsapp_command = "/c " + whatsapp_command + " && timeout 5";
            int whatsapp_result = ShellExecuteW(0, "open", "cmd.exe", final_whatsapp_command, NULL, 0);
            if (whatsapp_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute WhatsApp Python script. Error code: ", error_code);
                Comment("Failed to send message: " + message);
            } else {
                Print("Successfully executed WhatsApp Python script. Result code: ", whatsapp_result);
                Comment("Success message sent: " + message);
            }
    
            // Send to Telegram
            string telegram_script_path = "C:\\Users\\protech\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\send_telegram_message.py";
            string telegram_command = python_path + " \"" + telegram_script_path + "\" \"" + full_message + "\"";
            
            // Debugging: Print the command being executed for Telegram
            Print("Executing command to send Telegram message: ", telegram_command);
    
            // Use cmd.exe to execute the command and then wait for 5 seconds
            string final_telegram_command = "/c " + telegram_command + " && timeout 5";
            int telegram_result = ShellExecuteW(0, "open", "cmd.exe", final_telegram_command, NULL, 0);
            if (telegram_result <= 32) {
                int error_code = GetLastError();
                Print("Failed to execute Telegram Python script. Error code: ", error_code);
                Comment("Failed to send message: " + message);
            } else {
                Print("Successfully executed Telegram Python script. Result code: ", telegram_result);
                Comment("Success message sent: " + message);
            }
        }
    }
    
    
    //+------------------------------------------------------------------+
    //| 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));
       // Send test message on launch
       myAlert("info", "Thank you for subscribing. You shall be receiving Trend Constraint signal alerts via Whatsapp.");
       //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);
         }
       Comment("Indicator successfully launched.");
       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);
      }
    //+------------------------------------------------------------------+



    Prüfung der Auswirkungen der Kommentarfunktion

    Die Umsetzung der Kommentarfunktion in MQL5 ist eine einfache Möglichkeit, die Interaktivität und Formatierung von Handelscharts zu verbessern. Durch die Integration dieser Funktion können Sie den Händlern wichtige Echtzeit-Updates direkt auf ihren Charts zur Verfügung stellen und so ihr Handelserlebnis insgesamt verbessern. Mit dieser Funktion lassen sich dynamische Daten wie aktuelle Preise, Indikatorwerte und nutzerdefinierte Meldungen übersichtlich darstellen. Auf diese Weise können Händler fundiertere Entscheidungen treffen, ohne zwischen mehreren Fenstern oder externen Tools wechseln zu müssen.

    Die Kommentarfunktion ist aufgrund ihrer Nutzerfreundlichkeit und Flexibilität ein unschätzbares Werkzeug für die Entwicklung nutzerfreundlicher und effizienter Handelsalgorithmen. Durch die Einbindung kontextspezifischer Echtzeit-Informationen direkt in die Handelsoberfläche verbessert die Funktion das Situationsbewusstsein und rationalisiert den Handelsprozess, was zu einer effektiveren und zufriedeneren Nutzererfahrung beiträgt. Hier ist ein Bild, das den erfolgreichen Start von Trend Constraint V1.07 zeigt:

     



    Schlussfolgerung

    Bei der Softwareentwicklung entsteht Innovation oft durch die nahtlose Integration bestehender Lösungen, um robustere und funktionsreichere Anwendungen zu schaffen. In diesem Artikel wurde der Prozess der Zusammenführung von zwei Programmen zu einer einzigen, zusammenhängenden Einheit untersucht, um die Möglichkeiten der Kombination von Funktionen zur Verbesserung der Gesamtleistung und der Nutzerfreundlichkeit zu demonstrieren.

    Wir begannen damit, die Kernfunktionalitäten der beiden separaten Programme zu verstehen, die jeweils ihre eigenen Stärken haben. Durch eine sorgfältige Analyse ihrer Codebasen und die Identifizierung von Synergieeffekten haben wir sie erfolgreich zu einem einheitlichen Programm zusammengeführt. Dieser Zusammenschluss hat nicht nur die Abläufe gestrafft, sondern auch Redundanzen und potenzielle Konflikte verringert und damit den Weg für eine effizientere Ausführung geebnet.

    Darüber hinaus hat die Einbindung der Kommentarfunktion in das MQL5-Programm unserer kombinierten Anwendung eine neue Dimension verliehen. Durch die Nutzung des robusten Warnsystems von MQL5 haben wir eine Funktion implementiert, die Echtzeit-Benachrichtigungen über verschiedene Kanäle, einschließlich WhatsApp und Telegram, ermöglicht. Durch diese Verbesserung wird sichergestellt, dass die Nutzer stets über kritische Ereignisse informiert sind, wodurch die Reaktionsfähigkeit und die Entscheidungsfindung verbessert werden.

     Die Möglichkeiten für weitere Verbesserungen und Anpassungen sind enorm und laden zu kontinuierlicher Verbesserung und Innovation ein. Durch den Ausbau bestehender Technologien und die durchdachte Integration neuer Funktionen können wir leistungsstarke Tools entwickeln, die die Effizienz steigern, die Nutzerfreundlichkeit erhöhen und letztlich zu besseren Ergebnissen führen.

    Siehe angehängte Dateien unten. Kommentare und Meinungen sind immer willkommen.

    Anhänge Beschreibung
    Trend Constraint V1.07.mq5 Integration von zwei Plattformen in ein Programm.
    Trend Constraint V1.08.mq5
    Einbindung der Befehlsfunktion.
    Send_telegram_message.py Skript zum Senden von Telegram-Nachrichten.
    send_whatsapp_message.py Skript zum Versenden von WhatsApp-Nachrichten.

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

    Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
    In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
    Datenwissenschaft und ML (Teil 26): Der ultimative Kampf der Zeitreihenprognosen — LSTM vs. GRU Neuronale Netze Datenwissenschaft und ML (Teil 26): Der ultimative Kampf der Zeitreihenprognosen — LSTM vs. GRU Neuronale Netze
    Im vorigen Artikel haben wir ein einfaches RNN besprochen, das trotz seiner Unfähigkeit, langfristige Abhängigkeiten in den Daten zu verstehen, in der Lage war, eine profitable Strategie zu entwickeln. In diesem Artikel werden sowohl das Long-Short Term Memory (LSTM) als auch die Gated Recurrent Unit (GRU) behandelt. Diese beiden wurden eingeführt, um die Unzulänglichkeiten eines einfachen RNN zu überwinden und es zu überlisten.
    Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
    In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
    SP500 Handelsstrategie in MQL5 für Anfänger SP500 Handelsstrategie in MQL5 für Anfänger
    Entdecken Sie, wie Sie MQL5 nutzen können, um den S&P 500 mit Präzision zu prognostizieren, indem Sie die klassische technische Analyse für zusätzliche Stabilität einbeziehen und Algorithmen mit bewährten Prinzipien für robuste Markteinblicke kombinieren.