Complete .mq5 source code

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

AspectPine Script (TradingView)MQL5 (MetaTrader 5)
ExecutionSeries evaluated on chart updatesEvent handlers with explicit buffers
DeploymentRuns in TradingView with alertsRuns in the MT5 terminal or on a VPS
Broker accessStrategy orders are simulated; live automation needs a separate integrationDirect broker connectivity
BacktestingStrategy Tester for strategy scriptsStrategy Tester for Expert Advisors
Code complexitySimpler, functional syntaxC++-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.