Using parts of QQE (Qualitative Quantitative Estimation) and applying the trailing line of QQE on price directly.
Outcome, it's behaving like a baseline filter and it can be use as an exit or a trailing stop indicator.
I modified the original code and added 3 type of QQE calculation method - try it!
Code:
CSS:
#//@version=4
#study("QQE Trailing Line for Trailing Stop | jh", overlay=true)
#// Adapted from the NNFX Baseline Script
#// https://www.tradingview.com/script/XmEVK58c-NNFX-Baseline-Script-Moving-Averages/
# Converted and mod by Sam4Cok@Samer800 - 10/2022
#//QQE Trend Line
input colorBar = no; # "Color Bars"
input ShowArrow = no;
input source = hlc3;
input qqeCalcMethod = {default "QQE 1", "QQE 2", "QQE 3"}; # "QQE Calc method
input qqeMaType = {default "TRAMA", "eVWMA", "SMMA", "EMA", "TEMA", "WMA", "SMA"};
input ShowQqeCloud = yes;
input qqeLength = 14; # "Signal Length")
input smoothening = 5; # "Smoothening Length")
input qqe_factor = 4.236; # "QQE Factor")
input atrSmoothing = {default "EMA", "eVWMA", "SMMA", "TEMA", "WMA", "SMA", "TRAMA"};
input showAtrBand = no; # "Show ATR Bands"
input showAtrViolation = no; # "Show ATR Violation"
input atrlength = 14;
input slMultiplier = 1.5;
input tpMultiplier = 1.0;
def na = Double.NaN;
DefineGlobalColor("green", CreateColor(76, 175, 80));
DefineGlobalColor("red", CreateColor(255, 82, 82));
#----- Scripts----
script nz {
input data = close;
input repl = 0;
def ret_val = if IsNaN(data) then repl else data;
plot return = ret_val;
}
#ma(type, src, len) =>
script ma {
input type = "EMA";
input src = close;
input len = 14;
def volumeSum = Sum(volume, len);
def evwma = ((volumeSum - volume) * nz(evwma[1]) + volume * src) / volumeSum;
def e = ExpAverage(src, len);
def Mcg = if IsNaN(Mcg[1]) then Average(src, len) else
CompoundValue(1, Mcg[1] + ((src - Mcg[1]) / (0.6 * len * Power(src / Mcg[1], 4))), src);
def ama;
def H = Highest(high, len);
def L = Lowest(low, len);
def HH = Max(Sign(H - H[1]), 0);
def LL = Max(Sign(L - L[1]) * -1, 0);
def TC = Power(Average(if HH or LL then 1 else 0, len), 2);
ama = ama[1] + TC * (src - ama[1]);
def ma;
ma = if type == "SMA" then SimpleMovingAvg(src, len) else
if type == "EMA" then ExpAverage(src, len) else
if type == "TEMA" then 3 * (e - ExpAverage(e, len)) + ExpAverage(ExpAverage(e, len), len) else
if type == "WMA" then WMA(src, len) else
if type == "SMMA" then WildersSmoothing(src, len) else
if type == "eVWMA" then evwma else
if type == "TRAMA" then ama else
if type == "McGinley" then Mcg else Double.NaN;
plot result = ma;
}
#//Credits to Shizaru
#qqeLine(src, len, sf, qqe, qqeMaType) =>
script qqeLine1 {
input src = close;
input len = 14;
input sf = 5;
input qqe = 4.236;
input qqeMaType = yes;
def maType = qqeMaType;
def wildersper = len * 2 - 1;
def rsima = ma(maType, src, sf);
def atr = AbsValue(rsima[1] - rsima);
def maatrrsi = ma(maType, atr, wildersper);
def dar = ma(maType, maatrrsi, wildersper) * qqe;
def trr;
trr = if rsima > nz(trr[1]) then (If((rsima - dar) < trr[1], trr[1], rsima - dar)) else
(If((rsima + dar) > trr[1], trr[1], rsima + dar));
plot return = trr;
}
#//Credits to Glaz
#qqeLine2(src, len, sf, qqe, qqeMaType) =>
script qqeLine2 {
input src = close;
input len = 14;
input sf = 5;
input qqe = 4.236;
input qqeMaType = yes;
def maType = qqeMaType;
def Wilders_Period = len * 2 - 1;
def RsiMa = ma(maType, src, sf);
def AtrRsi = AbsValue(RsiMa[1] - RsiMa);
def MaAtrRsi = ma(maType, AtrRsi, Wilders_Period);
def dar = ma(maType, MaAtrRsi, Wilders_Period) * qqe;
def longband;
def shortband;
def trend;
def DeltaFastAtrRsi = dar;
def RSIndex = RsiMa;
def newshortband = RSIndex + DeltaFastAtrRsi;
def newlongband = RSIndex - DeltaFastAtrRsi;
longband = if RSIndex[1] > longband[1] and RSIndex > longband[1] then
Max(longband[1], newlongband) else newlongband;
shortband = if RSIndex[1] < shortband[1] and RSIndex < shortband[1] then
Min(shortband[1], newshortband) else newshortband;
trend = if Crosses(RSIndex, shortband[1]) then 1 else
if Crosses(longband[1], RSIndex) then -1 else nz(trend[1], 1);
def FastAtrRsiTL = if trend == 1 then longband else shortband;
plot FastAtrRsiTL_plot = FastAtrRsiTL;
}
#//Credits to KivancOzbilgic
#qqeLine3(src, len, sf, qqe, qqeMaType) =>
script qqeLine3 {
input src = close;
input len = 14;
input sf = 5;
input qqe = 4.236;
input qqeMaType = yes;
def maType = qqeMaType;
def RSII = ma(qqeMaType,src,SF);
def TR = AbsValue(RSII-RSII[1]);
def wwalpha = 1/ len;
def WWMA;
WWMA = wwalpha*TR + (1-wwalpha)*nz(WWMA[1]);
def ATRRSI;
ATRRSI = wwalpha*WWMA + (1-wwalpha)*nz(ATRRSI[1]);
def QQEF = ma(qqeMaType,src,SF);
def QUP=QQEF+ATRRSI*4.236;
def QDN=QQEF-ATRRSI*4.236;
def QQES;
QQES = if QUP<nz(QQES[1]) then QUP else
if QQEF>nz(QQES[1]) and QQEF[1]<nz(QQES[1])then QDN else
if QDN>nz(QQES[1]) then QDN else
if QQEF<nz(QQES[1]) and QQEF[1]>nz(QQES[1]) then QUP else nz(QQES[1]);
plot return = QQES;
}
#//----Main Stuff
def baseline =
if qqeCalcMethod == qqeCalcMethod."QQE 1" then
qqeLine1(source,qqeLength,smoothening,qqe_factor,qqeMaType) else
if qqeCalcMethod == qqeCalcMethod."QQE 1" then
qqeLine2(source,qqeLength,smoothening,qqe_factor,qqeMaType) else
qqeLine3(source,qqeLength,smoothening,qqe_factor,qqeMaType);
#// ATR stuff
def tr = TrueRange(high, close, low);
def atr = ma(atrSmoothing, tr, atrlength);
#//Base Signals
#//Signals based on crossover
def base_cross_Long = Crosses(source, baseline, CrossingDirection.ABOVE);
def base_cross_Short = Crosses(baseline, source, CrossingDirection.ABOVE);
#//Signals based on signal position
def base_trend_Long = if baseline < source then 1 else 0;
def base_trend_Short = if baseline > source then 1 else 0;
#//ATR Check
def distBasefromPrice = AbsValue(baseline - source);
#//1 if more than ATR
def atrFail = if distBasefromPrice <= atr then 0 else 1;
#//Always 1, unless ATR fails
def allow_enter_ATR = if atrFail then 0 else 1;
def atrchecklocation =
if atrFail and base_trend_Long then baseline - (atr * (slMultiplier - tpMultiplier)) else
if atrFail and base_trend_Short then baseline + (atr * (slMultiplier - tpMultiplier)) else na;
def atr_top_1_time = source + (atr * tpMultiplier);
def atr_top_1_5_time = source + (atr * slMultiplier);
def atr_bottom_1_time = source - (atr * tpMultiplier);
def atr_bottom_1_5_time = source - (atr * slMultiplier);
#//Plots
def codiff = if base_cross_Long then 1 else
if base_cross_Short then -1 else na;
def color_bar = if source > baseline then 1 else 0;
#//Baseline Plots
plot arrowUp = if ShowArrow then if codiff > 0 then low else na else na;
arrowUp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
arrowUp.SetDefaultColor(Color.UPTICK);
plot arrowDn = if ShowArrow then if codiff < 0 then high else na else na;
arrowDn.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
arrowDn.SetDefaultColor(Color.DOWNTICK);
plot slowMAGlow = baseline; # "slow MA Glow"
slowMAGlow.AssignValueColor(if color_bar then GlobalColor("green") else GlobalColor("red"));
slowMAGlow.SetLineWeight(2);
def p2 = ohlc4;
AddCloud(if ShowQqeCloud then if color_bar then p2 else na else na, slowMAGlow, Color.DARK_GREEN);
AddCloud(if ShowQqeCloud then if !color_bar then slowMAGlow else na else na, p2, Color.DARK_RED);
AssignPriceColor(if !colorBar then Color.CURRENT else
if color_bar > 0 then Color.GREEN else Color.RED);
#//Plot Shape if price is more than 1 ATR from baseline
plot atrViolation = if showAtrViolation then atrchecklocation else na;
atrViolation.SetPaintingStrategy(PaintingStrategy.POINTS);
atrViolation.AssignValueColor(if atrViolation >= high then Color.RED else
if atrViolation <= low then Color.GREEN else Color.WHITE);
#//ATR Plots
def tp1 = if showAtrBand then atr_top_1_time else na; # "ATR Top 1"
#tp1.SetDefaultColor(CreateColor(33,150,243));
def tp2 = if showAtrBand then atr_bottom_1_time else na; # "ATR Bottom 1"
#tp2.SetDefaultColor(CreateColor(33,150,243));
def sl1 = if showAtrBand then atr_top_1_5_time else na; # "ATR Top 1.5"
#sl1.SetDefaultColor(Color.ORANGE);
def sl2 = if showAtrBand then atr_bottom_1_5_time else na; # "ATR Bottom 1.5"
AddCloud(sl1, tp1, Color.GRAY);
AddCloud(tp2, sl2, Color.GRAY);
#---- END