Building A Candlestick Trend Constraint Model (Part 5): Notification System (Part I)
Contents
- Introduction
- Terminal notifications
- Push notifications
- Email notifications
- Debugging Trend Constraint V1.04
- Integrating the social network channels (e.g. Telegram, and WhatsApp)
- Telegram Integration
- WhatsApp Integration
- The power of virtual private network (VPS) on our notification system
- Conclusion
Introduction
MetaTrader 5 provides various notification options for informing users about trading events, such as terminal, email, and push notifications. Integrating it with social platforms like Telegram and WhatsApp for signal sharing can be highly beneficial. Configuring notifications in MetaTrader 5 enables you to stay informed about your trading activities regardless of your location. By utilizing the aforementioned notification access methods, you can select the option that best fits your requirements. This guide will walk you through the setup and customization of MetaTrader 5 notifications, including integration with Telegram and other social media platforms. It will focus on configuration details and the initial steps for integration, paving the way for a more in-depth exploration in Part II of this series.
Terminal notifications
Terminal notifications are internal alerts in the MetaTrader 5 platform. They cover all alert events triggered within MetaTrader 5. You can manually set alerts in MetaTrader 5 to trigger when specific conditions are met. Alert settings are typically found in the tools tab at the bottom of the default MetaTrader 5 window.
- Symbol: Select the trading instrument for which you want to set the alert.
- Condition: Choose the condition that will trigger the alert (e.g., Bid >, Ask <, Time =, etc.).
- Value: Specify the value that the condition will be compared against (e.g., a specific price level).
- Source: Select the type of alert (e.g., Sound, File, Mail, etc.). For terminal notifications, you can choose Sound.
- Action: Select the action to be taken when the alert is triggered (e.g., play a sound, send a notification, etc.).
- Sound: Choose a sound file to be played when the alert is triggered.
- Timeout: Set the time interval after which the alert will be checked again.
- Maximum Iterations: Specify the number of times the alert should be triggered.
Below is an example of setting up an alert using Step Index synthetics. The values shown in the table can be adjusted based on your needs. After configuring the settings, click Ok to create the alert and it will be ready for activation. See the animated demonstration image below the table for a quick summary. To begin, right-click on the alert tab in the tools window, select create from the menu that appears, and a dialogue box with the settings outlined in the table will open.
Setting | Value |
---|---|
Symbol | Step Index |
Condition | Bid> |
Value | 9666 |
Source | Sound |
Action | Selected a sound file ( alert2.wav) |
Timeout | Set to 60 seconds |
Maximum Iterations | Set to 5 |
Push notifications
It is a feature in MetaTrader 5 which allows notifications generated on platform whether generated internally or by an indictor or an expert advisor to be send to a mobile phone MetaTrader 5 platform via the MetaQuotes ID of the mobile device. For mobile device to receive push notification MetaTrader 5 must be installed from playstore for Android or apple store for IOS. On desktop MetaTrader 5 push notifications must be enabled for alert to be received on mobile phone. A unique MetaQuotes ID is created on mobile phone soon after installation of mobile MetaTrader 5.
On the left, you can find an image illustrating how to find the MetaQuotes ID. On the right, there is an image demonstrating how to activate push notifications on the desktop MetaTrader 5 platform, along with the field for entering the MetaQuotes ID. By checking the box and entering the ID from your mobile platform, you can instantly begin receiving notifications in the messages section of your MetaTrader 5 mobile platform. You can add many MetaQuotes IDs from various mobile devices seperating them
Email notifications
Email remains a powerful and versatile tool for communication due to its convenience, efficiency, and wide range of functionalities. Whether for personal use, business correspondence, or professional networking, email provides a reliable and effective means of staying connected and exchanging information. Setting up email notifications in MetaTrader 5 allows you to receive alerts via email for various trading activities, such as price movements, order executions, and custom events.
The advantage of emails is their nearly instantaneous delivery, enabling swift information exchange and efficient dissemination to large groups. Email services often provide encryption to secure content, protecting sensitive information. Direct delivery to recipient inboxes minimizes interception risks compared to other communication forms.
Here is a step by step guide for setting up email notifications:
- Launch the MetaTrader 5 platform on your computer.
- Go to Tools > Options > Email.
- Check the box Enable.
- Fill in SMTP Server Details:
Setting Fill in details SMTP server The SMTP server address for your email provider (e.g., smtp.gmail.com for Gmail). SMTP login Your email address (e.g., your-email@gmail.com). SMTP password Your email password or app-specific password if using Gmail. From Your email address (e.g., your-email@gmail.com). To The email address where you want to receive notifications (can be the same as the From address or different).
What is SMTP server.
Based on my research, an Simple Mail Transfer Protocol (SMTP) server is a mail server that utilizes the (SMTP) protocol to send, receive, and relay outgoing emails. It functions alongside the Mail Transfer Agent (MTA) to direct emails from the sender's email client to the recipient's email server. Here is a list of mail providers with SMTP servers:
- gmail
- yahoo mail
- hotmail
- zohomail
- icloud mail
Debugging Trend Constraint V1.04
We have successfully integrated the Draw_Line style into our system's trends. However, I discovered that numerous alerts were being triggered after each bar due to this new feature. For instance, when a chart was set to a minute timeframe, alerts were being generated at every minute candle close, which is quite overwhelming.
Our aim is to obtain optimal signals, focusing on only a select few. To tackle this issue, I have contemplated resolving the matter by removing myalert() from the fifth and sixth buffers. It is essential that this code is rectified for the seamless integration of Telegram and WhatsApp as discussed in this article. Below is the revised version of our code:
Buffer 5 Modified:
// --- Buffer5 (Buy Trend) if(MA5[i] > MA6[i]) { Buffer5[i] = Low[i] - 15 * myPoint; // Disabled myAlert from Buffer 5 // myAlert("indicator", "BUY TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2)); }
Buffer 6 Modified:
// --- Buffer6 (Sell Trend) if(MA5[i] < MA6[i]) { Buffer6[i] = High[i] + 15 * myPoint; // Disabled myAlert from Buffer 6 // myAlert("indicator", "SELL TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2)); }
Trend Constraint V1.04 modified:
///Indicator Name: Trend Constraint #property copyright "Clemence Benjamin" #property link "https://mql5.com" #property version "1.04" #property description "A model that seek to produce sell signal when D1 candle is Bearish only and buy signal 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 Trend" #property indicator_type6 DRAW_LINE #property indicator_style6 STYLE_SOLID #property indicator_width6 2 #property indicator_color6 0x0000FF #property indicator_label6 "Sell Trend" #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[]; void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); } else if(type == "order") { } else if(type == "modify") { } else if(type == "indicator") { if(Audible_Alerts) Alert(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+message); if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.04 @ "+Symbol()+","+IntegerToString(Period())+" | "+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)); //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); } 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[]; int RSIBuffer; int MABuffer; int RSIPeriod = 14; ArrayResize(RSI, rates_total); ArrayResize(Open, rates_total); ArrayResize(Close, rates_total); CopyOpen(NULL, 0, 0, rates_total, Open); CopyClose(NULL, 0, 0, rates_total, Close); if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) < 0) { Print("Getting RSI values failed, not enough bars!"); } ArrayResize(MA, rates_total); if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) < 0) { Print("Getting MA values failed, not enough bars!"); } ArrayResize(MA2, rates_total); if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) < 0) { Print("Getting MA values failed, not enough bars!"); } ArrayResize(MA3, rates_total); if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) < 0) { Print("Getting MA values failed, not enough bars!"); } ArrayResize(MA4, rates_total); if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) < 0) { Print("Getting MA values failed, not enough bars!"); } ArrayResize(Low, rates_total); if(CopyLow(NULL, 0, 0, rates_total, Low) < 0) { Print("Getting LOW values failed, not enough bars!"); } ArrayResize(High, rates_total); if(CopyHigh(NULL, 0, 0, rates_total, High) < 0) { Print("Getting HIGH values failed, not enough bars!"); } ArrayResize(MA5, rates_total); if(CopyBuffer(MA_handle5, 0, 0, rates_total, MA5) < 0) { Print("Getting MA values failed, not enough bars!"); } ArrayResize(MA6, rates_total); if(CopyBuffer(MA_handle6, 0, 0, rates_total, MA6) < 0) { Print("Getting MA values failed, not enough bars!"); } for(int i=limit-1; i>=0; i--) { if(i < rates_total-1 && time[i] != time[i+1]+PeriodSeconds()) { continue; } Buffer1[i] = EMPTY_VALUE; Buffer2[i] = EMPTY_VALUE; Buffer3[i] = EMPTY_VALUE; Buffer4[i] = EMPTY_VALUE; Buffer5[i] = EMPTY_VALUE; Buffer6[i] = EMPTY_VALUE; // --- Indicator calculations // --- Buffer1 (Buy) if((Close[i] > MA[i] && MA[i] > MA2[i] && RSI[i] < Oversold) || (RSI[i] < Oversold && Close[i] > MA3[i])) { Buffer1[i] = Low[i] - 5 * myPoint; myAlert("indicator", "BUY OPPORTUNITY | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2)); } // --- Buffer2 (Sell) if((Close[i] < MA[i] && MA[i] < MA2[i] && RSI[i] > Overbought) || (RSI[i] > Overbought && Close[i] < MA3[i])) { Buffer2[i] = High[i] + 5 * myPoint; myAlert("indicator", "SELL OPPORTUNITY | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2)); } // --- Buffer3 (Buy Reversal) if(RSI[i] < Oversold && Close[i] > MA[i]) { Buffer3[i] = Low[i] - 10 * myPoint; myAlert("indicator", "BUY REVERSAL | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2)); } // --- Buffer4 (Sell Reversal) if(RSI[i] > Overbought && Close[i] < MA[i]) { Buffer4[i] = High[i] + 10 * myPoint; myAlert("indicator", "SELL REVERSAL | RSI: " + DoubleToString(RSI[i], 2) + " | MA: " + DoubleToString(MA[i], 2)); } // --- Buffer5 (Buy Trend) if(MA5[i] > MA6[i]) { Buffer5[i] = Low[i] - 15 * myPoint; //Disabled myAlert from Buffer 5 // myAlert("indicator", "BUY TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2)); } // --- Buffer6 (Sell Trend) if(MA5[i] < MA6[i]) { Buffer6[i] = High[i] + 15 * myPoint; // Disabled myAlert from Buffer 6 // myAlert("indicator", "SELL TREND | MA Fast: " + DoubleToString(MA5[i], 2) + " | MA Slow: " + DoubleToString(MA6[i], 2)); } } return(rates_total); }
Integrating the social network (e.g. Telegram and WhatsApp )
This article section will show the integration of Telegram and WhatsApp on MetaTrader 5 specifically for our Trend Constraint indicator. This process significantly boosts MetaTrader 5's capabilities by offering real-time, secure, and convenient notifications. These integrations enhance the efficiency, responsiveness, and effectiveness of trading activities, serving as valuable tools for traders today. With a vast user base on these platforms, sharing signals with these communities can be beneficial. Let's delve into how we can transmit the signals generated by our indicator to social media platforms. I have conducted research and tested this to confirm its functionality.
Requirements:
- latest MetaTrader5 platform desktop.
- Verified Whatsapp and Telegram accounts (download from playstore for android and app store for IOS).
- Web browser e.g. Google Chrome.
- Server for hosting middleware scripts.
Telegram Integration
Step 1: Create a Telegram Bot
Create the Bot:
- Open Telegram and search for the "BotFather" bot.
- Start a chat with BotFather and use the /newbot command to create a new bot.
- Follow the prompts to set a name and username for your bot.
- BotFather will provide a token, which you will use to interact with the Telegram API.
Get Chat ID:
- Add your bot to a Telegram group or start a chat with it.
- Use the following URL in your browser to get updates and find your chat ID: https://api.telegram.org/bot<YourBotToken>/getUpdates
- Send a message in the chat and check the URL again to find the chat ID.
For a more comprehensive guide on getting a Chat ID visit Github
Step 2: Create a Middleware Script
You need a script to send messages via Telegram's API.
To create a middleware script we are going to use Python language according to the research that I did. This Python script uses the requests library to send a message to a Telegram chat via a bot. Here is an explanation of each line of the script:
import requests
Imports the requests library used to make HTTP requests in Python. In this script, it will be used to send a POST request to the Telegram Bot API.
def send_telegram_message(chat_id, message, bot_token):
Defines a function named send_telegram_message: This function takes three parameters:
- chat_id: The unique identifier for the target chat or username of the target channel.
- message: The text message to be sent.
- bot_token: The token for the Telegram bot, which is provided by @BotFather when creating the bot.
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
This line constructs the URL for the Telegram Bot API method sendMessage using the provided bot_token.
payload = { 'chat_id': chat_id, 'text': message }
Creates the payload for the POST request. This dictionary contains the parameters required by the sendMessage method:
- chat_id: The ID of the chat where the message will be sent.
- text: The content of the message.
response = requests.post(url, data=payload)
This line sends the HTTP POST request to the constructed URL with the payload data using the requests.post method. The response from the API is stored in the response variable.
return response.json()
This line converts the response to JSON format and returns it. This JSON response typically contains information about the sent message, including message ID, sender, chat details, and more.
Combining all the pieces of code together here is what we get:
import requests def send_telegram_message(chat_id, message, bot_token): url = f"https://api.telegram.org/bot{bot_token}/sendMessage" payload = { 'chat_id': chat_id, 'text': message } response = requests.post(url, data=payload) return response.json()
Step 3: Configure MetaTrader 5 to Use the Middleware
Create an MQL5 script to send alerts via HTTP requests to your middleware script
Lets go through the breakdown of the code and gain an understanding each line:
void SendTelegramMessage(string chat_id, string message, string bot_token)
Defines a function named SendTelegramMessage.
Parameters within the function:
- chat_id: A string representing the Telegram chat ID where the message will be sent.
- message: A string containing the message to be sent.
- bot_token: A string representing the bot token required for authorization with the Telegram API.
{ string url = "http://your-server-url/send_telegram_message";
Assigns the server endpoint URL to the variable url. This URL is the address of the server that handles forwarding the message to Telegram.
char postData[]; StringToCharArray("chat_id=" + chat_id + "&message=" + message + "&bot_token=" + bot_token, postData);
postData Array:
- Declaration: Declares an array postData of type char to hold the POST request data.
- String to Char Array Conversion: Converts a concatenated string of the chat_id, message, and bot_token parameters into a character array and stores it in postData. The concatenated string forms the body of the POST request in the format required by the server.
char result[];
Declares an array result of type char to hold the response from the web request.
int res = WebRequest("POST", url, "", NULL, 0, postData, 0, result, NULL);
Web Request:
- HTTP Method: "POST" indicates the request type.
- URL: url is the endpoint to send the request.
- Headers: An empty string "" means no additional headers.
- Cookies: NULL indicates no cookies.
- Timeout: 0 specifies no timeout.
- Post Data: postData is the data to be sent in the POST request.
- Result: result is where the response will be stored.
- The function returns an integer res which is the HTTP status code of the response.
if (res != 200)
Check Response Code: Compares the response code res to 200 (HTTP OK). If it is not 200, it indicates an error.
Error Handler:
{ Print("Error sending message: ", GetLastError()); }
Print Error Message: If the response code is not 200, this block prints an error message along with the last error code using GetLastError().
Success Handler:
else { Print("Message sent successfully."); }
Print Success Message: If the response code is 200, this block prints a success message indicating the message was sent successfully.
This line ends the SendTelegramMessage function with closing brace.
MQL5 Code Sending Telegram Messages:
void SendTelegramMessage(string chat_id, string message, string bot_token) { string url = "http://your-server-url/send_telegram_message"; char postData[]; StringToCharArray("chat_id=" + chat_id + "&message=" + message + "&bot_token=" + bot_token, postData); char result[]; int res = WebRequest("POST", url, "", NULL, 0, postData, 0, result, NULL); if (res != 200) { Print("Error sending message: ", GetLastError()); } else { Print("Message sent successfully."); } }
This MQL5 script above is designed to send a message to a Telegram chat by making a web request to a server endpoint. The example usage shows how to use the SendTelegramMessage function within the OnStart event, which runs when the script is initiated. We look at WhatsApp integration in next section below and every we have explained the integration of telegram makes sense even when it is now a different social platform. Always remember to put substitute some part of the code with your actual credentials for them to work.
WhatsApp Integration
Step 1: Register with a Messaging API Provider.
- Choose a Provider: Twilio is a popular choice for WhatsApp integration.
- Create an Account: Sign up for Twilio and complete any necessary verification.
- Obtain API Credentials: Get your API credentials (account SID, auth token) from Twilio.
Step 2: Create a Middleware Script.
Middleware Python Script For WhatsApp Integration:
import requests def send_whatsapp_message(to, message, account_sid, auth_token): url = f"https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json" payload = { 'From': 'whatsapp:+14155238886', # Twilio sandbox number 'To': f'whatsapp:{to}', 'Body': message } headers = { 'Authorization': f'Basic {account_sid}:{auth_token}' } response = requests.post(url, data=payload, headers=headers) return response.json()
Step 3: Configure MetaTrader 5 to Use the Middleware
MQL5 code send WhatsApp Notifications:
void SendWhatsAppMessage(string to, string message, string account_sid, string auth_token) { string url = "http://your-server-url/send_whatsapp_message"; char postData[]; StringToCharArray("to=" + to + "&message=" + message + "&account_sid=" + account_sid + "&auth_token=" + auth_token, postData); char result[]; int res = WebRequest("POST", url, "", NULL, 0, postData, 0, result, NULL); if (res != 200) { Print("Error sending message: ", GetLastError()); } else { Print("Message sent successfully."); } }
The Power of Virtual Private Service(VPS) on our notification system
A Virtual Private Service operates continuously without downtime, ensuring your MetaTrader 5 platform and notification systems are always active. This is critical for receiving real-time notifications without interruptions. VPS providers offer robust and stable internet connections, reducing the risk of disconnections that can occur with home or office networks. VPS servers are often located in data centers with high-speed connections to major financial exchanges, reducing latency and improving the speed at which trading alerts and notifications are received and acted upon. Unlike shared hosting, a VPS provides dedicated CPU, RAM, and storage resources, ensuring consistent performance for running MetaTrader 5 and handling notifications. A VPS can be accessed remotely from any device with an internet connection, allowing you to manage your MetaTrader 5 platform and receive notifications from anywhere.
Conclusion
We have successfully configured a robust notification system for our indicator, laying the groundwork for WhatsApp and Telegram integration. This enhancement is pivotal in attracting a large community, as these signals can be instantly shared. Developers can capitalize through marketing these signals to interested traders through these popular platforms, offering a swift and efficient means of transmission directly from the platform to social media channels.
This approach ensures signal accessibility anytime, anywhere with internet access, allowing for easy sharing with just a click. Traders can conveniently choose between Telegram or WhatsApp for signal access. Further integration details will be explored in Part II. Please find the reference files attached below. Feel free to engage in discussions in the comments section.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use