QQE_alerts_001
Download scriptThe Qualitative Quantitative Estimation (QQE) indicator is a sophisticated technical analysis tool designed to help traders identify the underlying trend and momentum of a financial asset. Unlike simple moving averages that can be lagging, this script combines several mathematical layers to provide a more responsive "smoothed" view of price action.
Core Logic and Processing
The indicator operates by processing market data through four primary stages:
1. Momentum Baseline (RSI) The logic begins by calculating the Relative Strength Index (RSI). The RSI measures the speed and change of price movements to determine whether an asset is overbought, oversold, or simply trending in a specific direction.
2. Smoothing and Volatility Analysis Instead of using the raw RSI directly, the script applies an Exponential Moving Average (EMA) to the RSI values. This removes "noise" from the data. It then calculates the absolute difference between these smoothed values to measure volatility. By tracking how much the momentum is shifting, the indicator can distinguish between a steady trend and erratic price swings.
3. Dynamic Trend Tracking (The "Slow" Level) One of the most distinct features of this logic is how it establishes its primary trend line (the TrLevelSlow). It uses a combination of:
- Moving Average Smoothing: To keep the data fluid.
- Volatility Factors: By multiplying the volatility by a specific coefficient (the DARFACTOR), the indicator determines how much "room" a trend has to breathe.
- Adaptive Adjustment: The script compares the current momentum against previous levels. If the momentum moves significantly, the trend line updates; however, it includes logic to prevent the line from jumping erratically, ensuring that the trend remains stable unless a significant move occurs.
4. Signal Generation (Cross-overs) The final output is the interaction between two lines: the smoothed RSI (the fast movement) and the calculated Trend Level (the slow, steady path).
- Bullish Signal: When the fast moving average crosses above the trend level, it suggests that upward momentum is accelerating.
- Bearish Signal: When the fast moving average crosses below the trend level, it suggests that downward pressure is taking over.
User Experience and Alerts
To ensure traders do not have to watch the screen constantly, the script includes a comprehensive notification system. It monitors these "cross-over" events in real-time and can trigger three types of alerts:
- Visual Alerts: Pop-up boxes on the trading platform.
- Audio Alerts: Playback of a specific sound file (e.g., a "stop" or "alert" sound).
- Email Notifications: Sending an automated message to the user's registered email address containing the asset name, timeframe, and current price.
By combining momentum, volatility filtering, and smoothed averages, this tool aims to provide a clearer picture of market direction while minimizing the false signals often found in basic trend-following indicators.
//+------------------------------------------------------------------+
//| Qualitative Quantitative Estimation Indicator for Metatrader 4 |
//| Copyright © 2006Roman Ignatov |
//| mailto:roman.ignatov@gmail.com |
//+------------------------------------------------------------------+
//mod alerts
#property copyright "Copyright © 200 Roman Ignatov"
#property link "mailto:roman.ignatov@gmail.com"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_color2 Yellow
#property indicator_style2 STYLE_DOT
extern int SF = 5; // original 5
extern int RSI_Period = 14; // original 14
extern double DARFACTOR = 4.236; //original 4.236
extern bool BoxAlertON = false;
extern bool SoundAlertON = true;
extern bool EmailAlertON = false;
extern int alertDelayBars = 0;
extern string soundfile = "stops.wav"; //ok.wav/alert.wav/short.wav
double alertboxTag,alertsoundTag,alertmailTag;
int Wilders_Period;
int StartBar;
double TrLevelSlow[];
double AtrRsi[];
double MaAtrRsi[];
double Rsi[];
double RsiMa[];
int init()
{
Wilders_Period = RSI_Period * 2 - 1;
if (Wilders_Period < SF)
StartBar = SF;
else
StartBar = Wilders_Period;
IndicatorBuffers(6);
SetIndexBuffer(0, RsiMa);
SetIndexStyle(0, DRAW_LINE);
SetIndexLabel(0, "Value 1");
SetIndexDrawBegin(0, StartBar);
SetIndexStyle(1, DRAW_LINE);
SetIndexBuffer(1, TrLevelSlow);
SetIndexLabel(1, "Value 2");
SetIndexDrawBegin(1, StartBar);
SetIndexBuffer(2, AtrRsi);
SetIndexBuffer(3, MaAtrRsi);
SetIndexBuffer(4, Rsi);
IndicatorShortName(StringConcatenate("QQE(", SF, ")"));
return(0);
}
int start()
{
int counted, i;
double rsi0, rsi1, dar, tr, dv;
if(Bars <= StartBar)
return (0);
counted = IndicatorCounted();
if(counted < 1)
for(i = Bars - StartBar; i < Bars; i++)
{
TrLevelSlow[i] = 0.0;
AtrRsi[i] = 0.0;
MaAtrRsi[i] = 0.0;
Rsi[i] = 0.0;
RsiMa[i] = 0.0;
}
counted = Bars - counted - 1;
for (i = counted; i >= 0; i--)
Rsi[i] = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i);
for (i = counted; i >= 0; i--)
{
RsiMa[i] = iMAOnArray(Rsi, 0, SF, 0, MODE_EMA, i);
AtrRsi[i] = MathAbs(RsiMa[i + 1] - RsiMa[i]);
}
for (i = counted; i >= 0; i--)
MaAtrRsi[i] = iMAOnArray(AtrRsi, 0, Wilders_Period, 0, MODE_EMA, i);
i = counted + 1;
tr = TrLevelSlow[i];
rsi1 = iMAOnArray(Rsi, 0, SF, 0, MODE_EMA, i);
while (i > 0)
{
i--;
rsi0 = iMAOnArray(Rsi, 0, SF, 0, MODE_EMA, i);
dar = iMAOnArray(MaAtrRsi, 0, Wilders_Period, 0, MODE_EMA, i) * DARFACTOR;
dv = tr;
if (rsi0 < tr)
{
tr = rsi0 + dar;
if (rsi1 < dv)
if (tr > dv)
tr = dv;
}
else if (rsi0 > tr)
{
tr = rsi0 - dar;
if (rsi1 > dv)
if (tr < dv)
tr = dv;
}
TrLevelSlow[i] = tr;
rsi1 = rsi0;
string message= Symbol()+" M"+Period()+" "+DoubleToStr(Close[0],4); // Bid +DoubleToStr(Close[0],4)
int b=i+alertDelayBars;
if(RsiMa[b]> TrLevelSlow[b] && RsiMa[b+1]< TrLevelSlow[b+1])
{
if (BoxAlertON && alertboxTag!=Time[b])
{ Alert("QQE Cross: Trend going Up on ",message); alertboxTag = Time[b];
}
if (EmailAlertON && alertmailTag!=Time[b])
{ SendMail("QQEA","QQECross: Trend going Up on "+message); alertmailTag = Time[b];
}
if (SoundAlertON && alertsoundTag!=Time[b])
{ PlaySound (soundfile); alertsoundTag = Time[b];
}
}
if(RsiMa[b]< TrLevelSlow[b] && RsiMa[b+1]> TrLevelSlow[b+1])
{
if (BoxAlertON && alertboxTag!=Time[b])
{ Alert("QQE Cross: Trend going Down on ",message); alertboxTag = Time[b];
}
if (EmailAlertON && alertmailTag!=Time[b])
{ SendMail("QQEA","QQECross: Trend going Down on "+message); alertmailTag = Time[b];
}
if (SoundAlertON && alertsoundTag!=Time[b])
{ PlaySound (soundfile); alertsoundTag = Time[b];
}
}
}
return(0);
}
Comments