Indicator · Pine Script v6 · Own pane

Quantitative Qualitative Estimation (QQE)

by mihakralj

This indicator plots Quantitative Qualitative Estimation in a separate pane.

View on GitHub

GitHub stars99on the repository
Pine versionv6current
Lines of code129
Settings4inputs
LicenceApache-2.0
Last update4 weeks ago27 Sep 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

129 lines of Pine Script v6 from lib/oscillators/qqe/qqe.pine, published under Apache-2.0. Keep the author's credit and licence lines when you reuse it.

qqe.pine
// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Quantitative Qualitative Estimation (QQE)", "QQE", overlay=false)

//@function Calculates QQE — smoothed RSI with dynamic volatility bands
//@param source Series to evaluate (typically close)
//@param rsiPeriod RSI lookback period
//@param smoothFactor EMA smoothing factor for RSI (SF)
//@param qqeFactor Multiplier for the ATR-like trailing band (Wilders factor)
//@returns [qqeLine, trailingLevel] QQE smoothed RSI and its trailing signal
//@description QQE applies a multi-stage smoothing pipeline to RSI:
//  Stage 1: Compute RSI using Wilder's RMA (alpha=1/rsiPeriod) with §2 warmup.
//  Stage 2: Smooth RSI with EMA(smoothFactor) → rsiMA. Also §2 warmup.
//  Stage 3: Compute |rsiMA − rsiMA[1]|, smooth with double EMA(2*SF-1)
//           → "dar" (dynamic average range). Both EMAs use §2 warmup.
//  Stage 4: Build trailing level: upper/lower bands at rsiMA ± qqeFactor*dar.
//           Trailing level follows price directionally (like Parabolic SAR logic):
//             if rsiMA > prevTrail and rsiMA[1] > prevTrail → trail = max(trail, lower)
//             if rsiMA < prevTrail and rsiMA[1] < prevTrail → trail = min(trail, upper)
//             else → trail flips to upper or lower based on rsiMA side.
//  The QQE line is rsiMA; the trailing level acts as signal for crossover triggers.
//  Crosses of QQE above/below trailing level indicate momentum shifts.
//  Zero-crossing of (QQE - 50) can also be used for trend direction.
qqe(series float source, simple int rsiPeriod, simple int smoothFactor, simple float qqeFactor) =>
    if rsiPeriod <= 0
        runtime.error("RSI period must be greater than 0")
    if smoothFactor <= 0
        runtime.error("Smooth factor must be greater than 0")
    if qqeFactor <= 0.0
        runtime.error("QQE factor must be greater than 0")

    float EPSILON = 1e-10

    // --- Stage 1: Wilder RSI via RMA (alpha = 1/rsiPeriod) with §2 warmup ---
    var float prevSrc   = na
    var float rmaGain   = 0.0
    var float rmaLoss   = 0.0
    var float eRma      = 1.0
    float rmaAlpha      = 1.0 / float(rsiPeriod)
    float rmaBeta       = 1.0 - rmaAlpha

    float chg = not na(prevSrc) ? nz(source) - prevSrc : 0.0
    prevSrc := nz(source)
    float gain = chg > 0 ? chg : 0.0
    float loss = chg < 0 ? -chg : 0.0

    rmaGain := rmaGain * rmaBeta + gain * rmaAlpha
    rmaLoss := rmaLoss * rmaBeta + loss * rmaAlpha
    eRma *= rmaBeta
    float cRma = eRma > EPSILON ? 1.0 / (1.0 - eRma) : 1.0
    float avgGain = rmaGain * cRma
    float avgLoss = rmaLoss * cRma
    float rs = avgLoss == 0.0 ? 100.0 : avgGain / avgLoss
    float rsiVal = 100.0 - 100.0 / (1.0 + rs)

    // --- Stage 2: EMA smooth of RSI (alpha = 2/(SF+1)) with §2 warmup ---
    var float rawRsiMa = 0.0
    var float eRsiMa   = 1.0
    float sfAlpha       = 2.0 / (float(smoothFactor) + 1.0)
    float sfBeta        = 1.0 - sfAlpha

    rawRsiMa := rawRsiMa * sfBeta + rsiVal * sfAlpha
    eRsiMa *= sfBeta
    float cRsiMa = eRsiMa > EPSILON ? 1.0 / (1.0 - eRsiMa) : 1.0
    float rsiMa = rawRsiMa * cRsiMa

    // --- Stage 3: Double EMA of |delta(rsiMA)| → dar ---
    //  Both EMAs use period = 2*SF - 1 → alpha = 2 / (2*SF)
    var float prevRsiMa = na
    float darPeriod     = float(2 * smoothFactor - 1)
    float darAlpha      = 2.0 / (darPeriod + 1.0)
    float darBeta       = 1.0 - darAlpha

    float absDelta = not na(prevRsiMa) ? math.abs(rsiMa - prevRsiMa) : 0.0
    prevRsiMa := rsiMa

    var float rawDar1 = 0.0
    var float eDar1   = 1.0
    rawDar1 := rawDar1 * darBeta + absDelta * darAlpha
    eDar1 *= darBeta
    float cDar1 = eDar1 > EPSILON ? 1.0 / (1.0 - eDar1) : 1.0
    float dar1 = rawDar1 * cDar1

    var float rawDar2 = 0.0
    var float eDar2   = 1.0
    rawDar2 := rawDar2 * darBeta + dar1 * darAlpha
    eDar2 *= darBeta
    float cDar2 = eDar2 > EPSILON ? 1.0 / (1.0 - eDar2) : 1.0
    float dar = rawDar2 * cDar2

    // --- Stage 4: Trailing level (directional flip logic) ---
    float band = qqeFactor * dar
    float upperBand = rsiMa + band
    float lowerBand = rsiMa - band

    var float trail = 0.0
    var float prevRsiMa2 = 50.0

    float newTrail = trail
    if rsiMa > trail and prevRsiMa2 > trail
        newTrail := math.max(trail, lowerBand)
    else if rsiMa < trail and prevRsiMa2 < trail
        newTrail := math.min(trail, upperBand)
    else
        newTrail := rsiMa > trail ? lowerBand : upperBand

    prevRsiMa2 := rsiMa
    trail := newTrail

    [rsiMa, trail]

// ---------- Main loop ----------

// Inputs
i_source       = input.source(close, "Source")
i_rsiPeriod    = input.int(14, "RSI Period", minval=1)
i_smoothFactor = input.int(5, "Smooth Factor", minval=1)
i_qqeFactor    = input.float(4.236, "QQE Factor", minval=0.001, step=0.001)

// Calculation
[qqeLine, trailLine] = qqe(i_source, i_rsiPeriod, i_smoothFactor, i_qqeFactor)

// Plot
plot(qqeLine, "QQE", color=color.yellow, linewidth=2)
plot(trailLine, "Trailing", color=color.aqua, linewidth=1)
hline(50, "Midline", color=color.gray, linestyle=hline.style_dotted)
hline(70, "Overbought", color=color.red, linestyle=hline.style_dashed)
hline(30, "Oversold", color=color.green, linestyle=hline.style_dashed)

Overview

Quantitative Qualitative Estimation (QQE) computes Wilder RSI from the chosen source, smooths it with an exponential moving average, and derives a dynamic average range from a double EMA of absolute RSI changes. A trailing level tracks the smoothed RSI with parabolic-style bands scaled by the QQE factor. Crosses of the QQE line through that trailing level mark momentum shifts, and the distance of QQE from 50 can indicate direction. Source, RSI period, smooth factor, and QQE factor are adjustable.

Details

Published by

mihakralj on GitHub

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Oscillators & momentum

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

algorithmic-tradingcsharpdotnetpinescriptpythonquantitative-financesimdta-libtechnical-analysistechnical-indicators

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Sourcesourceclosei_source
RSI Periodint14i_rsiPeriod
Smooth Factorint5i_smoothFactor
QQE Factorfloat4.236i_qqeFactor
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Asymmetrical RSI

by everget
948 stars

Asymmetrical RSI is an indicator that computes a custom relative strength index from the rate of change of a user-selected source. It plots the resulting ARSI line in a separate pane with color coding that turns green above the overbought level and red below t

Indicator v4 Oscillators & momentum
Updated 10 days ago · GPL-3.0 GitHub repository of Asymmetrical RSI

This indicator calculates momentum setups based on the Relative Strength Index (RSI) and plots in a separate pane. It offers multiple scanning modes such as Continuous Break, Continuous Retracement, Flip Break, Flip Retracement, and both regular and hidden div

Indicator v6 Oscillators & momentumDivergence Repaints
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup - RSI Directional Momentum Indicator

Beep Boop

by magic8bot
409 stars

This indicator calculates a modified MACD oscillator and signal line alongside a trend EMA filter, plotting the output as a stylized column histogram in a separate pane. Instead of plotting true MACD distance, it quantifies positive and negative histogram mome

Indicator v4 Oscillators & momentumTrend
Updated 3 years ago · MIT GitHub repository of Beep Boop
261 stars

This indicator demonstrates an experimental graph-style scatter visualization within a separate pane using Pine Script arrays. It tracks two features across recent bars: the single-bar price change and a scaled 14-period Relative Strength Index. Values are loa

Indicator v4 Oscillators & momentum
Updated 4 years ago · None stated GitHub repository of Example: Graph Style - 4th Dimension RSI

KD指標

by TaichiS
219 stars

This script calculates and plots a Stochastic Oscillator (KD indicator) in a separate chart pane. It determines the fast stochastic value over a 9-period lookback, then applies a 3-period Simple Moving Average (SMA) to create the %K line, and a second 3-period

Indicator v4 Oscillators & momentum
Updated 5 years ago · None stated GitHub repository of KD指標

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers