Alert(), SendMail(), SendNotification(), PlaySound(): One Helper for MT4's Four Alert Channels

Alert(), SendMail(), SendNotification(), PlaySound(): One Helper for MT4's Four Alert Channels

21 October 2026, 10:22
Boris Armenteros
0
25

MT4 gives an indicator or an Expert Advisor four ways to tell the trader that something happened: a pop-up alert, an email, a push notification and a plain sound. Each one is a single function call. Whether the trader actually hears about the event depends on what surrounds that call: the terminal settings it needs, the return value it hands back, and how often the code calls it.

What each channel does

Alerts matter because they let a trader follow an event without watching the market. With alerts added to an indicator, one trader can follow several symbols and timeframes at once, without even sitting in front of the computer. MT4 offers four types:

  • Pop-up alert, the most used: Alert() opens a window with a text message and, unless that is disabled, also plays a sound. Both the text and the sound can be customised. Someone has to be near the computer to see the window or hear the sound.
  • Email: SendMail() sends the message to the trader's email address, so it reaches them wherever they can read their mail.
  • Push notification: SendNotification() sends the message to the trader's smartphone or other mobile device running the terminal.
  • Sound: PlaySound() plays a custom sound and shows no text, so again someone has to be close enough to hear it.

What each call needs before it works

Three of the four depend on something outside the code, and the documentation spells out each dependency.

SendMail() sends to the address set on the Email tab of the terminal's settings. Sending can be disabled there, or the address left empty. It returns true when the email is put into the send queue, so a true means queued, not delivered.

SendNotification() sends to the MetaQuotes IDs set on the Notifications tab. The text may not exceed 255 characters. On failure it returns false, and GetLastError() names the reason: 4250 (send failed), 4251 (wrong parameter), 4252 (wrong settings) or 4253 (too frequent). The last one matters most, because the function allows no more than 2 calls per second and 10 calls per minute, and the terminal can disable it when a program breaks that limit.

PlaySound() plays only WAV files, and only from the terminal's Sounds folder or a sub-folder of it. It returns false when the file is not found.

Alert() has no return value, so there is nothing to check.

One helper that reports what failed

Calling the four functions from one place keeps the checks in one place too. The helper below sends to every channel the user switched on, and writes a line to the Experts log whenever a channel reports a failure.

// Channels the user can switch on in the inputs
input bool   UsePopup  = true;         // Pop-up alert
input bool   UseEmail  = false;        // Email
input bool   UsePush   = false;        // Push notification
input bool   UseSound  = false;        // Sound
input string SoundFile = "alert.wav";  // Sound file (WAV, in the terminal's Sounds folder)

void SendSignalAlert(const string text)
{
   string msg = Symbol() + " M" + IntegerToString(Period()) + ": " + text;

   if(UsePopup)
      Alert(msg);                              // no return value to check

   if(UseEmail)
   {
      ResetLastError();
      if(!SendMail("Signal on " + Symbol(), msg))
         PrintFormat("SendMail failed, error %d", GetLastError());
   }

   if(UsePush)
   {
      ResetLastError();
      if(!SendNotification(StringSubstr(msg, 0, 255)))
         PrintFormat("SendNotification failed, error %d", GetLastError());
   }

   if(UseSound && !PlaySound(SoundFile))
      PrintFormat("PlaySound: %s not found in the Sounds folder", SoundFile);
}

StringSubstr(msg, 0, 255) keeps the push text inside the 255-character limit. A 4252 in the log points at the Notifications tab, not at the code, and a 4253 points at the call rate, which is the next point.

Once per bar, not once per tick

An indicator's OnCalculate() usually runs when a new tick arrives, and an EA's OnTick() runs on every new tick (event handlers). A condition that stays true for the whole bar would therefore call SendNotification() on every tick, and any minute with more than ten ticks would break the 10-per-minute limit. A guard on the bar's open time stops that:

datetime lastAlertBar = 0;   // open time of the bar that last sent an alert

void AlertOncePerBar(const string text)
{
   if(Time[0] == lastAlertBar)
      return;                  // this bar has already alerted

   lastAlertBar = Time[0];
   SendSignalAlert(text);
}

Time[0] is the open time of the current bar, so the message goes out at most once per bar, however many ticks keep the condition true.

None of the four works in the Strategy Tester

The documentation of all four functions says the same thing: they do not work in the Strategy Tester. A backtest therefore says nothing about the alert path. Test it on a demo chart with every channel switched on, and read the Experts log for the lines the helper writes.

The same calls in MQL5

The four functions keep their names in MQL5. SendMail() and SendNotification() are documented there under Network functions, and Alert() and PlaySound() under Common functions.

The original post, with the four alert types and where traders often use them, is on barmenteros.com: MT4 Alerts and Notifications.