AudioAlerts20090201

Download script
Author: Copyright � 2009 Robert Dee
AudioAlerts20090201

This software is an automated monitoring tool designed for MetaTrader 4 to provide real-time visual and audio notifications based on specific market conditions. It simplifies the process of watching complex technical indicators by identifying specific "Buy" and "Sell" signals automatically.

Core Signal Logic

The script monitors the market using a combination of three primary technical tools:

  • MACD: Measures momentum to determine if price movement is accelerating.
  • Stochastics: Identifies whether an asset is "overbought" (potentially ready to drop) or "oversold" (potentially ready to rise).
  • Exponential Moving Averages (EMA): Tracks the average price over a short period to help identify the immediate trend direction.

The script offers two different levels of sensitivity for these signals:

  1. Basic Force Alerts: This is a more conservative mode. It requires the market to first enter an extreme "oversold" or "overbought" state before it will trigger a notification. It ensures that signals are only generated when the price has moved significantly far from its recent average.
  2. Advanced Force Alerts: This is a more aggressive mode. It provides notifications more frequently by ignoring the extreme overbought/oversold restrictions and focusing primarily on the relationship between momentum, moving averages, and stochastic crossovers.

Interactive Features

Beyond automated technical analysis, the script includes two specific manual monitoring features:

  • Line Alerts: If you manually draw trend lines or horizontal support/resistance lines on your chart, the script can monitor the price for you. It will trigger an alert whenever the live price touches these specific lines (within a small 1-pip margin).
  • Visual Feedback: The script can be configured to physically alter the chart by drawing arrows pointing up or down at signal locations and highlighting the bodies of the candles where the signals occurred, allowing for easy visual confirmation of past activity.

Notification System

To ensure you don't miss a signal, the tool uses a multi-layered notification system:

  • Pop-up Windows: On-screen alerts appear immediately when a condition is met.
  • Audio Alerts: The script can play a specific sound file (customizable) to grab your attention. It includes a repeating feature that can play the sound multiple times in succession.
  • Expert Logs: It prints a status message in the "Experts" tab of the platform, providing a running log of what the system is detecting (e.g., "BasicForceBUY," "OSReset," or "NO ALERTS").
Indicators Used
MACD HistogramStochastic oscillatorMoving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt plays sound alerts
11 Views
0 Downloads
0 Favorites
AudioAlerts20090201
//+-----------------------------------------------------+
//| INDICATOR                          AudioAlerts.mq4  |
//| copy to [experts\indicators] and recompile          |
//| status messages printed in Experts tab of terminal  |
//+-----------------------------------------------------+
//| This is free experimental software.                 |
//| No guarantees are expressed or implied.             |
//| Feedback welcome via Forex Factory private message. |
//+-----------------------------------------------------+
#property copyright "Copyright © 2009 Robert Dee"
#property link      "www.forexfactory.com/member.php?u=12983"

#define INDICATOR_VERSION    20090201
#define INDICATOR_NAME       "AudioAlerts"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 DarkBlue  // BUY alert arrows
#property indicator_color2 Red       // SELL alert arrows
#property indicator_color3 DarkBlue  // BULLISH signal candle body
#property indicator_color4 Red       // BEARISH signal candle body
#property indicator_width1 5
#property indicator_width2 5
#property indicator_width3 3
#property indicator_width4 3

extern bool   BasicForceAlerts    = True;         // macd + stochastics + emas (includes all stoch OB & OS restrictions)
extern bool   AdvancedForceAlerts = True;         // macd + stochastics + emas (ignores stoch OB & OS restrictions also ignores divergence)
extern bool   LineAlerts          = False;        // when price touches a line (any trend line or horizontal line object on the price chart)
extern bool   AlertPopups         = True;         // enable alert popup window
extern string AlertSoundFile      = "alert2.wav"; // the WAV file must be located in the MT4\sounds folder, ("" = empty = disable sounds)
extern int    AlertSoundRepeats   = 3;            // number of times the WAV file will be repeated after the first alert sound
extern bool   ShowChartArrows     = False;        // printing of alert arrows on the price chart (default = disabled)
extern bool   PaintSignalCandles  = True;         // painting of signal candle bodies on the price chart (default = disabled)

//---- global vars
int      LastAlert, AlertSoundCount; 
bool     osreset, obreset;
datetime signalcandletime, lastcandletime, lastlinealert;
double   BuyAlerts[];
double   SellAlerts[];
double   CandleBodyLow[];
double   CandleBodyHigh[];

int lastsignal;
#define NONE         0
#define BASICBUY     1
#define BASICSELL    2
#define ADVANCEDBUY  3
#define ADVANCEDSELL 4

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
if(ShowChartArrows == True) SetIndexStyle(0,DRAW_ARROW); else SetIndexStyle(0,DRAW_NONE);
SetIndexArrow(0,SYMBOL_ARROWUP);
SetIndexEmptyValue(0,0);
if(ShowChartArrows == True) SetIndexStyle(1,DRAW_ARROW); else SetIndexStyle(1,DRAW_NONE);
SetIndexArrow(1,SYMBOL_ARROWDOWN);
SetIndexEmptyValue(1,0);
if(PaintSignalCandles == True) {SetIndexStyle(2,DRAW_HISTOGRAM); SetIndexStyle(3,DRAW_HISTOGRAM);}
SetIndexBuffer(0,BuyAlerts);
SetIndexBuffer(1,SellAlerts);
SetIndexBuffer(2,CandleBodyLow);
SetIndexBuffer(3,CandleBodyHigh);
IndicatorDigits(Digits);
IndicatorShortName(INDICATOR_NAME);
SetIndexLabel(0,"");
SetIndexLabel(1,"");
SetIndexLabel(2,"");
SetIndexLabel(3,"");
// cleanup buffers
int i = 0;
while(i < Bars)
   {
   BuyAlerts[i] = 0;
   SellAlerts[i] = 0;
   CandleBodyLow[i] = 0;
   CandleBodyHigh[i] = 0;
   i++;
   }
Print("version "+INDICATOR_VERSION+" Copyright © 2009 Robert Dee");   
}

//+------------------------------------------------------------------+
//| Paints the candle body at position (shift) using a histogram
//+------------------------------------------------------------------+
void PaintCandleBody(int shift)
{
CandleBodyLow[shift]  = Close[shift];
CandleBodyHigh[shift] = Open[shift];
}

//+------------------------------------------------------------------+
//| Indicator start() function called every time price changes (tic)
//+------------------------------------------------------------------+
int start()
{
int    count;
int    multi       = MathPow(10,Digits);               // calc multiplier for this currency
int    daycandles  = (3600*24)/(Time[0]-Time[1]);      // candles per day in this timeframe
int    spread = MarketInfo(Symbol(),MODE_SPREAD);      // spread for this pair
double macd1, macd2, stoch1, stoch2, stochsig1, stochsig2, oema5, cema5, objvalue;
string objname, objdesc, msg;

// find starting position at beginning of chart
int shift;
int limit;
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
shift = limit;
while(shift >= 0)
   {
   /////////////////////////////
   // DATA from CLOSED CANDLES
   macd1     = iMACD(NULL,0,12,26,1,PRICE_CLOSE,MODE_MAIN,shift+1);
   macd2     = iMACD(NULL,0,12,26,1,PRICE_CLOSE,MODE_MAIN,shift+2);
   stoch1    = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,shift+1);
   stoch2    = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,shift+2);
   stochsig1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,shift+1);
   stochsig2 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,shift+2);
   oema5     = NormalizeDouble(iMA(NULL,0,5,0,MODE_EMA,PRICE_OPEN,shift+1),Digits);
   cema5     = NormalizeDouble(iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,shift+1),Digits);
   
   //////////////////////////////////
   // BASIC FORCE STOCH RESET RULES
   if(stoch1 < 20 && stochsig1 < 20) {osreset = True; obreset = False;} // oversold reset allows new BuyAlerts
   if(stoch1 > 80 && stochsig1 > 80) {obreset = True; osreset = False;} // overbought reset allows new SellAlerts
   if(lastsignal == BASICBUY  && cema5 < oema5) lastsignal = NONE;
   if(lastsignal == BASICSELL && cema5 > oema5) lastsignal = NONE;
   //if(lastsignal == ADVANCEDBUY  && cema5 < oema5) lastsignal = NONE;
   //if(lastsignal == ADVANCEDSELL && cema5 > oema5) lastsignal = NONE;

   /////////////////////////////////
   // BASIC FORCE BUY ALERT RULES
   if(BasicForceAlerts == True)
   if(osreset == True)
   if(macd1 > macd2)
   if(stoch1 >= stochsig1+1 && stoch1 > stoch2 && stoch1 > 20 && stoch1 < 80 && stochsig1 > 20)
   if(cema5 >= oema5+1*Point)   
      {
      BuyAlerts[shift] = Low[shift]-5*Point;
      if(PaintSignalCandles == True) PaintCandleBody(shift+1);
      osreset = False;
      lastsignal = BASICBUY;
      signalcandletime = Time[shift+1];
      }

   /////////////////////////////////
   // BASIC FORCE SELL ALERT RULES
   if(BasicForceAlerts == True)
   if(obreset == True)
   if(macd1 < macd2)
   if(stoch1 <= stochsig1-1 && stoch1 < stoch2 && stoch1 < 80 && stoch1 > 20 && stochsig1 < 80)
   if(cema5 <= oema5-1*Point)   
      {
      SellAlerts[shift] = High[shift]+5*Point;
      if(PaintSignalCandles == True) PaintCandleBody(shift+1);
      obreset = False;
      lastsignal = BASICSELL;
      signalcandletime = Time[shift+1];
      }

   ///////////////////////////////////
   // ADVANCED FORCE BUY ALERT RULES
   if(AdvancedForceAlerts == True)
   if(lastsignal != ADVANCEDBUY && lastsignal != BASICBUY)
   if(macd1 > macd2)
   if(stoch1 >= stochsig1+1 && stoch1 > stoch2 && stoch1 < 80)
   if(cema5 >= oema5+1*Point)   
      {
      BuyAlerts[shift] = Low[shift]-5*Point;
      if(PaintSignalCandles == True) PaintCandleBody(shift+1);
      osreset = False;
      lastsignal = ADVANCEDBUY;
      signalcandletime = Time[shift+1];
      }

   ///////////////////////////////////
   // ADVANCED FORCE SELL ALERT RULES
   if(AdvancedForceAlerts == True)
   if(lastsignal != ADVANCEDSELL && lastsignal != BASICSELL)
   if(macd1 < macd2)
   if(stoch1 <= stochsig1-1 && stoch1 < stoch2 && stoch1 > 20)
   if(cema5 <= oema5-1*Point)   
      {
      SellAlerts[shift] = High[shift]+5*Point;
      if(PaintSignalCandles == True) PaintCandleBody(shift+1);
      obreset = False;
      lastsignal = ADVANCEDSELL;
      signalcandletime = Time[shift+1];
      }

   shift--; // move forward one candle
   } // end of while() loop

/////////////////////
// LINE ALERT RULES
if(LineAlerts == True && lastlinealert != Time[0]) // only one line alert per candle
   {
   shift = ObjectsTotal()-1; // objects index starts at zero
   while(shift >= 0)
      {
      // get data from the object
      objname  = ObjectName(shift);
      objdesc  = ObjectDescription(objname); if(objdesc == "") objdesc = objname; objdesc = StringTrimLeft(objdesc);
      objvalue = NormalizeDouble(ObjectGetValueByShift(objname,0),Digits);
      if(ObjectType(objname) == OBJ_HLINE) objvalue = NormalizeDouble(ObjectGet(objname,OBJPROP_PRICE1),Digits);
      // line alert rules
      if(ObjectType(objname) == OBJ_TREND || ObjectType(objname) == OBJ_HLINE) // trend line or horizontal line
      if(Bid <= objvalue+1*Point && Bid >= objvalue-1*Point)                   // 1 pip above or below the line
         {
         Alert("Line Alert for '"+objdesc+"' at " + DoubleToStr(objvalue,Digits));
         PlaySound(AlertSoundFile);
         lastlinealert = Time[0];
         break;
         }
      shift--; // move to next object in the list
      }
    } // end of line alert while() loop

///////////////////////////////////////////////////////////////////////
// a status message is printed in the experts log for each new candle
if(lastcandletime != Time[0])
   {
   if(AlertPopups == True)
      {
      if(BuyAlerts[0] != 0  && lastsignal == BASICBUY)     {Alert("Basic Force BUY candle "+TimeToStr(signalcandletime,TIME_MINUTES));PlaySound(AlertSoundFile);}
      if(SellAlerts[0] != 0 && lastsignal == BASICSELL)    {Alert("Basic Force SELL candle "+TimeToStr(signalcandletime,TIME_MINUTES));PlaySound(AlertSoundFile);}
      if(BuyAlerts[0] != 0  && lastsignal == ADVANCEDBUY)  {Alert("Advanced Force BUY candle "+TimeToStr(signalcandletime,TIME_MINUTES));PlaySound(AlertSoundFile);}
      if(SellAlerts[0] != 0 && lastsignal == ADVANCEDSELL) {Alert("Advanced Force SELL candle "+TimeToStr(signalcandletime,TIME_MINUTES));PlaySound(AlertSoundFile);}
      }
   msg = "status";
   if(lastsignal == NONE) msg = msg + " NO ALERTS";
   if(lastsignal == BASICBUY) msg = msg + " BasicForceBUY " +TimeToStr(signalcandletime,TIME_MINUTES);
   if(lastsignal == BASICSELL) msg = msg + " BasicForceSELL " +TimeToStr(signalcandletime,TIME_MINUTES);
   if(lastsignal == ADVANCEDBUY) msg = msg + " AdvancedForceBUY " +TimeToStr(signalcandletime,TIME_MINUTES);
   if(lastsignal == ADVANCEDSELL) msg = msg + " AdvancedForceSELL " +TimeToStr(signalcandletime,TIME_MINUTES);
   if(osreset == True) msg = msg + " OSReset";
   if(obreset == True) msg = msg + " OBReset";
   Print(msg);
   lastcandletime = Time[0];
   AlertSoundCount = 0;  // reset the counter with each new candle
   }

////////////////////////////////////////////////////////////////////////
// AlertSoundFile played again depending on value of AlertSoundRepeats
if(Seconds() < LastAlert) LastAlert = Seconds();     // reset counter each minute
if(AlertSoundFile != "" && Seconds() >= LastAlert+5) // five seconds delay then repeating on next price tick
   {
   if(BuyAlerts[0]  != 0 && AlertSoundCount < AlertSoundRepeats) {PlaySound(AlertSoundFile);LastAlert = Seconds();AlertSoundCount++;}
   if(SellAlerts[0] != 0 && AlertSoundCount < AlertSoundRepeats) {PlaySound(AlertSoundFile);LastAlert = Seconds();AlertSoundCount++;}
   if(lastlinealert == Time[0] && AlertSoundCount < AlertSoundRepeats) {PlaySound(AlertSoundFile);LastAlert = Seconds();AlertSoundCount++;}
   }

return(0);
} // end of start()

//+------------------------------------------------------------------+
void deinit()
{
// cleanup buffers
int i = 0;
while(i < Bars)
   {
   BuyAlerts[i] = 0;
   SellAlerts[i] = 0;
   CandleBodyLow[i] = 0;
   CandleBodyHigh[i] = 0;
   i++;
   }
}

Comments