SuperTrend Of MACD and AVG RSI

MichaelSF

MichaelSF

New member
I was playing around with Mobius's original SuperTrend script recently -
https://usethinkscript.com/threads/supertrend-indicator-by-mobius-for-thinkorswim.7/

- and combining it with other popular indicators and found a couple of interesting results after a lot of tweaking and testing. Below is the first Indicator I tested this with; the MACD. It plots the MACD Diff Line (The Histogram Part) and uses that to calculate a SuperTrend "of" that line in order to smooth its movement. I'm sure that I'm not the first person to have done this, but I couldn't find a thread on here relating to it so here's my shot at it.

Code:
#SuperTrendOfMACD
#MichaelSF 2/2020
#Original SuperTrend Code By Mobius

declare lower;

## MACD ##
input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input averageType = AverageType.EXPONENTIAL;

def Value = MovingAverage(averageType, close, fastLength) - MovingAverage(averageType, close, slowLength);
def Avg = MovingAverage(averageType, Value, MACDLength);

plot MACDdiff = Value - Avg;
MACDdiff.SetPaintingStrategy(PaintingStrategy.LINE);

plot ZeroLine = 0;
ZeroLine.setDefaultColor(Color.dark_GRAY);

## SUPERTREND ##
input AtrMult = 1.0;
input nATR = 18;

def ATR = MovingAverage(AverageType.HULL, TrueRange(MACDdiff, MACDdiff, MACDdiff), nATR);
def UP = MACDdiff + (AtrMult * ATR);
def DN = MACDdiff + (-AtrMult * ATR);
def ST = if MACDdiff < ST[1] then UP else DN;

plot SuperTrend = ST;
SuperTrend.setDefaultColor(Color.dark_GRAY);

## COLORS & PLOTS ##

MACDDiff.AssignValueColor(if ST < MACDdiff then color.green else if ST > MACDdiff then color.red else color.Gray);

plot UpSignal = if ST crosses below MACDdiff then MACDdiff else Double.NaN;
plot DownSignal = if ST crosses above MACDdiff then MACDdiff else Double.NaN;
UpSignal.SetDefaultColor(Color.UPTICK);
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
DownSignal.SetDefaultColor(Color.DOWNTICK);
DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);


Above is an example of this indicator being used on SPY in combination with the normal RSI. I find it works best on extreme overbought/oversold conditions, which is why the RSI is a good pair with it.

Unsurprisingly, the next indicator I tried to convert to SuperTrend was the RSI. The thing with the RSI is that it tends to be very choppy, and SuperTrending it would just be a zig-zag mess of nothingness, which is pictured below. Still could be useful in some cases maybe, but too choppy to be reliable in my opinion.



The solution to this was creating a MovingAverage of the RSI, and then adding a SuperTrend calculated off of that line instead. Below is the result of this and the code for the script.



In the picture above its crosses were almost identical to the Original SuperTrend crosses, so I added another picture from a different day that shows it better below.
NOTE: I've found that when the Classic SuperTrend and AvgRSISuperTrend do line up it's actually a pretty good way of confirming a strong move, so if you choose to use this remember to look out for that.



Code:
#SuperTrendOfAvgRSI
#MichaelSF 2/2020
#Original SuperTrend Code By Mobius

declare lower;

## RSI ##
input AvgLength = 10;
input AvgType = AverageType.SIMPLE;
input price = close;

def NetChgAvg = MovingAverage(AverageType.WILDERS, price - price[1], 14);
def TotChgAvg = MovingAverage(AverageType.WILDERS, AbsValue(price - price[1]), 14);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;

def RSI = 50 * (ChgRatio + 1);

plot RSIAvg = MovingAverage(AvgType, RSI, Avglength);
RSIAvg.SetPaintingStrategy(PaintingStrategy.Line);

## SUPERTREND ##
input AtrMult = 1.0;
input nATR = 20;

def ATR = MovingAverage(AverageType.HULL, TrueRange(RSIAvg, RSIAvg, RSIAvg), nATR);
def UP = RSIAvg + (AtrMult * ATR);
def DN = RSIAvg + (-AtrMult * ATR);
def ST = if RSIAvg < ST[1] then UP else DN;

plot SuperTrend = ST;
SuperTrend.setDefaultColor(Color.dark_GRAY);

## COLORS ##
RSIAvg.AssignValueColor(if SuperTrend < RSIAvg then color.green else if SuperTrend > RSIAvg then color.red else color.Gray);

plot OverSold = 30;
OverSold.setDefaultColor(Color.dark_GRAY);
plot OverBought = 70;
OverBought.setDefaultColor(Color.dark_GRAY);

plot UpSignal = if ST crosses below RSIAvg then RSIAvg else Double.NaN;
plot DownSignal = if ST crosses above  RSIAvg then RSIAvg else Double.NaN;
UpSignal.SetDefaultColor(Color.UPTICK);
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
DownSignal.SetDefaultColor(Color.DOWNTICK);
DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
A few other things:
  • The colors on the chart are from the Mobius SuperTrend, not the indicators
  • The Settings on these indicators are what I found works best, but play around with them yourself to see if something works better for you.

Hopefully someone can find some use out of these. I've created a few strategies based on them and they ended up working pretty well.

Thank you to everyone that's apart of this community! Learned more than I could've imagined since finding this forum.
 
Last edited:
J

john3

Active member
2019 Donor
Warehouse
@MichaelSF Have you seen this contraption? It has everything, Superterend based on RSI, Ultimate and Chandelier.
Code:
## START STUDY
## SuperCombo Bull/Bear Indicator
## linus, 2014-07-24, v0.1

#hint: SuperTrend of price, RSI and Ultimate Oscillator, combined with Chandelier stops.

## Signal inputs:
input paintBars = {OFF, default DIR, STR};
input signals = {OFF, default ALL, ST, CS, RSI, UO};
input strength = {"1", "2", default "3", "4"};
input showLabel = Yes;
input showBubbles = Yes;
input showPrompt = Yes;

## SuperTrend of Price inputs:
input stATRMult = 3.5;
input stATRLength = 22;
input stATRType = AverageType.WILDERS;
input stPivot = hl2;

## Chandelier Stop inputs:
input csPeriod = 15;
input csATRLength = 5;
input csATRMult = 3.0;  
input csATRType = AverageType.SIMPLE;
input csShift = 1;
input csHideOpposite = Yes;

## SuperTrend of RSI inputs:
input rsiLength = 14;
input rsiPrice = close;
input rsiSmooth = 2;
input rsiSmoothType = AverageType.SIMPLE;
input rsiATRMult = 2.3;
input rsiATRLength = 25;
input rsiATRType = AverageType.WILDERS;

## SuperTrend of Ultimate Oscillator inputs:
input uoFastLen = 7;
input uoMedLen = 14;
input uoSlowLen = 28;
input uoATRMult = 2.8;
input uoATRLength = 3;
input uoATRType = AverageType.SIMPLE;

########################################
## SuperTrend of Price

def stATR = MovingAverage(stATRType, TrueRange(high, close, low), stATRLength) * stATRMult;

def stUp = stPivot + stATR;
def stDn = stPivot - stATR;

def rStTrend = compoundValue(1,
    if rStTrend[1] > 0 then
        if close < Max(stDn[1], rStTrend[1]) then -stUp
        else Max(stDn, rStTrend[1])
    else if rStTrend[1] < 0 then
        if close > Min(stUp[1], AbsValue(rStTrend[1])) then stDn
        else -Min(stUp, AbsValue(rStTrend[1]))
    else rStTrend[1]
, stPivot);

plot StTrend = if Sign(rStTrend) == Sign(rStTrend[1]) then absValue(rStTrend) else Double.NaN;
StTrend.DefineColor("Up", Color.CYAN);
StTrend.DefineColor("Dn", Color.MAGENTA);
StTrend.AssignValueColor(if rStTrend > 0 then StTrend.Color("Up") else StTrend.Color("Dn"));
StTrend.HideBubble();
StTrend.SetLineWeight(3);

########################################
## Chandelier_Stops

def csATR = MovingAverage(csATRType, TrueRange(high, close, low), csATRLength) * csATRMult;

def smax = Lowest(low, csPeriod)[csShift] + csATR[csShift];
def smin = Highest(high, csPeriod)[csShift] - csATR[csShift];

def rCSTrend = compoundValue(1, if close > smax[1] then 1 else if close < smin[1] then -1 else rCSTrend[1], 0);

def rUB = compoundValue(1, if rCSTrend > 0 then if smax > rUB[1] then smax else rUB[1] else if rCSTrend < 0 then if smax < rUB[1] then smax else rUB[1] else rUB[1], high);

def rLB = compoundValue(1, if rCSTrend < 0 then if smin < rLB[1] then smin else rLB[1] else if rCSTrend > 0 then if smin > rLB[1] then smin else rLB[1] else rLB[1], low);

plot UB = if !csHideOpposite or rCSTrend < 0 then rUB else Double.NaN;
UB.SetDefaultColor(Color.MAGENTA);
UB.SetLineWeight(3);
UB.SetStyle(Curve.SHORT_DASH);
UB.HideBubble();

plot LB = if !csHideOpposite or rCSTrend > 0 then rLB else Double.NaN;
LB.SetDefaultColor(Color.CYAN);
LB.SetLineWeight(3);
LB.SetStyle(Curve.SHORT_DASH);
LB.HideBubble();

########################################
## SuperTrend of RSI

def avgDif = WildersAverage(AbsValue(rsiPrice - rsiPrice[1]), rsiLength);
def RSI = MovingAverage(rsiSmoothType, 50 * ((if avgDif != 0 then WildersAverage(rsiPrice - rsiPrice[1], rsiLength) / avgDif else 0) + 1), rsiSmooth);

def rsiATR = MovingAverage(rsiATRType, TrueRange(Highest(RSI, ceil(rsiATRMult)), RSI, Lowest(RSI, ceil(rsiATRMult))), rsiATRLength) * rsiATRMult;
def rsiUp = RSI + rsiATR;
def rsiDn = RSI - rsiATR;

def rRSITrend = compoundValue(1,
    if rRSITrend[1] > 0 then
        if RSI < Max(rsiDn[1], rRSITrend[1]) then -rsiUp
        else Max(rsiDn, rRSITrend[1])
    else if rRSITrend[1] < 0 then
        if RSI > Min(rsiUp[1], AbsValue(rRSITrend[1])) then rsiDn
        else -Min(rsiUp, AbsValue(rRSITrend[1]))
    else rRSITrend[1]
, RSI);

########################################
## SuperTrend of Ultimate Oscillator

def TR = TrueRange(high, close, low);
def BP = close - Min(close[1], low);
def nFast = (uoSlowLen / uoFastLen);
def nMed = (uoSlowLen / uoMedLen);
def trFast = sum(TR, uoFastLen);
def trMed = sum(TR, uoMedLen);
def trSlow = sum(TR, uoSlowLen);

def UO = 100 * (((if trFast != 0 then (sum(BP, uoFastLen) / trFast) * nFast else 0)
    +  (if trMed != 0 then (sum(BP, uoMedLen) / trMed) * nMed else 0)
    + (if trSlow != 0 then (sum(BP, uoSlowLen) / sum(TR, uoSlowLen)) else 0))
/ (nFast + nMed + 1));

def uoATR = MovingAverage(uoATRType, TrueRange(Highest(UO, ceil(uoATRMult)), UO, Lowest(UO, ceil(uoATRMult))), uoATRLength) * uoATRMult;
def uoUp = UO + uoATR;
def uoDn = UO - uoATR;

def rUOTrend = compoundValue(1,
    if rUOTrend[1] > 0 then
        if UO < Max(uoDn[1], rUOTrend[1]) then -uoUp
        else Max(uoDn, rUOTrend[1])
    else if rUOTrend[1] < 0 then
        if UO > Min(uoUp[1], AbsValue(rUOTrend[1])) then uoDn
        else -Min(uoUp, AbsValue(rUOTrend[1]))
    else rUOTrend[1]
, UO);

########################################
## Signals

def orderDir;
def p;
def sumUp = (rStTrend > 0) + (rCSTrend > 0) + (rRSITrend > 0) + (rUOTrend > 0);
def sumDn = (rStTrend < 0) + (rCSTrend < 0) + (rRSITrend < 0) + (rUOTrend < 0);

switch (signals) {
case OFF:
    orderDir = 0;
    p = 0;
case ALL:
    orderDir = compoundValue(1, if sumUp >= strength+1 then 1 else if sumDn >= strength+1 then -1 else orderDir[1], 0);
    p = if showPrompt then 1 else 0;
case ST:
    orderDir = rStTrend;
    p = if showPrompt then 2 else 0;
case CS:
    orderDir = rCSTrend;
    p = if showPrompt then 3 else 0;
case RSI:
    orderDir = rRSITrend;
    p = if showPrompt then 4 else 0;
case UO:
    orderDir = rUOTrend;
    p = if showPrompt then 5 else 0;
}

def isOrder = orderDir crosses 0;

def orderCount = compoundValue(1, if isNaN(isOrder) then 0 else if isOrder then orderCount[1] + 1 else orderCount[1], 0);

def noBar = isNaN(open[-1]);

def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice[1];
def profitLoss = if !isOrder or orderCount == 1 then 0 else if orderDir > 0 then orderPrice[1] - orderPrice else if orderDir < 0 then orderPrice - orderPrice[1] else 0;
def profitLossSum = compoundValue(1, if isNaN(isOrder) then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);

AddLabel(signals and showLabel, (if p==1 then "ALL: " else if p==2 then "ST: " else if p==3 then "CS: " else if p==4 then "RSI: " else if p==5 then "UO: " else "") + orderCount + " orders | P/L " + AsDollars((profitLossSum / tickSize()) * tickValue()), if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY);

AddChartBubble(signals and showBubbles and isOrder and orderDir > 0, low, profitLoss, if noBar then Color.LIGHT_GRAY else Color.GREEN, 0);
AddChartBubble(signals and showBubbles and isOrder and orderDir < 0, high, profitLoss, if noBar then Color.GRAY else Color.RED, 1);

AssignPriceColor(if !paintBars then Color.CURRENT
else if paintBars == paintBars.DIR then
    if orderDir > 0 then
        if rSTTrend < 0 or rCSTrend < 0 then Color.DARK_ORANGE
        else Color.UPTICK
    else if orderDir < 0 then
        if rSTTrend > 0 or rCSTrend > 0 then Color.YELLOW
        else Color.DOWNTICK
    else Color.GRAY
else if sumUp >= strength+1 then Color.UPTICK
else if sumDn >= strength+1 then Color.DOWNTICK
else if sumUp > sumDn then Color.YELLOW
else if sumDn > sumUp then Color.DARK_ORANGE
else Color.GRAY);

## END STUDY
 
Last edited by a moderator:
horserider

horserider

Well-known member
VIP
How is this an ATR ?
def ATR = MovingAverage(AverageType.HULL, TrueRange(RSIAvg, RSIAvg, RSIAvg), nATR);
 
MichaelSF

MichaelSF

New member
How is this an ATR ?
def ATR = MovingAverage(AverageType.HULL, TrueRange(RSIAvg, RSIAvg, RSIAvg), nATR);
Yeah I'm sure it's not. I literally just spliced the MACD and RSI together with Mobius's code and got these indicators as the result, so it might be closer to a Moving Average than an ATR. It still ends up having unique smoothing similar to the Classic SuperTrend however, which is what I was going for.
 
Last edited:
H

HighBredCloud

Active member
@MichaelSF Which Mobius SuperTrend did you compare this to? The one below? The AVG RSI SuperTrend looks nice...I will have to test it out and see how it compares to standard Heikin Ashi.

Code:
# SuperTrend
# Mobius
# Chat Room Request
# 11.20.2019 tomsk Enhanced and adjusted bubbles with coloring and description tag

input AtrMult = 1.0;
input nATR = 4;
input AvgType = AverageType.HULL;
input PaintBars = yes;
input n = 0;
def n1  = n + 1;
def ATR = MovingAverage(AvgType, TrueRange(high, close, low), nATR);
def UP = HL2 + (AtrMult * ATR);
def DN = HL2 + (-AtrMult * ATR);
def ST = if close < ST[1] then UP else DN;
plot SuperTrend = ST;
SuperTrend.AssignValueColor(if close < ST then Color.RED else Color.GREEN);
AssignPriceColor(if PaintBars and close < ST
                 then Color.RED
                 else if PaintBars and close > ST
                      then Color.GREEN
                      else Color.CURRENT);

#AddChartBubble(close[n] crosses below ST[n], low[n+1] + TickSize() * n, "Sell @ " + low[n1], color.Cyan, yes);
#AddChartBubble(close[n] crosses above ST[n], high[n+1] - TickSize() * n, "Buy @ " + high[n1], color.Yellow, no);

# End Code SuperTrend
 
H

HighBredCloud

Active member
@HighBredCloud Yep, that's the one I based both on
Yeah that particular SuperTrend...IF you change the ATRMULT to .7 even .5 from 1.0 will hit faster for more precise results...Have you tested your RSIavg SuperTrend with such settings changed to see how it stacks up or what it can be improved...
 
horserider

horserider

Well-known member
VIP
If want a smoothed RSI not based on fuzzy calculations check the Derivative RSI.
 
MichaelSF

MichaelSF

New member
Yeah that particular SuperTrend...IF you change the ATRMULT to .7 even .5 from 1.0 will hit faster for more precise results...Have you tested your RSIavg SuperTrend with such settings changed to see how it stacks up or what it can be improved...
Yes, I did a lot of adjusting with different combinations of AtrMult and NAtr settings to see how it affected the quickness and effectiveness, but as I remember there wasn't anything that really stood out as a perfect setting for it. Keeping the AtrMult at 1.0 seems to be a good neutral level, but different settings work well for different tickers and timeframes.
 
Last edited:
MichaelSF

MichaelSF

New member
If want a smoothed RSI not based on fuzzy calculations check the Derivative RSI.
That looks like a good one too. Wasn't trying to say mine wasn't fuzzy, just thought id share it because I got some decent results with it.
 
retrobeast

retrobeast

New member
So there is 3 or 4 codes on this page. Which one is actually the one to use for trading futures or is it for stocks using a long time frame?
 
Last edited:

Top