Hi folks,
Did you hear the "Brain Damage" album of Pink Floyd, No need to hear! But the Alert Once is a very hard challenge for any MQL4 programmer's brain!
When the Fast Moving Average crosses from downside to upside the Slow Moving Average in 1 Hour time frame make an Alert to buy! Great! Easy? Yes but:
When the above condition met I've got an Alert and all the time the Fast Moving Average is still above the Slow moving Average I'm getting ALERTS.
I want it to alert me once per par when the condition met! That's why I'm writing this article Alert Once (per bar).
In the code there are two methods to tell it's a new bar; The first method is a function I've created before called NewBar() which return true in the case of new bar and false otherwise:
bool NewBar()
{
static datetime lastbar;
datetime curbar = Time[0];
if(lastbar!=curbar)
{
lastbar=curbar;
return (true);
}
else
{
return(false);
}
}
The function above compare the time of opening bar for the last save bar with the time of opening bar of the current bar. If they not equals (which means it's a new bar) it returns true and if they are equals it means theres's no new bar has been developed and returns false.
This function is great if you want to track one only alert. But I want to track more than one Alert. For example I want to show alerts when:
1- When the FMA (Fast Moving Average) crosses up the SMA (Slow Moving Average) Alert me to Buy!
2- When FMA crosses down the SMA Alert me to Sell!
3- When the 2 bars ago FMA crosses up the previous bar SMA Alert me Buy confirmed by another bar!
4- When the 2 bars ago FMA crosses down the previous bar SMA Alert me Sell confirmed by another bar!
I want 4 Alert and you have to keep track of each of them and Alert Only Once Per Bar! This is the Brain Damage or programming :)!
Let's see the second type that telling it's a new bar:
static int LastAlert = 0;
if( LastAlert == 0 || LastAlert_1 < Bars )
{
Alert(alert_msg);
LastAlert = Bars;
}
In this code we compare between the last save number of bars and the current bars count, if this count increased it means it's a new bar. I prefer this code because I'll use it to track more than Alert.
One Image = 10000 words (I don't remember the count of words). Please give this image a look to know the logic behind Alert Once function.

As you can see in the above image the logic is very easy one:
1 -When the Alert Once function is called we check first if it's the first call of the function and in this case we Alert the message.
2- If it wasn't the first call we check "Was the last alert bar occurred in the same bar" which means is it a same bar for the new alert? If No we Alert the message.
Before we convert the above image to code I want to add a new concept, the reference of the Alert.
I want to track 4 Alert so I want to make the function accept a reference for each alert and track each alert alone. I hope it's clear and the code below will make it clearer (I hope).
bool AlertOnce(string alert_msg, int ref)
{
static int LastAlert_1 = 0;
static int LastAlert_2 = 0;
static int LastAlert_3 = 0;
static int LastAlert_4 = 0;
switch(ref)
{
case 1:
if( LastAlert_1 == 0 || LastAlert_1 < Bars )
{
Alert(alert_msg);
LastAlert_1 = Bars;
return (1);
}
break;
case 2:
if( LastAlert_2 == 0 || LastAlert_2 < Bars )
{
Alert(alert_msg);
LastAlert_2 = Bars;
return (1);
}
break;
case 3:
if( LastAlert_3 == 0 || LastAlert_3 < Bars )
{
Alert(alert_msg);
LastAlert_3 = Bars;
return (1);
}
break;
case 4:
if( LastAlert_4 == 0 || LastAlert_4 < Bars )
{
Alert(alert_msg);
LastAlert_4 = Bars;
return (1);
}
break;
}
}
First we track 4 Alert so we will use 4 static variables to hold the statue of every alert and we use switch keyword to work with every alert alone. that's better than making 4 functions one for every alert? right?
1- In the case the LastAlert_1 (or any of the four alerts) is equal to 0, it means it's the first call we Alert the alert_msg and set the LastAlert_1 to the number of bars on the chart.
2- Or if the LastAlert_1 is less the number of bars on the chart, which means it's a new bar we Alert the alert_msg.
That's all!
It's an easy task, you can use for the first alert type (Buy when FMA crosses up ) a code like that:
if (Cross(FMA ,SMA) == CROSS_UP)
AlertOnce ("We have to buy",1);
Just remember that the reference of this alert is number 1.
I hope you find a useful and brain save lesson!
Coders' Guru