RSI TrendLines with Breakouts For ThinkOrSwim

LPFibonacci317811

New member
A pivot-based breakout indicator that attempts to provide traders with a visual aid for finding breakouts on the RSI. Similar to how we use trendlines on our charts, using them on the Relative Strength Index can also give us a sense of direction in the markets.

This script uses its own pivot-based system that checks for real-time swing levels and triggers a new pivot event after every dip and nth bars. The breakout alerts that are given were not designed to be taken as signals since their purpose is to provide an extra bit of confluence. Because of this, I added no other conditions that try to make the alerts "perfect", but instead, print every breakout that is detected. Despite stating this, I did happen to add a condition that checks the difference in RSI and the breakout value, but that's as far as it'll go.

There are alerts built-in to the script, along with adjustable repainting options.

🔳 Settings
  • Lookback Range: Lookback period to trigger a new pivot point when conditions are met.
  • RSI Difference: The difference between the current RSI value and the breakout value. How much higher in value should the current RSI be compared to the breakout value in order to detect a breakout?
  • RSI Settings
  • Styling Options
🔳 Repaint Options
On: Allows repainting
Off - Bar Confirmation: Prevents repainting and generates alerts when the bar closes. (1 candle later)

🔳 How it Works
Before a trendline is drawn, the script retrieves the slope between the previous pivot point and the current. Then it adds or subtracts the slope x amount of times (based on the lookback range) from the current pivot value until the current x-axis is reached. By doing this we can get a trendline that will detect a breakout accurately.

ieH4mHN.png

Hi,

Can someone please help converting the following script from TradingView from HoanGhetti. I have attached a link and also pictures. Thanks.

LINK:https://www.tradingview.com/script/YcKrOcXe-RSI-Trendlines-with-Breakouts/

RSI Trendlines with Breakouts (HoanGhetti)
 
Last edited by a moderator:

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

check below with MTF, variety RSI and Divergence.

HeBQgFR.png


CODE:

CSS:
# https://www.tradingview.com/v/YcKrOcXe/
#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © HoanGhetti
# rsi types from @loxx - https://www.tradingview.com/v/iKTE0aCF/
#indicator("RSI Trendlines with Breakouts [HG]", precision = 2, max_labels_count = 500, max_lines_count = 500)
# Converted and mod by Sam4Cok@Samer800 - 07/2023 - Result may not be typical
declare lower;
input colorBreakoutBar = yes;
input useChartTimeframe =  {default"Yes", "No"};
input manualTimeframe   = AggregationPeriod.FIFTEEN_MIN;
input selectRSI = {default Regular, Slow, Rapid, Harris, "Ehlers Smoothed", RSX};
input LookbackRange = 4; # 'How many bars to determine when a swing high/low is detected.'
input repaint = yes;
input rsiSource = close;
input rsiLength = 14;
input overbought = 70;
input oversold   = 30;
input rsiDifference = 3; # 'The difference between the current RSI value and the breakout value'
input ShowBrakouts = yes;
input alerts   = yes;
input alertType = Alert.BAR;
input sound     = Sound.NoSound;

#-- MTF
def c; def h; def l;
Switch (useChartTimeframe) {
case "Yes" :
    c = rsiSource;
    h = high;
    l = low;
case "No"  :
    c = close(Period=manualTimeframe);
    h = high(Period=manualTimeframe);
    l = low(Period=manualTimeframe);
}
# //Regular RSI, same as ta.rsi(src, per)
script rsi_rsi {
    input src = close;
    input per = 14;
    def alpha = 1.0 / Max(per, 1);
    def change = src - src[1];
    def _change = _change[1] + alpha * (change  - _change[1]);
    def _changa = _changa[1] + alpha * (AbsValue(change) - _changa[1]);
    def out = if _changa != 0 then 50 * (_change / _changa + 1) else 50;
    plot rsi_rsi = out;
}
#// rsx RSI
script rsi_rsx {
    input src = close;
    input len = 14;
    def nRSI = RSI(Price = src, Length = len);
    def src_out = 100 * src;
    def mom0 = (src_out - src_out[1]);
    def moa0 = AbsValue(mom0);
    def Kg = 3 / (len + 2.0);
    def Hg = 1 - Kg;
    def f28 = CompoundValue(1, Kg * mom0 + Hg * f28[1], nRSI);
    def f30 = CompoundValue(1, Hg * f30[1] + Kg * f28, nRSI);
    def mom1 = f28 * 1.5 - f30 * 0.5;
    def f38 = CompoundValue(1, Hg * f38[1] + Kg * mom1, nRSI);
    def f40 = CompoundValue(1, Kg * f38 + Hg * f40[1], nRSI);
    def mom2 = f38 * 1.5 - f40 * 0.5;
    def f48 = CompoundValue(1, Hg * f48[1] + Kg * mom2, nRSI);
    def f50 = CompoundValue(1, Kg * f48 + Hg * f50[1],  nRSI);
    def mom_out = f48 * 1.5 - f50 * 0.5;
    def f58 = CompoundValue(1, Hg * f58[1] + Kg * moa0, nRSI);
    def f60 = CompoundValue(1, Kg * f58 + Hg * f60[1], nRSI);
    def moa1 = f58 * 1.5 - f60 * 0.5;
    def f68 = CompoundValue(1, Hg * f68[1] + Kg * moa1, nRSI);
    def f70 = CompoundValue(1, Kg * f68 + Hg * f70[1], nRSI);
    def moa2 = f68 * 1.5 - f70 * 0.5;
    def f78 = CompoundValue(1, Hg * f78[1] + Kg * moa2, nRSI);
    def f80 = CompoundValue(1, Kg * f78 + Hg * f80[1], nRSI);
    def moa_out = f78 * 1.5 - f80 * 0.5;
    def rsiout = Max(Min((mom_out / moa_out + 1.0) * 50.0, 100), 0);
    plot rsx = rsiout;
}
#// Slow RSI
script rsi_slo {
    input src = close;
    input per = 14;
    def _rsival;
    def nRSI = RSI(Price = src, Length = per);
    def up = fold k = 0 to per with p do
                if (src[k] - GetValue(src, k + 1)) > 0 then p + (src[k] - GetValue(src, k + 1)) else p;
    def dn = fold i = 0 to per with q do
                if (src[i] - GetValue(src, i + 1)) > 0 then q else q - (src[i] - GetValue(src, i + 1));
    if (up + dn == 0) {
        _rsival = CompoundValue(1, _rsival[1] + (1 / Max(per, 1)) * (50 - _rsival[1]), nRSI);
    } else {
        _rsival = CompoundValue(1, _rsival[1] + (1 / Max(per, 1)) * (100 * up / (up + dn) - _rsival[1]), nRSI);
    }
    plot out = _rsival;
}
#// Rapid RSI, same as Cuttlers RSI
script rsi_rap {
    input src = close;
    input per = 14;
    def up = fold k = 0 to per with p do
                if (src[k] - GetValue(src, k + 1)) > 0 then p + (src[k] - GetValue(src, k + 1)) else p;
    def dn = fold i = 0 to per with q do
                if (src[i] - GetValue(src, i + 1)) > 0 then q else q - (src[i] - GetValue(src, i + 1));
    def out = if (up + dn) == 0 then 50 else 100 * up / (up + dn);
    plot rsi_rap = out;
}
#// Harris RSI
script rsi_har {
    input src = close;
    input per = 14;
    def avUp = fold k = 0 to per with p do
                if (src[k] - GetValue(src, k + 1)) > 0 then p + (src[k] - GetValue(src, k + 1)) else p;
    def avDn = fold i = 0 to per with q do
                if (src[i] - GetValue(src, i + 1)) > 0 then q else q - (src[i] - GetValue(src, i + 1));
    def Up    = fold k1 = 0 to per with p1 do
                if (src[k1] - GetValue(src, k1 + 1)) > 0 then p1 + 1 else p1;
    def Dn    = fold i1 = 0 to per with q1 do
                if (src[i1] - GetValue(src, i1 + 1)) > 0 then q1 else q1 + 1;
    def avgUp = if (Up != 0) then avUp / Up else avgUp[1];
    def avgDn = if (Dn != 0) then avDn / Dn else avgDn[1];
    def rs = if rs[1] == 0 then 1 else
             if avgDn != 0 then avgUp / avgDn else rs[1];
    def out = 100 - 100 / (1.0 + rs);
    plot rsi_har = out;
}
# //Ehlers' Smoothed RSI
script rsi_ehl {
    input src = close;
    input per = 14;
    def bar_index = if IsNaN(close) then bar_index[1] else bar_index[1] + 1;
    def _src = if (bar_index > 2) then (src + 2 * src[1] + src[2]) / 4.0 else src;
    def Up = fold k = 0 to per with p do
                if (_src[k] - GetValue(_src, k + 1)) > 0 then p + (_src[k] - GetValue(_src, k + 1)) else p;
    def Dn = fold i = 0 to per with q do
                if (_src[i] - GetValue(_src, i + 1)) > 0 then q else q - (_src[i] - GetValue(_src, i + 1));
    def out = 50 * (Up - Dn) / (Up + Dn) + 50;
    plot rsi_ehl = out;
}
def Regular = rsi_rsi(c, rsiLength);
def Slow    = rsi_slo(c, rsiLength);
def Rapid   = rsi_rap(c, rsiLength);
def Harris  = rsi_har(c, rsiLength);
def Ehlers  = rsi_ehl(c, rsiLength);
def RSX     = rsi_rsx(c, rsiLength);

def nRSI;
switch (selectRSI) {
case Regular :
    nRSI = Regular;
case Slow    :
    nRSI = Slow;
case Rapid   :
    nRSI = Rapid;
case Harris  :
    nRSI = Harris;
case "Ehlers Smoothed" :
    nRSI = Ehlers;
case RSX     :
    nRSI = RSX;
}

plot rsiLine = nRSI;
rsiLine.SetLineWeight(2);
rsiLine.SetDefaultColor(Color.WHITE);

def na = Double.NaN;
def last = IsNaN(close);
def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;

plot OB = if last then na else overbought;     # 'OVERBOUGHT'
plot OS = if last then na else oversold;       # 'OVERSOLD'
plot midLine = if last then na else 50;        # "Middle Line"
midLine.SetStyle(Curve.SHORT_DASH);
midLine.SetDefaultColor(Color.DARK_GRAY);
ob.SetDefaultColor(Color.DARK_GRAY);
os.SetDefaultColor(Color.DARK_GRAY);

AddCloud(OB, OS, CreateColor(76,10,127));

#----------------------------
#//----
script fixnan {
    input source = close;
    def fix = if !IsNaN(source) then source else fix[1];
    plot result = fix;
}
script FindPivots {
    input dat = close; # default data or study being evaluated
    input HL  = 0;    # default high or low pivot designation, -1 low, +1 high
    input lbL  = 1;    # default Pivot Lookback Left
    input lbR  = 1;    # default Pivot Lookback Right
    ##############
    def _nan;    # used for non-number returns
    def _BN;     # the current barnumber
    def _VStop;  # confirms that the lookforward period continues the pivot trend
    def _V;      # the Value at the actual pivot point
    ##############
    _BN  = CompoundValue(1, BarNumber(), 0);
    _nan = Double.NaN;
    _VStop = if !IsNaN(dat) and lbR > 0 and lbL > 0 then
                fold a = 1 to lbR + 1 with b=1 while b do
                    if HL > 0 then dat > GetValue(dat, -a) else dat < GetValue(dat, -a) else _nan;
    if (HL > 0) {
        _V = if _BN > lbL and dat == Highest(dat, lbL + 1) and _VStop
            then dat else _nan;
    } else {
        _V = if _BN > lbL and dat == Lowest(dat, lbL + 1) and _VStop
            then dat else _nan;
    }
    plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
def ph = fixnan(findpivots(nRSI,  1, 1, LookbackRange));
def pl = fixnan(findpivots(nRSI, -1, 1, LookbackRange));
script pivot {
    input rsi = close;
    input LookbackPeriod = 4;
    input pType = 1;
    input ph = close;
    input pl = close;
    input rsiDiff = 3;
    input repaint = yes;
    def na = Double.NaN;
    def bar_index = CompoundValue(1, BarNumber(), 0);
    def pvtL = pType < 0;
    def pivot = if pvtL then pl else ph;
    def change = pivot != pivot[1];
    def xAxis0 = if change then bar_index else xAxis0[1];
    def xAxis1 = if xAxis0 != xAxis0[1] then xAxis0[1] else xAxis1[1];
    def xAxis = xAxis0 - xAxis1;
    def prevPivot0 = if change then pivot[1] else prevPivot0[1];
    def prevPivot = if prevPivot0 != prevPivot0[1] then prevPivot0[1] else prevPivot[1];
    def pivotCond = change and (if pvtL then pivot > prevPivot else pivot < prevPivot);
    def slopePre;
    def validElements;
    def y1;
    def y2;
    def Slope;
    if pivotCond {
        slopePre = (pivot - prevPivot) / xAxis;
        validElements = fold i = 0 to LookbackPeriod with p=1 while p do
                    if pvtL then GetValue(rsi, LookbackPeriod - i) >= (pivot + (slopePre * i))
                            else GetValue(rsi, LookbackPeriod - i) <= (pivot + (slopePre * i));
        if validElements {
            y1     = prevPivot;
            y2     = pivot;
            Slope = (y2 - y1) / xAxis;
        } else {
            y1     = y1[1];
            y2     = y2[1];
            Slope = Slope[1];
        }
    } else {
        slopePre = na;#slope[1];
        validElements = na;#validElements[1];
        y1 = y1[1];
        y2 = y2[1];
        Slope = Slope[1];
    }
    def y1Change = (y1 != y1[1]);
    def changeInX = if y1Change then 0 else  changeInX[1] + 1;
    def trendLine;
    def label;
    def Crossed;
    def hasCrossed;
    if y1Change {
        Crossed = no;
    } else {
        Crossed = hasCrossed[1];
    }
    def data = if !Crossed then y2 + (Slope * changeInX) else data[1];
    def condType = (if pvtL then rsi < (data - rsiDiff) else rsi > (data + rsiDiff)) and !Crossed;
    def condition = if repaint then condType else (condType and !IsNaN(close));
    if condition {
        hasCrossed = yes;
        trendLine = y2;
        label     = yes;
    } else {
        hasCrossed = Crossed;
        trendLine = data;
        label     = na;
    }
    plot pData = if trendLine == rsi or trendLine >= 100 or trendLine <= 0 or hasCrossed then na else trendLine;
    plot breakout = if label then data else na;
}
def UpValue = pivot(nRSI, LookbackRange,  1, ph, pl, rsiDifference, repaint).pData;
def DnValue = pivot(nRSI, LookbackRange, -1, ph, pl, rsiDifference, repaint).pData;
def BreakUp = pivot(nRSI, LookbackRange,  1, ph, pl, rsiDifference, repaint).breakout;
def BreakDn = pivot(nRSI, LookbackRange, -1, ph, pl, rsiDifference, repaint).breakout;

def UpPH = UpValue;
def LoLH = DnValue;
def UpBreak = BreakUp;
def LoBreak = BreakDn;

#-------- Breakout Bubbles
AddChartBubble(ShowBrakouts and UpBreak, UpBreak, "Break", Color.CYAN, no);
AddChartBubble(ShowBrakouts and LoBreak, LoBreak, "Break", Color.MAGENTA, yes);

AssignPriceColor(if !colorBreakoutBar then Color.CURRENT else
                 if !IsNaN(UpBreak) then Color.CYAN else
                 if !IsNaN(LoBreak) then Color.MAGENTA else Color.CURRENT);
#//----
plot upperPH = UpPH;
upperPH.SetDefaultColor(Color.GREEN);

plot LowerLH = LoLH;
LowerLH.SetDefaultColor(Color.RED);

#---- Alerts
Alert(alerts and UpBreak, "Break Up!", alertType, sound);
Alert(alerts and LoBreak, "Break Down!", alertType, sound);

#----Div-----------
input MaxLookback = 60;   # "Max of Lookback Range"
input DivBull = no;       # "Plot Bullish"
input DivHiddenBull = no; # "Plot Hidden Bullish"
input DivBear = no;       # "Plot Bearish"
input DivHiddenBear = no; # "Plot Hidden Bearish"

def divSrc = nRSI;

#_inRange(cond) =>
script _inRange {
    input cond = yes;
    input rangeUpper = 60;
    input rangeLower = 5;
        def bars = if cond then 0 else bars[1] + 1;
        def inrange =  (rangeLower <= bars) and (bars <= rangeUpper);
plot retrun = inRange;
}
def pld = findpivots(divSrc,-1, LookbackRange, LookbackRange);
def phd = findpivots(divSrc, 1, LookbackRange, LookbackRange);

def plFound = if !isNaN(pld) then 1 else 0;
def phFound = if !isNaN(phd) then 1 else 0;

def lFound = if plFound then divSrc else lFound[1];
def vlFound = if lFound!=lFound[1] then lFound[1] else vlFound[1];

def hFound = if phFound then divSrc else hFound[1];
def vhFound = if hFound!=hFound[1] then hFound[1] else vhFound[1];

def lPrice = if plFound then l else lPrice[1];
def plPrice = if lPrice!=lPrice[1] then lPrice[1] else plPrice[1];

def hPrice = if phFound then h else hPrice[1];
def phPrice = if hPrice!=hPrice[1] then hPrice[1] else phPrice[1];

#// Regular Bullish
def oscHL = divSrc > vlFound and  _inRange(plFound[1],MaxLookback,LookbackRange);
def priceLL = l < plPrice;
def bullCond = DivBull and plFound and oscHL and priceLL;
#// Hidden Bullish
def oscLL = divSrc < vlFound and  _inRange(plFound[1],MaxLookback,LookbackRange);
def priceHL = l > plPrice;
def hiddenBullCond = DivHiddenBull and plFound and oscLL and priceHL;

#// Regular Bearish
def oscLH   = divSrc < vhFound and  _inRange(phFound[1],MaxLookback,LookbackRange);
def priceHH = h > phPrice;
def bearCond = DivBear and phFound and oscLH and priceHH;
#// Hidden Bearish
def oscHH = divSrc > vhFound and  _inRange(phFound[1],MaxLookback,LookbackRange);
def priceLH = h < phPrice;
def hiddenBearCond = DivHiddenBear and phFound and oscHH and priceLH;

#------ Bubbles
addchartbubble(bullCond, divSrc, "R", color.GREEN, no);
addchartbubble(bearCond, divSrc, "R", Color.RED, yes);
addchartbubble(hiddenBullCond, divSrc, "H", color.DARK_green, no);
addchartbubble(hiddenBearCond, divSrc, "H", color.DARK_red, yes);

#----End of Code
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
434 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