Meet the Creator
Real author: Paul Stringer
The Harami Alert Indicator is designed to identify Harami patterns in the market, complete with alerts, email notifications, and push notifications to keep you in the loop while trading.
We made a few tweaks to the indicator's code to implement these alerts and notifications, making it even more useful for traders:
- New input parameters were introduced:
input uint NumberofBar=1;//Bar number for the signal input bool SoundON=true; //Enable alerts input uint NumberofAlerts=2;//Number of alerts input bool EMailON=false; //Enable mailing the signal input bool PushON=false; //Enable sending the signal to mobile devices
- Three new functions were added at the end of the indicator code: BuySignal(), SellSignal(), and GetStringTimeframe().
//+------------------------------------------------------------------+ //| Buy signal function | //+------------------------------------------------------------------+ void BuySignal(string SignalSirname, // Indicator name for alerts double &BuyArrow[], // Buffer for buy signals const int Rates_total, // Current number of bars const int Prev_calculated, // Number of bars on the previous tick const double &Close[], // Closing prices const int &Spread[]) // Spread { //--- static uint counter=0; if(Rates_total!=Prev_calculated) counter=0; bool BuySignal=false; bool SeriesTest=ArrayGetAsSeries(BuyArrow); int index; if(SeriesTest) index=int(NumberofBar); else index=Rates_total-int(NumberofBar)-1; if(NormalizeDouble(BuyArrow[index],_Digits) && BuyArrow[index]!=EMPTY_VALUE) BuySignal=true; if(BuySignal && counter<=NumberofAlerts) { counter++; MqlDateTime tm; TimeToStruct(TimeCurrent(),tm); string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min); SeriesTest=ArrayGetAsSeries(Close); if(SeriesTest) index=int(NumberofBar); else index=Rates_total-int(NumberofBar)-1; double Ask=Close[index]; double Bid=Close[index]; SeriesTest=ArrayGetAsSeries(Spread); if(SeriesTest) index=int(NumberofBar); else index=Rates_total-int(NumberofBar)-1; Bid+=Spread[index]*_Point; string sAsk=DoubleToString(Ask,_Digits); string sBid=DoubleToString(Bid,_Digits); string sPeriod=GetStringTimeframe(ChartPeriod()); if(SoundON) Alert("BUY signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod); if(EMailON) SendMail(SignalSirname+": BUY signal alert","BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod); if(PushON) SendNotification(SignalSirname+": BUY signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod); } //--- } //+------------------------------------------------------------------+ //| Sell signal function | //+------------------------------------------------------------------+ void SellSignal(string SignalSirname, // Indicator name for alerts double &SellArrow[], // Buffer for sell signals const int Rates_total, // Current number of bars const int Prev_calculated, // Number of bars on the previous tick const double &Close[], // Closing prices const int &Spread[]) // Spread { //--- static uint counter=0; if(Rates_total!=Prev_calculated) counter=0; bool SellSignal=false; bool SeriesTest=ArrayGetAsSeries(SellArrow); int index; if(SeriesTest) index=int(NumberofBar); else index=Rates_total-int(NumberofBar)-1; if(NormalizeDouble(SellArrow[index],_Digits) && SellArrow[index]!=EMPTY_VALUE) SellSignal=true; if(SellSignal && counter<=NumberofAlerts) { counter++; MqlDateTime tm; TimeToStruct(TimeCurrent(),tm); string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min); SeriesTest=ArrayGetAsSeries(Close); if(SeriesTest) index=int(NumberofBar); else index=Rates_total-int(NumberofBar)-1; double Ask=Close[index]; double Bid=Close[index]; SeriesTest=ArrayGetAsSeries(Spread); if(SeriesTest) index=int(NumberofBar); else index=Rates_total-int(NumberofBar)-1; Bid+=Spread[index]*_Point; string sAsk=DoubleToString(Ask,_Digits); string sBid=DoubleToString(Bid,_Digits); string sPeriod=GetStringTimeframe(ChartPeriod()); if(SoundON) Alert("SELL signal \n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod); if(EMailON) SendMail(SignalSirname+": SELL signal alert","SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod); if(PushON) SendNotification(SignalSirname+": SELL signal at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod); } //--- } //+------------------------------------------------------------------+ //| Getting the timeframe as a string | //+------------------------------------------------------------------+ string GetStringTimeframe(ENUM_TIMEFRAMES timeframe) { //---- return(StringSubstr(EnumToString(timeframe),7,-1)); //---- }
- We added calls to BuySignal() and SellSignal() functions following the indicator calculation cycles within the OnCalculate() block:
//--- BuySignal("Harami_Alert",BuyBuffer,rates_total,prev_calculated,close,spread); SellSignal("Harami_Alert",SellBuffer,rates_total,prev_calculated,close,spread); //---
Here, BuyBuffer and SellBuffer are the names of the indicator buffers where buy and sell signals are stored. Remember to set empty values in these buffers as either zeros or EMPTY_VALUE.
Initially, this indicator was developed in MQL4 and was first shared on the Code Base back on June 14, 2016.

Fig. 1. Harami_Alert indicator on the chart

Fig. 2. Harami_Alert. Generating alerts
Related Posts
- Unlock Trading Insights with Volume Profile + Range v6.0 for MetaTrader 5
- Mastering the Open Range Breakout Indicator for MetaTrader 5
- ID Lite Info MA: A Comprehensive Indicator for MetaTrader 5
- Unlocking Trading Insights with Volume Profile + Range v6.0 for MetaTrader 5
- Optimize Your Backtesting with the New Economic Calendar Tool for MetaTrader 5