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++;
   }
}



Sample





Analysis



Market Information Used:

Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar
Series array that contains close prices for each bar
Series array that contains open prices of each bar
Series array that contains open time of each bar


Indicator Curves created:

Implements a curve of type DRAW_ARROW
Implements a curve of type DRAW_NONE
Implements a curve of type DRAW_HISTOGRAM


Indicators Used:

MACD Histogram
Stochastic oscillator
Moving average indicator


Custom Indicators Used:

Order Management characteristics:

Other Features:

It issuies visual alerts to the screen
It plays sound alerts