Repaints QQE MTF (Multi Timeframe) for ThinkorSwim

Repaints
Had this on the backburner for quite awhile and finally got off my lazy *** to clean it up a bit.(Searched and didn't see anyone post one yet, so hopefully I didn't miss it)

QQE indicator with a MTF spin on it. It has two variations with "1" being the faster one(6/3 2.621 settings) and "2" being the slower one(20/5/ 4.236 settings).

Time frames go in order of Bottom to top with bottom being the current timeframe you're on and working it's way upward. Default secondary timeframes are 15m and 30m.

Colors:
Green = Fast > Slower
Red = Fast < Slower
White = Fast < Slower and in Oversold Territory(Below 30)
Blue = Fast > Slower and in Overbought Territory(Above 70)

The last two colors only apply to the bottom row(current time frame) considering that I mainly use this for day trading on the 5m and those OS & OB areas help me a lot. I am currently back testing to see how often the same areas will work on higher time frames. Currently 15m is the top contender for being great for the colors, so I'll be more than likely adding in code to detect that aggregation period to allow it on the 15m.

I would also like to thank @BenTen for posting the QQE thread months ago which got me to start using QQE in the first place and testing to see what could be done with it in general to improve it.

Code:
#QQEV2 7/18/2020
#MTF QQE based off of the first version I made, Ended up sticking with only MTF and getting rid of the extra "Fib variations" for this version.
#Timeframes will go from Bottom to Top with the bottom being the current time frame
#Green = Fast > Slow and Blue indicates that Fast > Slow AND it's in overbought territory while white will indicate fast < slow and in oversold Territory.
#This feature will only appear for the current time ONLY, as I mainly use it to daytrade on the 5m where it helps me avoid sudden drops
#Author - Xiuying

#Update 10/05/2020 - Replaced the inputs to change the Slow/Fast/QQE with a simple Variation input. Input "1" shall be the usual fast 6/3 and anything not "1" will be the generic 20/5
#Update 11/07/2020 - Ended up changing the original lines that I had and switched to something simple like the MMARB that I imported, however the lines would be too "Trippy" so changed to singular bubbles

#Future - I plan on adding anothing feature based off of the trend that is usually associated with QQE, Going to do some more backtesting before I do so.

# The Original Base that this all started from was the one that Kory Gill converted for Benten at useThinkScript.com



declare lower;

input Variation =  1;
Input Agg2 = {"1 min", "3 min", "5 min", "10 min", default  "15 min", "30 min", "60 min", "120 min", "Daily", "Weekly", "Monthly"};
Input Agg3 = { "3 min", "5 min", "10 min", "15 min", default  "30 min", "60 min", "120 min", "Daily","Weekly", "Monthly"};


###Agg Code
def middleAggregation;

switch (Agg2) {
case "1 min":
    middleAggregation = AggregationPeriod.MIN;
case "3 min":
    middleAggregation = AggregationPeriod.THREE_MIN;
case "5 min":
    middleAggregation = AggregationPeriod.FIVE_MIN;
case "10 min":
    middleAggregation = AggregationPeriod.TEN_MIN;
case "15 min":
    middleAggregation = AggregationPeriod.FIFTEEN_MIN;
case "30 min":
    middleAggregation = AggregationPeriod.THIRTY_MIN;
case "60 min":
    middleAggregation = AggregationPeriod.HOUR;
case "120 min":
    middleAggregation = AggregationPeriod.TWO_HOURS;
case "Daily":
    middleAggregation = AggregationPeriod.DAY;
case "Weekly":
    middleAggregation = AggregationPeriod.WEEK;
case "Monthly":
    middleAggregation = AggregationPeriod.MONTH;
}

def highestAggregation;
switch (Agg3) {
case "3 min":
    highestAggregation = AggregationPeriod.THREE_MIN;
case "5 min":
    highestAggregation = AggregationPeriod.FIVE_MIN;
case "10 min":
    highestAggregation = AggregationPeriod.TEN_MIN;
case "15 min":
    highestAggregation = AggregationPeriod.FIFTEEN_MIN;
case "30 min":
    highestAggregation = AggregationPeriod.THIRTY_MIN;
case "60 min":
    highestAggregation = AggregationPeriod.HOUR;
case "120 min":
    highestAggregation = AggregationPeriod.TWO_HOURS;
case "Daily":
    highestAggregation = AggregationPeriod.DAY;
case "Weekly":
    highestAggregation = AggregationPeriod.WEEK;
case "Monthly":
    highestAggregation = AggregationPeriod.MONTH;
}

####

def RSI_Period = if Variation != 1 then 20 else 6;
def Slow_Factor = if Variation != 1 then 5 else 3;
def QQE = if Variation != 1 then 4.236 else 2.621;

def Wilder_Period = RSI_Period * 2 - 1;
def vClose = close;
def vClose15 = close(period = middleAggregation);
def vClose30 = close(period = highestAggregation);

def rsi = RSI(price = vClose, length = RSI_Period).RSI;
def rsi_ma = MovingAverage(AverageType.EXPONENTIAL, rsi, Slow_Factor);
def atr_rsi = AbsValue(rsi_ma[1] - rsi_ma);
def atr_rsi_ma = MovingAverage(AverageType.EXPONENTIAL, atr_rsi, Wilder_Period);
def dar = MovingAverage(AverageType.EXPONENTIAL, atr_rsi_ma, Wilder_Period) * QQE;

def DeltaFastAtrRsi = dar;
def RSIndex = rsi_ma;
def newshortband =  RSIndex + DeltaFastAtrRsi;
def newlongband = RSIndex - DeltaFastAtrRsi;

def longband = if RSIndex[1] > longband[1] and RSIndex > longband[1]
               then Max(longband[1], newlongband)
               else newlongband;

def shortband = if RSIndex[1] < shortband[1] and  RSIndex < shortband[1]
                then Min(shortband[1], newshortband)
                else newshortband;

def trend = if Crosses(RSIndex, shortband[1])
            then 1
            else if Crosses(longband[1], RSIndex)
            then -1
            else if !IsNaN(trend[1])
            then trend[1]
            else 1;

def FastAtrRsiTL = if trend == 1
                   then longband
                   else shortband;

def pFastAtrRsiTL = FastAtrRsiTL;
def pRsiMa = rsi_ma;
def line50 = 50;

##################
def rsi15 = RSI(price = vClose15, length = RSI_Period).RSI;
def rsi_ma15 = MovingAverage(AverageType.EXPONENTIAL, rsi15, Slow_Factor);
def atr_rsi15 = AbsValue(rsi_ma15[1] - rsi_ma15);
def atr_rsi_ma15 = MovingAverage(AverageType.EXPONENTIAL, atr_rsi15, Wilder_Period);
def dar15 = MovingAverage(AverageType.EXPONENTIAL, atr_rsi_ma15, Wilder_Period) * QQE;

def DeltaFastAtrRsi15 = dar15;
def RSIndex15 = rsi_ma15;
def newshortband15 =  RSIndex15 + DeltaFastAtrRsi15;
def newlongband15 = RSIndex15 - DeltaFastAtrRsi15;

def longband15 = if RSIndex15[1] > longband15[1] and RSIndex15 > longband15[1]
               then Max(longband15[1], newlongband15)
               else newlongband15;

def shortband15 = if RSIndex15[1] < shortband15[1] and  RSIndex15 < shortband15[1]
                then Min(shortband15[1], newshortband15)
                else newshortband15;

def trend15 = if Crosses(RSIndex15, shortband15[1])
            then 1
            else if Crosses(longband15[1], RSIndex15)
            then -1
            else if !IsNaN(trend15[1])
            then trend15[1]
            else 1;

def FastAtrRsiTL15 = if trend15 == 1
                   then longband15
                   else shortband15;

def pFastAtrRsiTL15 = FastAtrRsiTL15;
def pRsiMa15 = rsi_ma15;
def OS = 30;
def OB = 70;




##################

def rsi30 = RSI(price = vClose30, length = RSI_Period).RSI;
def rsi_ma30 = MovingAverage(AverageType.EXPONENTIAL, rsi30, Slow_Factor);
def atr_rsi30 = AbsValue(rsi_ma30[1] - rsi_ma30);
def atr_rsi_ma30 = MovingAverage(AverageType.EXPONENTIAL, atr_rsi30, Wilder_Period);
def dar30 = MovingAverage(AverageType.EXPONENTIAL, atr_rsi_ma30, Wilder_Period) * QQE;

def DeltaFastAtrRsi30 = dar30;
def RSIndex30 = rsi_ma30;
def newshortband30 =  RSIndex30 + DeltaFastAtrRsi30;
def newlongband30 = RSIndex30 - DeltaFastAtrRsi30;

def longband30 = if RSIndex30[1] > longband30[1] and RSIndex30 > longband30[1]
               then Max(longband30[1], newlongband30)
               else newlongband30;

def shortband30 = if RSIndex30[1] < shortband30[1] and  RSIndex30 < shortband30[1]
                then Min(shortband30[1], newshortband30)
                else newshortband30;

def trend30 = if Crosses(RSIndex30, shortband30[1])
            then 1
            else if Crosses(longband30[1], RSIndex30)
            then -1
            else if !IsNaN(trend30[1])
            then trend30[1]
            else 1;

def FastAtrRsiTL30 = if trend30 == 1
                   then longband30
                   else shortband30;

def pFastAtrRsiTL30 = FastAtrRsiTL30;
def pRsiMa30 = rsi_ma30;


##################
plot Five = 0;
plot Fifteen = 1;
plot Thirty = 2;


### Color Coding
Five.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
Five.AssignValueColor(if pfastAtrRsiTL < prsiMa and prsima > OB then color.blue else if pfastAtrRsiTL < prsiMa then color.green else if  prsima < OS then color.white else color.red);
Fifteen.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
Fifteen.AssignValueColor(if pfastAtrRsiTL15 < prsiMa15 then color.green else color.red);
Thirty.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
Thirty.AssignValueColor(if pfastAtrRsiTL30 < prsiMa30 then color.green else color.red);

Five.SetLineWeight(5);
Fifteen.SetLineWeight(5);
Thirty.SetLineWeight(5);

http://tos.mx/b0AAp9f

An Example from NVDA, We can see the higher Aggregation period is staying Green overall with a few dips on the lower 5m time frame I've been using.
I do plan on adding a "Flat" trend that QQE has to point out when a crossover could be occurring, but still figuring out a few more variables to that equation(I.E, Above or Below 50, How often they matter above 70 or below 30, etc etc)

QQEVExample.jpg
gr8 work
I think so many people selling this with different name
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Yea, you would just need to go into Studies and click the Cogwheel next to the indicator and change it to those periods. However, if you're current chart is on a higher time period, then the lower ones won't work.

However, I only have 1/3/5 as the smallest ones, don't have Two since I saw it as Redundant.
Good Evening---question of the MTFqqe? How have you kept the higher time frames from changing all the time?

I'm using the with a 1, 3, 5 minute set up and another programmer has suggested that the 3 and 5 will change all the time thus giving poor results. I've watched the screen for 6 hours and do not see the upper time changing ie the 3 or the 5 until new criterial is met.

Thanks in advance for your explanation.

Bob
 
Last edited by a moderator:
Good Evening---question of the MTFqqe? How have you kept the higher time frames from changing all the time?

I'm using the with a 1, 3, 5 minute set up and another programmer has suggested that the 3 and 5 will change all the time thus giving poor results. I've watched the screen for 6 hours and do not see the upper time changing ie the 3 or the 5 until new criterial is met.

Thanks in advance for your explanation.

Bob

Yes, scripts utilizing secondary timeframes repaint.
No, it is not possible to make repainters not repaint.

Think about it: the script is using the close of the 5-min candle on a 1-min chart.
BUT, there is no way of knowing what the close of the 5-min candle is going to be.

You have to wait FIVE candles for the 5-min candle to close; at which time, there will be a final repaint of those 5 dots.

1. On a 1-min chart, the script starts out with the value of the close of the previous 5-min candle.
2. Then it will update the next five candles on every tick (because in ToS, close is defined as the most recent price) for the next five minutes.
3. Then after five minutes, it goes back five candles and updates them, one last time, with the final close of that 5-min candle.

Yes, it is possible that there will not be a significant repainting of data for the dots to change color.
This is because the script is not just focused on the current candle.
def RSI_Period = if Variation != 1 then 20 else 6;
The above definition has the greatest effect on repainting. When the variation input is not equal to one, the calculations use the last 20 candles as lookback which mitigates the repainting of the last 5 candles.
Wilder's is weighted toward those 5 candles. But still, an additional 15 non-repainting bars are added to the calculation bringing some chance that the repainting will not be severe.

Obviously, on significant 5-min candles gaps with volatile stocks; it is possible to still have significant repainting.
It is never recommended to use repainters as triggers for entry.
 
Last edited by a moderator:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
366 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top