Author: Copyright � 200 Roman Ignatov
QQE_alerts

The Qualitative Quantitative Estimation (QQE) is a technical analysis indicator designed to help traders identify trend direction and momentum by smoothing out market "noise." Instead of looking at raw price action, it processes multiple layers of data to provide a clearer picture of where the market is heading.

How the Logic Works

The indicator functions by layering three different types of mathematical processing:

1. Momentum Measurement (The RSI Foundation) The script begins by calculating the Relative Strength Index (RSI). The RSI measures the speed and magnitude of price changes. By using this as a starting point, the indicator captures the underlying strength of the market movement rather than just the price itself.

2. Smoothing and Volatility Tracking To prevent the data from being too erratic, the script applies several rounds of "smoothing" (specifically using Exponential Moving Averages):

  • It calculates a moving average of the RSI to create a smoother trend line.
  • It then calculates the volatility—measuring how much that smoothed line is moving from one moment to the next.
  • Finally, it applies another layer of smoothing to this volatility data. This ensures that the resulting signals aren't triggered by tiny, insignificant price wobbles.

3. The Dynamic Threshold (The "Slow" Level) One of the most unique features of this logic is how it creates its "Trend Line." Rather than using a static level, it calculates a dynamic threshold based on the volatility of the momentum. It takes the smoothed volatility, multiplies it by a specific factor, and adds or subtracts it from the current price movement. This allows the indicator to expand when the market is volatile and contract when the market is calm.

How to Read the Results

The indicator displays two main lines on your chart:

  • The Momentum Line: Represents the current smoothed trend of the market.
  • The Threshold Line: Represents the calculated "buffer" zone based on volatility.

Identifying a Trend Change: The script is designed to trigger an alert or visual signal when the Momentum Line crosses the Threshold Line:

  • Trend Moving Up: When the Momentum Line crosses from below to above the Threshold Line, it suggests a shift toward bullish momentum.
  • Trend Moving Down: When the Momentum Line crosses from above to below the Threshold Line, it suggests a shift toward bearish momentum.

Notification System

The script includes an integrated alert system that can be customized. Depending on your settings, it can notify you via:

  • On-screen Pop-ups: Visual alerts within the trading platform.
  • Audio Signals: Playing a specific sound file when a crossover occurs.
  • Email Notifications: Sending a direct message to your registered email address providing the current symbol and price at the moment of the trend shift.
Indicators Used
Relative strength indexMoving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emails
14 Views
2 Downloads
0 Favorites
QQE_alerts
//+------------------------------------------------------------------+
//|   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

#property indicator_level1 50
#property indicator_levelcolor BlueViolet


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
extern bool   Value2Data       = true;


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");
    if(!Value2Data)
    SetIndexLabel(1, NULL);
    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