How to add alerts to your indicators

1
Hello coders and traders. I have seen many people requesting to add alerts to indicators they already have. I have also seen someone say that he didn't realize it was that simple to add the alert coding to his indicator. Is it that simple ? And if so , Would people be willing to give guidance on adding alerts rather than ten million people asking someone to do it for them ? So...If you can find it in your heart to give guidance to the many traders out there , that would be awesome of you.


Re: How to add alerts to your indicators

3
JADragon3 wrote: Tue Aug 01, 2017 5:25 am Hello coders and traders. I have seen many people requesting to add alerts to indicators they already have. I have also seen someone say that he didn't realize it was that simple to add the alert coding to his indicator. Is it that simple ? And if so , Would people be willing to give guidance on adding alerts rather than ten million people asking someone to do it for them ? So...If you can find it in your heart to give guidance to the many traders out there , that would be awesome of you.
For me was as simple as studying the code before the alert was added and then see what was done after the alert was added, and then trial and error after that.

IdeaRe: How to add alerts to your indicators

4
Old article by ANDREY KHATIMLIANSKII from MQL5 but , probably still useful for learning.

Sound Alerts in Indicators

Introduction

Though automated trading becomes more and more popular, many traders still practice manual trading. So, where an Expert Advisor needs some milliseconds to evaluate the current market situation, a human will spend much time, power and - which is most important - attention.

As a couple of years before, many traders use one or more Technical Indicators. Some strategies consider indicator values on several timeframes simultaneously.

So, how can one "catch" an important signal? There are several choices:

  • write an Expert Advisor that would analyze the market and alert about important events;
  • sit in front of the monitor and , switching between tens of charts, try to analyze the information from all of them;
  • add an alerting system into all indicators used.

The first choice is, in my opinion, the most proper. But it demands either programming skills or money to pay for realization. The second way is very time consuming, tiring, and inefficient. The third choice is a cross between the former two ways. One needs much fewer skills and less time to implement it, but it can really better the lot of the user trading manually.

It is the implementation of the third choice that the article is devoted to. After having read it, every trader will be able to add convenient alerts into indicators.

Types of Alerts

There are many ways to interpret indicators. People can differently understand the meaning of even MetaTrader 4 Client Terminal indicators, not to say about various custom indicators...

Somebody buys when the main line of MACD touches the signal line, another trader waits until it intersects the zero line, and somebody opens a long position when MACD is below 0 and starts moving up. I don't feel myself able to count all possible interpreting variations, so I will just describe the principles of how an alerting block can be added into an indicator. Then you will be able to add any kind of alerts into practically all indicators according to your taste.

The most possible alerts are listed below:

  • intersection of two lines of an indicator (lie in the example above - the main and the signal line of MACD);
  • intersection of the indicator line and a certain level (for example, the main line of MACD and zero line, Stoсhastic and levels of 70 and 30, CCI and levels of -100 and 100);
  • reversed moving of the indicator (for example, AC and AO, normal MA);
  • changed location towards price (Parabolic SAR);
  • appearing arrow above or below the price value (Fractals).

There are probably some other interpretations that are forgotten or even not known to me, so we will describe the five ones listed above.

Ways of Alerting

MetaTrader 4 and MQL4 allow implementation of several ways of both visual and audio alerting:
  • a usual screen message (function Comment);
  • a records in the log (function Print);
  • a message window plus a sound (function Alert);
  • a special sound, a file to be selected and played (function PlaySound).

Besides, there are functions for sending a file to the FTP server (function SendFTP()), displaying a message/dialog box (MessageBox()), and sending mails (SendMail()). Function SendFTP() will hardly be demanded by a regular user, function MessageBox() does not suit for being used in an indicator since it stops its operation until the message box is closed, function SendMail(), though it is good for sending SMS, is rather "dangerous" in use - having drawn a number of indicators in a chart, you will provide yourselves with an endless and uncontrolled stream of messages. The function may be used, but it would be better to use if from an EA, for instance, by sending a message when an alert occurs on several indicators simultaneously, paying much attention to it.

In this article, we will consider only audio and visual ways of alerting in the MetaTrader 4 Client Terminal.

One of the most convenient and the simplest of them is function Alert since it contains both text and sound. Besides, the terminal stores the Alerts history, so it is possible to see what signal came an hour ago.

But tastes differ, it's a common knowledge. So I will make something like a preform for all the above-mentioned methods (except for SendFTP, MessageBox, SendMail), and you will just choose a suitable one.

Alert Frequency Filter

If you have ever used alerts in indicators, you certainly had to deal with their overfrequency, especially on smaller timeframes. There are some ways to solve this problem:

  • To define alerts on bars already formed. This solution would be the most proper.
  • Alternate alerts - sell after buy and vice versa (it would be a very logical way, too, that can be used together with other ones).
  • Make a pause between alerts (not a good idea).
  • Give only one alert per bar (this limitation is rather affected limitation).

Whether to use alerts from a zero, not yet formed bar, is everyone's personal business. I, for instance, suppose this to be wrong. But there are indicators that need instant response - one bar is too much for them. So we will allow users to make their choice. Several alerts to buy would hardly have any sense, so we will alternate all alerts. We will not introduce any artificial pauses I suppose. If they are really necessary, this fact will be known from comments to this article.

Thus, let us start realization.

Alert One - Intersection of Two Lines of an Indicator

Let us start with the MACD that has been given in examples above.

Our main task is to detect in what arrays the indicator lines are stored. Let us look into the code for this:

Code: Select all

//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 2
#property  indicator_color1  Silver
#property  indicator_color2  Red
#property  indicator_width1  2
//---- indicator parameters
extern int FastEMA = 12;
extern int SlowEMA = 26;
extern int SignalSMA = 9;
//---- indicator buffers
double MacdBuffer[];
double SignalBuffer[];
Please note the comment of "indicator buffers" is that what we were looking for. Such arrays mostly have intuitively comprehensive names (MacdBuffer is the MACD main line value buffer, SignalBuffer - buffer of the signal line) and are always located outside of functions init, deinit, start.

If there are many arrays and it is difficult to see which of them is necessary, look into function init - all arrays shown in the chart are anchored to a certain number using function SetIndexBuffer:

Code: Select all

int init()
  {
//---- drawing settings
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexDrawBegin(1, SignalSMA);
   IndicatorDigits(Digits + 1);
//---- indicator buffers mapping
   SetIndexBuffer(0, MacdBuffer);
   SetIndexBuffer(1, SignalBuffer);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("sMACD(" + FastEMA + "," + SlowEMA + "," + SignalSMA + ")");
   SetIndexLabel(0, "sMACD");
   SetIndexLabel(1, "sSignal");
//---- initialization done
   return(0);
  }
This is the sequence (from 0 to 7), in which the indicator line values are shown in the DataWindow. Names that you can see there are given by function SetIndexLabel - this is the third identification method.

Now, when we know where the necessary data are stored, we can start realization of the alerting block. For this, let's go to the very end of function start - just above the preceding operator return:

Code: Select all

   for(i = 0; i < limit; i++)
       SignalBuffer[i] = iMAOnArray(MacdBuffer, Bars,S ignalSMA, 0, MODE_SMA, i);
//---- done
 
// we will add our code here
 
   return(0);
  }
//+------------------------------------------------------------------+
In no case, the alerting block should be added in the indicator's calculating loop - this will slow execution and give no effect.

So, let's start writing our "composition":

Code: Select all

    //---- Static variables where the last bar time
    //---- and the last alert direction are stored
    static int PrevSignal = 0, PrevTime = 0;
 
    //---- If the bar selected to be analyzed is not a zero bar, 
    //     there is no sense to check the alert
    //---- several times. If no new bar starts to be formed, quit.
    if(SIGNAL_BAR > 0 && Time[0] <= PrevTime ) 
        return(0);
    //---- Mark that this bar was checked
    PrevTime = Time[0];
Every time when function start is executed, our code will be executed, as well. Normal variables are zeroized after each execution of the function. So we have declared two static variables to store the latest alert and the calculated bar number.
Then a simple checking follows: we check whether a new bar has started (it only works if SIGNAL_BAR is more than 0).

By the way, we declared variable SIGNAL_BAR itself a bit earlier, before function init:

Code: Select all

double     SignalBuffer[];
 
//---- Bar number the alert to be searched by
#define SIGNAL_BAR 1
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
Please note directive #define - the compiler will just replace variable SIGNAL_BAR with the given value (1) throughout the code.

Below is the alert code itself:

Code: Select all

    //---- If the preceding alert was SELL or this is the first launch (PrevSignal=0)
    if(PrevSignal <= 0)
      {
        //---- Check whether the lines have met in the preceding bar:
        if(MacdBuffer[SIGNAL_BAR] - SignalBuffer[SIGNAL_BAR] > 0 && 
           SignalBuffer[SIGNAL_BAR+1] - MacdBuffer[SIGNAL_BAR+1] >= 0)
          {
            //---- If yes, mark that the last alert was BUY
            PrevSignal = 1;
            //---- and display information:
            Alert("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            Print("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            Comment("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            PlaySound("Alert.wav");
          }
      }
This is very simple, too. If the preceding alert was SELL, check intersection of lines:
if the MACD main line value on bar #1 exceeds that of the signal line on bar # 1
AND
the siganl line value on bar #2 exceeds that of the MACD line on bar #2,
then
lines have met.

Then mark that the last alert was for BUY and display the informing message. Note the three commented lines - these are three more alert variations. You can decomment or delete any or all of them. I left Alert by default as the most convenient one.
In function PlaySound, it can be specified what wave file should be played. The file must be located in directory MetaTrader 4\sounds\ and have extension wav. For example, a special sound can be assigned to the BUY alert, another - for the SELL alert, or there can be different sounds for different indicators, etc.

The SELL alert is absolutely the same:

Code: Select all

    //---- Completely the same for the SELL alert
    if(PrevSignal >= 0)
      {
        if(SignalBuffer[SIGNAL_BAR] - MacdBuffer[SIGNAL_BAR] > 0 && 
           MacdBuffer[SIGNAL_BAR+1] - SignalBuffer[SIGNAL_BAR+1] >= 0)
          {
            PrevSignal = -1;
            Alert("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            Print("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            Comment("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            PlaySound("Alert.wav");
          }
      }
Other Alerts

Now, when we have known the indicator code, it will be much easier for us to write other alerting blocks. Only the "formula" will be changed, the rest of the code will be just copied and pasted.

Alert that signals about touching a certain level is very similar to that of intersection of lines. I added it to Stochastic, but you can make a similar one for any other indicator:

Code: Select all

    if(PrevSignal <= 0)
      {
        if(MainBuffer[SIGNAL_BAR] - 30.0 > 0 && 
           30.0 - MainBuffer[SIGNAL_BAR+1] >= 0)
          {
            PrevSignal = 1;
            Alert("sStochastic (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(70.0 - MainBuffer[SIGNAL_BAR] > 0 && 
           MainBuffer[SIGNAL_BAR+1] - 70.0 >= 0)
          {
            PrevSignal = -1;
            Alert("sStochastic (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }
As you can see, if line %K (MainBuffer) meets level 30 bottom-up, the indicator will say "Buy", whereas it will say "Sell" if level 70 is met top-down.

The third kind of alert is alert informing about the changed direction of movement. We will consider it on the example of AC. Note that five buffers are used in this indicator:

Code: Select all

//---- indicator buffers
double     ExtBuffer0[];
double     ExtBuffer1[];
double     ExtBuffer2[];
double     ExtBuffer3[];
double     ExtBuffer4[];
ExtBuffer3 and ExtBuffer4 are used for intermediate calculations, ExtBuffer0 always stores the indicator value, ExtBuffer2 and ExtBuffer3 "color" columns in 2 colors. Since we need only indicator value, we will use ExtBuffer0:

Code: Select all

    if(PrevSignal <= 0)
      {
        if(ExtBuffer0[SIGNAL_BAR] - ExtBuffer0[SIGNAL_BAR+1] > 0 &&
           ExtBuffer0[SIGNAL_BAR+2] - ExtBuffer0[SIGNAL_BAR+1] > 0)
          {
            PrevSignal = 1;
            Alert("sAC (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR] > 0 &&
           ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR+2] > 0)
          {
            PrevSignal = -1;
            Alert("sAC (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }
If the indicator value was decreasing and then started to increase, we give a BUY alert. If vice versa - SELL alert.

The fourth kind of alert - informing about changed location towards price - is rather rare.
But it sometimes appears, for example, in Parabolic. We will write the "formula" using it as an example:

Code: Select all

    if(PrevSignal <= 0)
      {
        if(Close[SIGNAL_BAR] - SarBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = 1;
            Alert("sParabolic Sub (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(SarBuffer[SIGNAL_BAR] - Close[SIGNAL_BAR] > 0)
          {
            PrevSignal = -1;
            Alert("sParabolic Sub(", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }
It is all simple here - we compare the indicator value to the bar close price. Note that, if SIGNAL_BAR is set for 0, every price touch of the Parabolic will be accompanied with an alert.

The last alert informs about appearance of an arrow in the chart. It appears rather rarely in standard indicators, but it is rather popular in custom "pivot finders". I will consider this kind of alerts using indicator Fractals (its source code written in MQL4 can be found in Code Base: Fractals).

Such indicators have a common feature: they are not equal to 0 (or EMPTY_VALUE) in those places where they are drawn on a chart. On all other bars their buffers are empty. It means, you only need to compare the buffer value to zero in order to determine the signal:

Code: Select all

    if(PrevSignal <= 0 )
      {
        if(ExtDownFractalsBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = 1;
            Alert("sFractals (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(ExtUpFractalsBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = -1;
            Alert("sFractals (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }
But, if you attach an indicator with such a code to the chart, you will never receive any alerts. Fractals have a special feature - they use 2 future bars for analyses, so the arrows appear only on bar#2 (the third bar starting with the zero one). So, for alerts to start working it is necessary to set SIGNAL_BAR as 2:

Code: Select all

//---- Bar number to search an alert by
#define SIGNAL_BAR 2
That's all, and alerts will work!

Conclusion

The article gives a description of various methods used to add sound alerts into indicators. Such terms as alert interpreting method (type of alert), way of alerting and alert frequency filter are defined.

The following types of alerts are defined and realized:

intersection of two lines of an indicator;

  • intersection of the indicator line and a certain level;
  • reversed moving of the indicator;
  • changed location towards price;
  • appearing arrow above or below the price value.

The following functions are selected for alerts:

  • Comment() - displaying a normal message;
  • Print() - showing a message in the log;
  • Alert() - showing the message in a special window and a sound alert;
  • PlaySound() - playing any wave file.

To decrease the alert frequency:

  • use bars already formed when determining an alert;
  • all alerts alternate - only buy after sell, and vice versa.

I used five indicators that correspond with five types of alerts to study their alerting blocks. You can download the resulting indicators - they are attached to the article.

I hope you can see that there is nothing complicated in adding an alerting block into indicators - everyone can do this.

Re: How to add alerts to your indicators

5
JADragon3 wrote: Tue Aug 01, 2017 5:25 am Hello coders and traders. I have seen many people requesting to add alerts to indicators they already have. I have also seen someone say that he didn't realize it was that simple to add the alert coding to his indicator. Is it that simple ? And if so , Would people be willing to give guidance on adding alerts rather than ten million people asking someone to do it for them ? So...If you can find it in your heart to give guidance to the many traders out there , that would be awesome of you.
Each and every code and indicator has different rules
Some are already written in a way that alerts addition is easy
Some need a complete rewriting - and are far, far from being simple to do that

there is no general rule of thumb for that


Re: How to add alerts to your indicators

6
mladen wrote: Wed Aug 02, 2017 5:29 pm

Each and every code and indicator has different rules
Some are already written in a way that alerts addition is easy
Some need a complete rewriting - and are far, far from being simple to do that

there is no general rule of thumb for that
I can definitely understand that. Sometimes I start to open pandora's box when it comes to moving code around and then slam it back shut cause I have no idea what I am doing. Gotta start tinkering around somewhere I suppose.


Who is online

Users browsing this forum: No registered users and 11 guests