2026-10-21 16:07:10 +08:00
//+------------------------------------------------------------------+
//| SignalAlerts.mqh |
//| Copyright 2026, Allan Niñal |
//| https://www.allanninal.dev/mql5 |
//+------------------------------------------------------------------+
//| MT4 edition of the shared alert helper: one alert per closed-bar |
//| signal (pop-up, sound, push, e-mail), never during the history |
//| load, never twice for the same bar, silent in the tester. |
//+------------------------------------------------------------------+
// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0 (see LICENSE)
# property strict
2026-10-31 14:28:52 +08:00
# include <ChartKit/CkDebug.mqh>
2026-10-21 16:07:10 +08:00
input bool InpAlertPopup = true ; // Pop-up alert
input bool InpAlertSound = false ; // Play a sound
input string InpSoundFile = " alert.wav " ; // Sound file (terminal Sounds folder)
2026-10-31 14:28:52 +08:00
input bool InpAlertPush = true ; // Push notification (set up MetaQuotes ID in Options)
2026-10-21 16:07:10 +08:00
input bool InpAlertEmail = false ; // E-mail (set up in Options)
2026-10-31 14:28:52 +08:00
input bool InpDebug = false ; // Debug log for bug reports (Experts tab)
2026-10-21 16:07:10 +08:00
datetime g_alert_last = 0 ; // bar time of the last alert sent
//--- chart timeframe as text (M15, H1, ...)
string TfName ( )
{
switch ( _Period )
{
case PERIOD_M1 : return ( " M1 " ) ;
case PERIOD_M5 : return ( " M5 " ) ;
case PERIOD_M15 : return ( " M15 " ) ;
case PERIOD_M30 : return ( " M30 " ) ;
case PERIOD_H1 : return ( " H1 " ) ;
case PERIOD_H4 : return ( " H4 " ) ;
case PERIOD_D1 : return ( " D1 " ) ;
case PERIOD_W1 : return ( " W1 " ) ;
case PERIOD_MN1 : return ( " MN1 " ) ;
}
return ( " M " + IntegerToString ( _Period ) ) ;
}
//--- send one alert for a signal on the closed bar `bar_time`; `live` is false while the history is loading
void SignalAlert ( const string product , const string text , const datetime bar_time , const bool live )
{
if ( ! live | | bar_time < = g_alert_last | | IsTesting ( ) )
2026-10-31 14:28:52 +08:00
{
CkDbg ( StringFormat ( " signal not alerted (%s): %s on bar %s " , ! live ? " history loading " : ( bar_time < = g_alert_last ? " bar already alerted " : " tester " ) , text , TimeToString ( bar_time ) ) ) ;
2026-10-21 16:07:10 +08:00
return ;
2026-10-31 14:28:52 +08:00
}
CkDbg ( " alert: " + text + " on bar " + TimeToString ( bar_time ) ) ;
2026-10-21 16:07:10 +08:00
g_alert_last = bar_time ;
string msg = StringFormat ( " %s %s %s: %s " , product , _Symbol , TfName ( ) , text ) ;
if ( InpAlertPopup )
Alert ( msg ) ;
if ( InpAlertSound & & InpSoundFile ! = " " )
PlaySound ( InpSoundFile ) ;
if ( InpAlertPush & & TerminalInfoInteger ( TERMINAL_NOTIFICATIONS_ENABLED ) )
SendNotification ( msg ) ;
if ( InpAlertEmail & & TerminalInfoInteger ( TERMINAL_EMAIL_ENABLED ) )
SendMail ( product + " " + _Symbol , msg ) ;
}
//+------------------------------------------------------------------+