QQE MQL5 Indicator: Smoothed RSI Variant and Closed-Bar Alerts
Implement a clearly specified QQE-style oscillator in MQL5: an EMA-smoothed RSI and an adaptive trail based on one Wilder-smoothed series of RSI changes. The custom indicator plots values and can alert on completed-bar crosses. It does not execute orders or claim parity with every QQE or QQE MOD implementation.
What this MT5 indicator covers
Two readable indicator buffers: smoothed RSI and an adaptive trailing reference
One Wilder smoothing stage, explicitly distinguished from double-smoothed QQE variants
Completed-bar alert conditions with a threshold-level filter
No embedded order execution, strategy performance claim or guaranteed historical permanence
How the indicator signal works
Calculation and signal conditions
An up alert requires a completed-bar fast-line cross above the trail with fast above the chosen threshold; down alerts require the reverse cross with fast below it. The threshold is a level filter, not an additional crossover. Full-history chronological calculations use explicit seeds and independent popup and push controls.
Interpretation and limitations
This indicator has no positions, stops, take profits or trade exits. Its RSI-domain adaptive trail is not a price ATR stop. A separate EA must translate signals into a tested execution policy. The forming bar can change; completed-bar alerts avoid using that bar but do not prevent changes caused by revised history or different inputs.
MQL5 Custom Indicator Code
#property strict
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrCrimson
#property indicator_label1 "Smoothed RSI"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_label2 "Adaptive trail (single-stage variant)"
input int InpRSIPeriod=14;
input int InpSF=5;
input double InpQQEFactor=4.236;
input double InpThreshold=50;
input bool PopupAlerts=true;
input bool PushAlerts=false;
double fast[],slow[];
int rsiHandle=INVALID_HANDLE;
datetime lastClosed=0;
int OnInit()
{
if(InpRSIPeriod<2 || InpSF<1 || InpQQEFactor<=0 || InpThreshold<0 || InpThreshold>100)
return INIT_PARAMETERS_INCORRECT;
SetIndexBuffer(0,fast,INDICATOR_DATA); SetIndexBuffer(1,slow,INDICATOR_DATA);
ArraySetAsSeries(fast,false); ArraySetAsSeries(slow,false);
int begin=InpRSIPeriod+InpSF+10;
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,begin); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,begin);
IndicatorSetInteger(INDICATOR_LEVELS,1);
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,InpThreshold);
IndicatorSetInteger(INDICATOR_DIGITS,2);
IndicatorSetString(INDICATOR_SHORTNAME,"QQE-style single-stage variant");
rsiHandle=iRSI(_Symbol,_Period,InpRSIPeriod,PRICE_CLOSE);
return rsiHandle==INVALID_HANDLE?INIT_FAILED:INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(rsiHandle!=INVALID_HANDLE) IndicatorRelease(rsiHandle);
}
int OnCalculate(const int rates_total,const int prev_calculated,
const datetime &time[],const double &open[],const double &high[],const double &low[],
const double &close[],const long &tick_volume[],const long &volume[],const int &spread[])
{
int begin=InpRSIPeriod+InpSF+10;
if(rates_total<begin+3) return 0;
ArraySetAsSeries(time,false);
double raw[]; ArraySetAsSeries(raw,false);
if(CopyBuffer(rsiHandle,0,0,rates_total,raw)!=rates_total) return prev_calculated;
ArrayInitialize(fast,EMPTY_VALUE); ArrayInitialize(slow,EMPTY_VALUE);
int seed=InpRSIPeriod;
fast[seed]=raw[seed]; slow[seed]=raw[seed];
double alpha=2.0/(InpSF+1.0),wilder=1.0/InpRSIPeriod,variation=0;
for(int i=seed+1;i<rates_total;i++)
{
fast[i]=alpha*raw[i]+(1-alpha)*fast[i-1];
double change=MathAbs(fast[i]-fast[i-1]);
variation=wilder*change+(1-wilder)*variation; // One smoothing stage, not double Wilder.
double lower=fast[i]-InpQQEFactor*variation,upper=fast[i]+InpQQEFactor*variation;
if(fast[i-1]>slow[i-1])
slow[i]=fast[i]<slow[i-1]?upper:MathMax(lower,slow[i-1]);
else
slow[i]=fast[i]>slow[i-1]?lower:MathMin(upper,slow[i-1]);
}
int i=rates_total-2;
if(prev_calculated==0 || lastClosed==0) lastClosed=time[i]; // Do not alert old history at attachment.
else if(time[i]!=lastClosed)
{
lastClosed=time[i];
bool buy=fast[i-1]<=slow[i-1] && fast[i]>slow[i] && fast[i]>InpThreshold;
bool sell=fast[i-1]>=slow[i-1] && fast[i]<slow[i] && fast[i]<InpThreshold;
if(buy || sell)
{
string msg=StringFormat("%s %s QQE-style %s closed-bar cross: fast=%.2f trail=%.2f",_Symbol,
EnumToString(_Period),buy?"up":"down",fast[i],slow[i]);
if(PopupAlerts) Alert(msg);
if(PushAlerts && !SendNotification(msg)) Print("Push failed: ",GetLastError());
}
}
return rates_total;
}Copy this code into MetaEditor, save it in the MQL5/Indicators folder, and compile with F7.
Change the settings or add your own signal filter
Describe the inputs, buffers, alerts, visual style, or confirmation filter you want. Pineify generates editable MQL5 source code that you can inspect and compile in MetaEditor.
Pine Script vs MQL5: Same Strategy, Different Platforms
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Series evaluated on chart updates | Event handlers with explicit buffers |
| Deployment | Runs in TradingView with alerts | Runs in the MT5 terminal or on a VPS |
| Broker access | Strategy orders are simulated; live automation needs a separate integration | Direct broker connectivity |
| Backtesting | Strategy Tester for strategy scripts | Strategy Tester for Expert Advisors |
| Code complexity | Simpler, functional syntax | C++-like, more powerful |
The calculation can be implemented on either platform, but the runtime model and buffer APIs differ. Read the Pine Script reference guide before porting logic between them.
Frequently Asked Questions
Related MQL5 pages
Technical references
Risk and testing note
These educational examples require independent compilation and testing. A compile pass or an illustrative setting does not establish execution correctness or profitability. Any reported performance must be supported by reproducible data and test settings; past results do not predict future returns. Trading involves significant risk of loss. This content is not financial advice.