Haydens RSI Companion
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Editor: © BarefootJoey
// Authors: © dgtrd, LonesomeTheBlue, TradeChartist, mmoiwgg, TradingView,
//            and a couple of authors that need identification.
//                      
//@version=5
indicator("Hayden's Advanced Relative Strength Index (RSI) Companion", 'Hayden\s RSI Companion', overlay=true, max_bars_back=1000)

//-------------------------🦶 BarefootJoey Theme------------------------------//
// Gradient Bull/Bear
brightgreen = #00ff0a
green = color.green
darkgreen = #1b5e20
brightred = #ff1100
red = color.red
darkred = #801922
// Other
yellow = #ffe500
fuchsia = #da00ff
blue = #0006ff
aqua = #00ffef
orange = color.orange
gray = color.gray
grayishgreen = #a5d6a7
grayishred = #faa1a4

// Groups
grrsi = '📈 Relative Strength Index 📈'
grmtfma = '⏰ MTF Moving Averages ⏰'
grppl = '🔖 Price Pivot Labels 🔖' // label emoji appears unicode instead of emoji on some devices
grtl = "📐 Trend Lines 📐"
//grsx = "🧰 Stochastic [X] 🧰"
grhts = '🚦 Hayden Trend State 🚦'
grhaco = "🧨 Heiken Ashi Candle Overlay 🧨" // candle emoji appears unicode instead of emoji on some devices
grdv = '🔀 Divergences 🔀'
grfrt = '🧬 Fibonacci Retracements 🧬'
grwm = '✍ Watermark ✍ '
grtk = "🎰 Tickers 🎰"

// Default Variables
pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062

// ------------------------------------- RSI -------------------------------- //
rsisrc = input.source(close, "Source", group=grrsi)
prsilen = input.int(14, "RSI Length", group=grrsi, tooltip="For best results, these RSI settings should match the same settings used in Hayden's Advanced RSI oscillator.\nThis RSI length applies to all RSI functions in this chart indicator.")

//--------------------------------Moving Averages-----------------------------//
// Code Author: © TradingView
resCustom = input.timeframe(title='MTF MA\s Timeframe', defval='W', group=grmtfma)
showgaps = input(false, "Show MTF MA Gaps?", group=grmtfma, tooltip="Check this box for a smooth MTF MA line. The tradeoff is that it lags.")
// Fast MA
fastma = ta.sma(close, 9)
fastcol = fastma>fastma[1] ? green : fastma<fastma[1] ? red : gray
fastcolv = fastma>fastma[1] ? brightgreen : fastma<fastma[1] ? brightred : gray
// MTF Fast MA
fastma2 = request.security(syminfo.tickerid, resCustom, ta.sma(close,9), gaps=showgaps ? barmerge.gaps_on : barmerge.gaps_off)
fastcol2 = fastma2>fastma2[1] ? green : fastma2<fastma2[1] ? red : gray
// Slow 45 WMA/EMA
r45ma = input.string('WMA', title='45 WMA or EMA?', options=['WMA', 'EMA'], group=grmtfma, tooltip='There is some inconsistency in the book due to charts (Appendix C) citing use of a 45 EMA on RSI, and text (page 107 & 108) citing use of a 45 WMA on RSI. Take your pick.')
slowema = ta.ema(close, 45)
slowwma = ta.wma(close, 45)
slowmaout = r45ma == 'WMA' ? slowwma : slowema
slowcol = slowmaout>slowmaout[1] ? green : slowmaout<slowmaout[1] ? red : gray
slowcolv = slowmaout>slowmaout[1] ? brightgreen : slowmaout<slowmaout[1] ? brightred : gray
// MTF Slow 45 WMA/EMA
r45ma2 = input.string('WMA', title='MTF 45 WMA or EMA?', options=['WMA', 'EMA'], group=grmtfma, tooltip='There is some inconsistency in the book due to charts (Appendix C) citing use of a 45 EMA on RSI, and text (page 107 & 108) citing use of a 45 WMA on RSI. Take your pick.')
slowwma2 = request.security(syminfo.tickerid, resCustom, ta.wma(close,45), gaps=showgaps ? barmerge.gaps_on : barmerge.gaps_off)
slowema2 = request.security(syminfo.tickerid, resCustom, ta.ema(close,45), gaps=showgaps ? barmerge.gaps_on : barmerge.gaps_off)
slowmaout2 = r45ma2 == 'WMA' ? slowwma2 : slowema2
slowcol2 = slowmaout2>slowmaout2[1] ? green : slowmaout2<slowmaout2[1] ? red : gray
// River MA
riverlen = input(89, title="89 EMA Length", group=grmtfma, tooltip="Popular: 100, 144, 200, 233")
riverdisp = input.string("_____", title="89 EMA Display", options=["_____","-----","∙∙∙∙∙","None"], group=grmtfma)
riverglow = input.string("Normal", "89 EMA Color", options=["Normal", "Electric"], group=grmtfma, 
  tooltip="Normal is just a single aqua/orange line. Electric applies a thick & transparent blue/red line over the normal line to give the combination a glowing neon look.")
river = ta.ema(close, riverlen)
rivercol = river>river[1] ? aqua : river<river[1] ? orange : gray
rivercol2 = river>river[1] ? green : river<river[1] ? red : gray
// MTF River MA
riverlen2 = input(200, title="MTF 89 EMA Length", group=grmtfma)
river2 = request.security(syminfo.tickerid, resCustom, ta.ema(close, riverlen2), gaps=showgaps ? barmerge.gaps_on : barmerge.gaps_off)
fastfill = plot(fastma, '9 SMA', color=color.new(fastcol, 10))
slowfill = plot(slowmaout, '45 WMA', color=color.new(slowcol, 10))
fill(fastfill, slowfill, color=color.new(fastma>slowmaout ? green : red, 85))
plot(riverdisp=="_____"?river:na, '89 EMA', color=color.new(rivercol,10), linewidth=1, editable=false)
plot(riverdisp=="_____" and riverglow=="Electric"?river:na, '89 EMA Glow', color=color.new(rivercol2,60), linewidth=3, editable=false)
plotchar(riverdisp=="-----"?river:na, "Dashed 89 EMA", char="–", location=location.absolute, color=color.new(rivercol,10), editable=false)
plotchar(riverdisp=="∙∙∙∙∙"?river:na, "Dotted 89 EMA", char="∙", location=location.absolute, color=color.new(rivercol,10), editable=false)
fastfill2 = plot(fastma2, 'MTF 9 SMA', color=color.new(gray, 10), display=display.none, linewidth=1)
slowfill2 = plot(slowmaout2, 'MTF 45 WMA', color=color.new(gray, 10), display=display.none, linewidth=2) 
plot(river2, 'MTF 89 EMA', color=color.new(gray,10), display=display.none, linewidth=3)

//-------------------------------Pivots---------------------------------------//
// Code Author: © mmoiwgg
showperc = input(defval=true, title='Show Price Pivot Labels?', group=grppl, tooltip="Hover over labels for additional info. \nThese labels might repaint up to a length of ZigZag Period or Bars to the Left # of bars. ")
upcolor = input(defval=green, title='Bullish Color', group=grppl)
downcolor = input(defval=red, title='Bearish Color', group=grppl)
// Pivot Lookback
leftbars = input.int(8, minval=1, title='Bars to the left', group=grppl)
rightbars = input.int(8, minval=1, title='Bars to the right', group=grppl)

// Pivot Prices
phigh = ta.pivothigh(high, leftbars, rightbars)
plow = ta.pivotlow(low, leftbars, rightbars)

//Pivot %
//Inputs
zigperiod = input(defval=13, title='ZigZag Period', group=grppl, tooltip="The higher the number, the fewer the labels")
pppsize = input.string(size.small, title="Price & Percent Change Pivots Label Size", options=[size.normal, size.small, size.tiny], group=grppl)
percentdecimals = input.int(defval=2, title='% Decimals', minval=0, maxval=10, group=grppl, tooltip="This % Decimals value also applies to the Ticker")
pricedecimals = input.int(defval=2, title='Price Decimals', minval=0, maxval=10, group=grppl, tooltip="This Price Decimals value also applies to the Ticker")
showline = false 
zigstyle = input.string(defval='-----', title='Zig Zag Line Style', options=['.....', '-----'], group=grppl)
zigwidth = 1 
elen = 5 
esrc = close 
out = ta.ema(esrc, elen)
prsi = ta.rsi(rsisrc,prsilen)
rsi = ta.rsi(rsisrc,prsilen)

//Float
float highs = ta.highestbars(close, zigperiod) == 0 ? close : na
float lows = ta.lowestbars(close, zigperiod) == 0 ? close : na

//Variables
var dir1 = 0
iff_1 = lows and na(highs) ? -1 : dir1
dir1 := highs and na(lows) ? 1 : iff_1

var max_array_size = 10
var ziggyzags = array.new_float(0)

add_to_zigzag(pointer, value, bindex) =>
    array.unshift(pointer, bindex)
    array.unshift(pointer, value)
    if array.size(pointer) > max_array_size
        array.pop(pointer)
        array.pop(pointer)

update_zigzag(pointer, value, bindex, dir) =>
    if array.size(pointer) == 0
        add_to_zigzag(pointer, value, bindex)
    else
        if dir == 1 and value > array.get(pointer, 0) or dir == -1 and value < array.get(pointer, 0)
            array.set(pointer, 0, value)
            array.set(pointer, 1, bindex)
        0.
        
// Number of Decimals for Labels
truncatepercent(number, percentdecimals) =>
    factor = math.pow(10, percentdecimals)
    int(number * factor) / factor

percenttruncate(number, percentdecimals) =>
    factor = math.pow(10, percentdecimals)
    int(number * factor) / factor
    
truncateprice(number, pricedecimals) =>
    factor = math.pow(10, pricedecimals)
    int(number * factor) / factor
    
percent(n1, n2) =>
    ((n1 - n2) / n2) * 100

dir1changed = ta.change(dir1)
if highs or lows
    if dir1changed
        add_to_zigzag(ziggyzags, dir1 == 1 ? highs : lows, bar_index)
    else
        update_zigzag(ziggyzags, dir1 == 1 ? highs : lows, bar_index, dir1)
        
// Retrace Targets: (A-C)+B script, see book page 75: "We can also calculate the upside target by obtaining the difference between points "B" and "Ref'
rtt = (ta.valuewhen(highs or lows,close,2) - ta.valuewhen(highs or lows,close,0)) + ta.valuewhen(highs or lows,close,1)
// Stop Loss: Calculated as the high for the leftbars variable ('Bars to the left' setting)
lsl = ta.lowest(low,leftbars)
ssl = ta.highest(high,leftbars)

if array.size(ziggyzags) >= 6
    var line zzline1 = na
    var label zzlabel1 = na
    float val = array.get(ziggyzags, 0) 
    int point = math.round(array.get(ziggyzags, 1))
    if ta.change(val) or ta.change(point)
        float val1 = array.get(ziggyzags, 2) 
        int point1 = math.round(array.get(ziggyzags, 3))
        plabel = "∆y " + str.tostring(percenttruncate(val-val1,percentdecimals)) 
          + ", " + str.tostring(percenttruncate(percent(val, val1),percentdecimals)) + ' %' // ∴ instead of ,
          // Change in X
          + "\n⏱ ∆x " + str.tostring(point - point1) + " bars"
          // RSI
          + "\n📍 RSI " + str.tostring(percenttruncate(prsi,percentdecimals))
          // Targets
          + "\n🎯 " + str.tostring(rtt) + ", " +str.tostring(percenttruncate(percent(rtt, ta.valuewhen(highs or lows,close,0)),percentdecimals)) + " %" 
          // Stop
          + "\n🛑 " + str.tostring(highs?ssl:lsl) + ", " +str.tostring(percenttruncate(percent(highs?ssl:lsl, ta.valuewhen(highs or lows,close,0)),percentdecimals)) + " %" 
        
        if ta.change(val1) == 0 and ta.change(point1) == 0
            line.delete(zzline1)
            label.delete(zzlabel1)
        if showline
            zzline1 := line.new(x1=point, x2=point1, y1=val, y2=val1, color=dir1 == 1 ? upcolor : downcolor, width=zigwidth, style=zigstyle == '-----' ? line.style_dashed : line.style_dotted)
            zzline1
        labelcol = dir1 == 1 ? array.get(ziggyzags, 0) > out ? upcolor : downcolor : array.get(ziggyzags, 0) < out ? downcolor : upcolor
        if showperc
            zzlabel1 := label.new(x=point, y=val, text=str.tostring(truncateprice(close,pricedecimals)), size=pppsize, color=color.new(labelcol, 100), textcolor=dir1 == 1 ? downcolor : upcolor, style=dir1 == 1 ? label.style_label_down : label.style_label_up, tooltip=plabel)
            zzlabel1

//-------------------------Heiken Ashi Candles--------------------------------//
// Code Author: © ?
// Optional Mathmatical Calcualtion to avoid the security function 
hkClose         = (open + high + low + close) / 4
hkOpen          = float(na)
hkOpen          := na(hkOpen[1]) ? (open + close) / 2 : (nz(hkOpen[1]) + nz(hkClose[1])) / 2
hkHigh          = math.max(high, math.max(hkOpen, hkClose))
hkLow           = math.min(low,  math.min(hkOpen, hkClose))

candletype      = input.string  ("None",      
  "Candle Type",  
  options = ["Hollow", "Bars", "Candles", "None"],      
  group = grhaco, 
  tooltip = "User will have to 'Mute' the main series bar using the 👁 symbol when hovering over ticker id. The Complete RSI book pg 25: 'Build a chart using Japanese Candlesticks in whatever timeframe you prefer, print 30 pages of charts, identify the tops and bottoms, and begin looking for candlestick patterns.'")

BodyBull        = input.color   (brightgreen,       "Body",             inline="a",         group=grhaco)
BodyBear        = input.color   (brightred,       "Body",             inline="a",         group=grhaco)
BorderBull      = input.color   (color.new(brightgreen,100),       "Border",             inline="b",         group=grhaco)
BorderBear      = input.color   (color.new(brightred,100),       "Border",             inline="b",         group=grhaco)
WickBull        = input.color   (brightgreen,       "Wick",             inline="c",         group=grhaco)
WickBear        = input.color   (brightred,       "Wick",             inline="c",         group=grhaco)

hollow          = candletype == "Hollow" 
bars            = candletype == "Bars"
candle          = candletype == "Candles"

plotcandle(
  hkOpen, hkHigh, hkLow, hkClose, 
  "Hollow Candles",
  hollow ?      hkClose <   hkOpen  ?   BodyBear :  na :        candle ?        hkClose < hkOpen ?  BodyBear : BodyBull : na,
  hollow or     candle ?    hkClose <    hkOpen  ?  WickBear :  WickBull :      na,
  bordercolor = hollow or   candle ?    hkClose  <  hkOpen   ?  BorderBear :    BorderBull : na,
  editable=false)

plotbar(
  hkOpen, hkHigh, hkLow, hkClose,
  "Bars",
  bars ? hkClose < hkOpen ? BodyBear : BodyBull : na,
  editable=false)
  
//-------------------------------Trend Lines----------------------------------//
// Code author: © LonesomeTheBlue
n = bar_index
src=close

showtl = input(false, "Show Trend Lines?", group=grtl) 
prd = input.int(defval=8, title='Pivot Point Period', minval=5, maxval=50, group=grtl)
PPnum = input.int(defval=3, title='Number of Pivot Point to check', minval=2, maxval=3, group=grtl)
trendstyle = input.string(defval='.....', title='Trend Line Style', options=['.....', '-----'], group=grtl)

float ph = na
float pl = na
ph := ta.pivothigh(src, prd, prd)
pl := ta.pivotlow(src, prd, prd)

getloc(bar_i) =>
    _ret = bar_index + prd - bar_i
    _ret

t1pos = ta.valuewhen(ph, bar_index, 0)
t1val = nz(src[getloc(t1pos)])
t2pos = ta.valuewhen(ph, bar_index, 1)
t2val = nz(src[getloc(t2pos)])
t3pos = ta.valuewhen(ph, bar_index, 2)
t3val = nz(src[getloc(t3pos)])

b1pos = ta.valuewhen(pl, bar_index, 0)
b1val = nz(src[getloc(b1pos)])
b2pos = ta.valuewhen(pl, bar_index, 1)
b2val = nz(src[getloc(b2pos)])
b3pos = ta.valuewhen(pl, bar_index, 2)
b3val = nz(src[getloc(b3pos)])

getloval(l1, l2) =>
    _ret1 = l1 == 1 ? b1val : l1 == 2 ? b2val : l1 == 3 ? b3val : 0
    _ret2 = l2 == 1 ? b1val : l2 == 2 ? b2val : l2 == 3 ? b3val : 0
    [_ret1, _ret2]

getlopos(l1, l2) =>
    _ret1 = l1 == 1 ? b1pos : l1 == 2 ? b2pos : l1 == 3 ? b3pos : 0
    _ret2 = l2 == 1 ? b1pos : l2 == 2 ? b2pos : l2 == 3 ? b3pos : 0
    [_ret1, _ret2]

gethival(l1, l2) =>
    _ret1 = l1 == 1 ? t1val : l1 == 2 ? t2val : l1 == 3 ? t3val : 0
    _ret2 = l2 == 1 ? t1val : l2 == 2 ? t2val : l2 == 3 ? t3val : 0
    [_ret1, _ret2]

gethipos(l1, l2) =>
    _ret1 = l1 == 1 ? t1pos : l1 == 2 ? t2pos : l1 == 3 ? t3pos : 0
    _ret2 = l2 == 1 ? t1pos : l2 == 2 ? t2pos : l2 == 3 ? t3pos : 0
    [_ret1, _ret2]

var line l1 = na
var label l1a = na 
var line l2 = na
var label l2a = na
var line l3 = na
var label l3a = na
var line t1 = na
var label t1a = na
var line t2 = na
var label t2a = na
var line t3 = na
var label t3a = na

line.delete(l1)
label.delete(l1a[1]) 
line.delete(l2)
label.delete(l2a[1])
line.delete(l3)
label.delete(l3a[1])
line.delete(t1)
label.delete(t1a[1])
line.delete(t2)
label.delete(t2a[1])
line.delete(t3)
label.delete(t3a[1])

countlinelo = 0
countlinehi = 0
for p1 = 1 to PPnum - 1 by 1
    uv1 = 0.0
    uv2 = 0.0
    up1 = 0
    up2 = 0
    for p2 = PPnum to p1 + 1 by 1
        [val1, val2] = getloval(p1, p2)
        [pos1, pos2] = getlopos(p1, p2)
        if val1 > val2
            diff = (val1 - val2) / (pos1 - pos2)
            hline = val2 + diff
            lloc = bar_index
            lval = src
            valid = true
            for x = pos2 + 1 - prd to bar_index by 1
                if nz(src[getloc(x + prd)]) < hline
                    valid := false
                    valid
                lloc := x
                lval := hline
                hline += diff
                hline
            if valid
                uv1 := hline
                uv2 := val2
                up1 := lloc
                up2 := pos2
                break
    dv1 = 0.0
    dv2 = 0.0
    dp1 = 0
    dp2 = 0
    for p2 = PPnum to p1 + 1 by 1
        [val1, val2] = gethival(p1, p2)
        [pos1, pos2] = gethipos(p1, p2)
        if val1 < val2
            diff = (val2 - val1) / (pos1 - pos2)
            hline = val2 - diff
            lloc = bar_index
            lval = rsi
            valid = true
            for x = pos2 + 1 - prd to bar_index by 1
                if nz(src[getloc(x + prd)]) > hline
                    valid := false
                    break
                lloc := x
                lval := hline
                hline -= diff
                hline
            if valid
                dv1 := hline
                dv2 := val2
                dp1 := lloc
                dp2 := pos2
                break
    if up1 != 0 and up2 != 0 and showtl
        countlinelo += 1
        l1 := countlinelo == 1 ? line.new(up2 - prd, uv2, up1, uv1, color=green, style=trendstyle == '-----' ? line.style_dashed : line.style_dotted) : l1
        l2 := countlinelo == 2 ? line.new(up2 - prd, uv2, up1, uv1, color=green, style=trendstyle == '-----' ? line.style_dashed : line.style_dotted) : l2
        l3 := countlinelo == 3 ? line.new(up2 - prd, uv2, up1, uv1, color=green, style=trendstyle == '-----' ? line.style_dashed : line.style_dotted) : l3
        l3
        
    if dp1 != 0 and dp2 != 0 and showtl
        countlinehi += 1 // truncateprice(dp1-(dp2-prd),pricedecimals)
        t1 := countlinehi == 1 ? line.new(dp2 - prd, dv2, dp1, dv1, color=red, style=trendstyle == '-----' ? line.style_dashed : line.style_dotted) : t1
        t2 := countlinehi == 2 ? line.new(dp2 - prd, dv2, dp1, dv1, color=red, style=trendstyle == '-----' ? line.style_dashed : line.style_dotted) : t2
        t3 := countlinehi == 3 ? line.new(dp2 - prd, dv2, dp1, dv1, color=red, style=trendstyle == '-----' ? line.style_dashed : line.style_dotted) : t3
        t3

//------------------------------Fibonacci Retracements------------------------//
// Code Author: © TradeChartist
showfr = input(false, title='Show Fibonacci Retracements?', group=grfrt, tooltip="Hover over labels for additional info.\nPage 41: The level of the retracement is a strong indication of the trend strength.")
FP = input(21, title='Candles to Lookback', group=grfrt)
fibsize=input.string(size.tiny, title="Fibonacci Retracement Label Size", options=[size.normal, size.small, size.tiny], group=grfrt)
Reverse = input(false, title='Reverse Fibonacci Levels?', group=grfrt)
Mid_Color = input(#787b86, title='Lines & 50 Label Color', group=grfrt)
CurrentFib = input(false, 'Show Fib Level of Current Price', group=grfrt)
Current_Color = input(yellow, title='Current Fibonacci Level Label Color', group=grfrt)
LineStyle = input.string('-----', options=['.....', '-----'], title='Line Style', group=grfrt)
LineWidth = 1 // input.int(1, minval=1, maxval=3, title='Line Width', group=grfrt)
fiblinetransp = input.int(50, minval=1, maxval=100, title='Line Transparency', group=grfrt)
currentfiboffset = input.int(4, 'Current Fibonacci Level Horizontal Offset', group=grfrt, minval=-50, maxval=10)
Ext = false
FPeriod = FP

Fhigh = ta.highest(FPeriod) 
Flow = ta.lowest(FPeriod)
FH = ta.highestbars(high, FPeriod)
FL = ta.lowestbars(low, FPeriod)
revfibs = not Reverse ? FL > FH : FL < FH

Fib_x(n) =>
    revfibs ? (Fhigh - Flow) * n + Flow : Fhigh - (Fhigh - Flow) * n

Current = revfibs ? (close - Flow) / (Fhigh - Flow) : (Fhigh - close) / (Fhigh - Flow)

var label Current_Fib_Label = na
label.delete(Current_Fib_Label)

if CurrentFib and barstate.islast and showfr 
    Current_Fib_Label := label.new(bar_index + currentfiboffset, close, str.tostring(truncateprice(Current, pricedecimals)), 
      textcolor=Current_Color, color=color.new(#000000, 100), style=label.style_label_left, yloc=yloc.price, 
      size=fibsize, tooltip=str.tostring(truncateprice(close, pricedecimals)))
    Current_Fib_Label

EXTEND = Ext ? extend.left : extend.none
STYLE = LineStyle == '.....' ? line.style_dotted : line.style_dashed
WIDTH = LineWidth

BB = FL < FH ? bar_index[-FL] : bar_index[-FH] 

Fib_line(x) =>
    var line ln = na
    line.delete(ln)
    if showfr 
        ln := line.new(BB, x, bar_index, x, color=color.new(Mid_Color,fiblinetransp), extend=EXTEND, style=STYLE, width=WIDTH)
        ln
    
Fib0 = Fib_line(Fib_x(0))
Fib146 = Fib_line(Fib_x(0.146))
Fib236 = Fib_line(Fib_x(0.236))
Fib382 = Fib_line(Fib_x(0.382))
Fib500 = Fib_line(Fib_x(0.500))
Fib618 = Fib_line(Fib_x(0.618))
Fib786 = Fib_line(Fib_x(0.763))
Fib886 = Fib_line(Fib_x(0.854))
Fib1000 = Fib_line(Fib_x(1.000))

// Define labels 
Fib_label(x, _txt, lcol, tip) =>
    var label lbl = na
    label.delete(lbl)
    if showfr
        lbl := label.new(bar_index, x, _txt, textcolor=lcol, color=color.new(#000000,100), style=label.style_label_left, yloc=yloc.price, size=fibsize, tooltip="📍 " + str.tostring(truncateprice(x, pricedecimals)) + tip) 
        lbl

// Display labels with Hayden targets
LFib0 = Fib_label(Fib_x(0), '0.0', brightgreen, ' = 0 %' + '\n🤑 Strongest Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0)-(Fhigh - Flow)):(Fib_x(0)+(Fhigh - Flow)), pricedecimals)))
LFib146 = Fib_label(Fib_x(0.146), '0.146', brightgreen, ' = 14.6 %' + '\n🥳 Very Strong Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.146)-(Fhigh - Flow)):(Fib_x(0.146)+(Fhigh - Flow)), pricedecimals)))
LFib236 = Fib_label(Fib_x(0.236), '0.236', brightgreen, ' = 23.6 %' + '\n🤩 Strong Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.236)-(Fhigh - Flow)):(Fib_x(0.236)+(Fhigh - Flow)), pricedecimals)))
LFib382 = Fib_label(Fib_x(0.382), '0.382', brightgreen, ' = 38.2 %' + '\n😎 Medium Strong Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.382)-(0.8*(Fhigh - Flow))):(Fib_x(0.382)+(0.8*(Fhigh - Flow))), pricedecimals)))
LFib500 = Fib_label(Fib_x(0.500), '0.5', Mid_Color, ' = 50 %' + '\n😐 Medium Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.5)-(0.8*(Fhigh - Flow))):(Fib_x(0.5)+(0.8*(Fhigh - Flow))), pricedecimals)))
LFib618 = Fib_label(Fib_x(0.618), '0.618', brightred, ' = 61.8 %' + '\n😕Medium Weak Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.618)-(0.8*(Fhigh - Flow))):(Fib_x(0.618)+(0.8*(Fhigh - Flow))), pricedecimals)))
LFib786 = Fib_label(Fib_x(0.763), '0.763', brightred, ' = 76.3 %' + '\n😬 Weak Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.763)-(0.8*(Fhigh - Flow))):(Fib_x(0.763)+(0.8*(Fhigh - Flow))), pricedecimals)))
LFib886 = Fib_label(Fib_x(0.854), '0.854', brightred, ' = 85.4 %' + '\n😨 Very Weak Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(0.854)-(0.8*(Fhigh - Flow))):(Fib_x(0.854)+(0.8*(Fhigh - Flow))), pricedecimals)))
LFib1000 = Fib_label(Fib_x(1.000), '1.0', brightred, ' = 100 %' + '\n😱 Invalidated Trend \n'+'🎯 '+ str.tostring(truncateprice(FL>FH?(Fib_x(1.0)-(0.8*(Fhigh - Flow))):(Fib_x(1.0)+(0.8*(Fhigh - Flow))), pricedecimals)))

// ------------------------- Trend State ------------------------------------ //
// Code Author: © Koalafied_3
showtrend = input(false, title='Show Hayden triple trend state background?',group=grhts, 
  tooltip = "Check this box if you want to see the Bull, Bear, or Chop trend state background according to Hayden.\nFor best results, these settings should match the settings in Hayden's Advanced RSI oscillator.\n(Page 56) 10 Lies That Traders Believe = The RSI is unable to indicate trend direction, because it's only a momentum indicator.")
ts1 = input.float(defval=67, title="Precise Bullish RSI Crossover 66 to 68", minval=66, maxval=68, step=0.001, group=grhts, tooltip="End of chop. Popular: 66, 66.666, or 67")
ts2 = input.float(defval=33, title="Precise Bearish RSI Crossunder 32 to 34", minval=32, maxval=34, step=0.001, group=grhts, tooltip="End of chop. Popular: 34, 33.333, or 33")
ts1a = input.float(defval=61, title="Precise Bullish RSI Crossover 60 to 62", minval=60, maxval=62, step=0.001, group=grhts, tooltip="End of bearish trend. Popular: 61, 60.618, 60.5, or 60")
ts2a = input.float(defval=39, title="Precise Bearish RSI Crossunder 38 to 40", minval=38, maxval=40, step=0.001, group=grhts, tooltip="End of bullish trend. Popular: 39, 39.5, 39.618, or 40")
// Trend State
var state = 0
if ta.crossover(rsi, ts1)
    state := 1
    state
if ta.crossunder(rsi, ts2) 
    state := 2
    state
if state == 1 and ta.crossunder(rsi, ts2a)
    state := 3
    state
if state == 2 and ta.crossover(rsi, ts1a)
    state := 3
    state
state := state

bgcol=showtrend and state==1?green : showtrend and state==2?red : na
bgcolor(color.new(bgcol,80))

//-------------------------------Watermark------------------------------------//
// Watermark tooltips (hover)
q1 = "Look first / Then leap." 
q2 = "TradeStation™ Charting by Omega Research and Epsilon Charting"
q3 = "Made w/ ❤ by © 🦶 BarefootJoey"
// Watermark Displays
str1 = "₸⩒ TradingView"
str2 = "TradeStation™" 
str3 = "🦶 BarefootJoey"

// Need to toggle timeframe gaps if there are too many on MTF
showwatermark = input(true, 'Show Watermark?', group=grwm, tooltip="Hover over watermark for additional info.")
wmstring = input.string("TradingView", title="Watermark Display Text", options=["BarefootJoey", "TradeStation", "TradingView", "Custom"], group=grwm)
name = input(defval='Your name', title="Custom Watermark Text", group=grwm, tooltip="Emojis allowed!")
watermarktransp = input.int(30, 'Watermark Transparency', minval=0, maxval=100, group=grwm)
watermarkxoffset = input.int(-10, 'Watermark Horizontal Offset', group=grwm , minval=-50, maxval=5)
watermarklocation = input.string(yloc.belowbar, options=[yloc.belowbar, yloc.abovebar], title='Watermark Location', group=grwm)
wmsize = input.string(size.normal, title="Watermark Size", options=[size.normal, size.small, size.tiny], group=grwm)

whichwm = wmstring == "BarefootJoey" ? str3 :wmstring =="TradeStation"? str2 : wmstring == "TradingView" ? str1 : name
whichtt = wmstring == "TradeStation" ? q2 : wmstring == "TradingView"? q1 : q3

// Watermark Close
wmPrice = ta.valuewhen(bar_index + watermarkxoffset, close, 0)

// Label
if showwatermark
    var label watermark = na
    watermark := label.new(bar_index + watermarkxoffset,  y=wmPrice, yloc=watermarklocation, size=wmsize, text=whichwm, style=label.style_none, textcolor=color.new(gray,watermarktransp),tooltip=whichtt)
    label.delete(watermark[1])
    
// ------------------------ Advanced Data Ticker ---------------------------- //
showticker = input(true, "Show Tickers?", group=grtk)
datatype = input.string('None', 
  title = 'Ticker 1 Data Source?', 
  options = ['RSI to Price', "MA Price", 'Trend End', 'Trend State', 'ADX & DI+/-', "Watermark", "Volatility", "None"], 
  group = grtk)
datatype2 = input.string('ADX & DI+/-', 
  title = 'Ticker 2 Data Source?', 
  options = ['RSI to Price', "MA Price", 'Trend End', 'Trend State', 'ADX & DI+/-', "Watermark", "Volatility", "None"],  
  group = grtk)

// Code Conversion
r45maout = slowmaout
rsma = fastma
rwmacolv = slowcolv
rsmacolv = fastcolv
len_rsi = prsilen
targetsrc = src

price_by_rsi(level) =>
    x1 = (len_rsi - 1) * (ta.rma(math.max(nz(targetsrc[1], targetsrc) - targetsrc, 0), len_rsi) * level / (100 - level) - ta.rma(math.max(targetsrc - nz(targetsrc[1], targetsrc), 0), len_rsi))
    x1 >= 0 ? targetsrc + x1 : targetsrc + x1 * (100 - level) / level

// RSI to Price Target Inputs
obLevel1 = input.float(80, title='RSI to Price Target 1', minval=1, maxval=99, group=grtk, 
  tooltip ="Table #8 Fibonacci Bullish RSI Levels: 61.8, 66.67, 76.30, 85.42, 90.98, 94.43\n(Page 56) 10 Lies That Traders Believe = The RSI will generally 'top out' somewhere around the 70 level.")
osLevel1 = input.float(20, title='RSI to Price Target 2', minval=1, maxval=99, group=grtk, 
  tooltip ="Table #8 Fibonacci Bearish RSI Levels: 38.2, 33.33, 23.61, 14.59, 9.02, 5.57\n(Page 56) 10 Lies That Traders Believe = The RSI will generally 'bottom out' somewhere around the 30 level.")
// Functional Math and RSI Targets
// Code Author: @ LazyBear
ep = 2 * 14 - 1
auc = ta.ema(math.max(src - src[1], 0), ep)
adc = ta.ema(math.max(src[1] - src, 0), ep)
x1 = (14 - 1) * (adc * obLevel1 / (100 - obLevel1) - auc)
longrsitarget = x1 >= 0 ? src + x1 : src + x1 * (100 - obLevel1) / obLevel1
x2 = (14 - 1) * (adc * osLevel1 / (100 - osLevel1) - auc)
shortrsitarget = x2 >= 0 ? src + x2 : src + x2 * (100 - osLevel1) / osLevel1
// Text
tickerstateob = (str.tostring(obLevel1) + " 🎯 = " + str.tostring(truncateprice(longrsitarget,pricedecimals)))
tickerstateos = (str.tostring(osLevel1) + " 🎯 = " + str.tostring(truncateprice(shortrsitarget,pricedecimals)))
// Plots
roblcol = input.color(aqua, title="RSI to Price Target 1 Color", group=grtk)
roslcol = input.color(fuchsia, title="RSI to Price Target 2 Color", group=grtk)
// Shape Plots
plotshape(datatype=="RSI to Price" or datatype2=="RSI to Price" ?price_by_rsi(obLevel1):na, title="User-defined RSI to Price Target 1", location=location.absolute, style=shape.cross, color=color.new(roblcol, 0), show_last=1)
plotshape(datatype=="RSI to Price" or datatype2=="RSI to Price" ?price_by_rsi(osLevel1):na, title="User-defined RSI to Price Target 2", location=location.absolute, style=shape.cross, color=color.new(roslcol, 0), show_last=1)

// MA Price Targets
// Emoji Rating
erating = (slowmaout>slowmaout[1] and slowmaout>slowmaout[1])?" 🚀 ":
 (slowmaout<slowmaout[1] and rsma<rsma[1])?" 💀 ":"  🪓 "
// Text
tickerstaterwma = ("45 "+ (r45ma == 'WMA' ? "WMA" : "EMA") + " = " + str.tostring(truncateprice(slowmaout, pricedecimals))) + "  " + erating
tickerstatersma = ("9 SMA = " + str.tostring(truncateprice(fastma, pricedecimals)))
// Text Color
rwmatcol2=rwmacolv
rsmatcol2=rsmacolv

// Trend Ends Text
// Fib variables
fr1 = 0
fr3 = 14.59
fr5 = 23.61
fr7 = ts2
fr9 = ts2a
fr11 = 50
fr13 = ts1a
fr16 = ts1
fr18 = 76.3
fr20 = 85.41
fr21 = 100
tickerstateendbull = ("🐮 Bullish above " + str.tostring(truncateprice(price_by_rsi(fr9),pricedecimals)))
tickerstateendbear = ("🐻 Bearish below " + str.tostring(truncateprice(price_by_rsi(fr13),pricedecimals)))
tickerstateendbullchop = ("Bullish above " + str.tostring(truncateprice(price_by_rsi(fr16),pricedecimals)))
tickerstateendbearchop = ("🪓 Bearish below " + str.tostring(truncateprice(price_by_rsi(fr7),pricedecimals)))

// Trend State Text
bulltrend = rsi>r45maout and rsi>rsma and state==1
tickerstatebulltrend = ("📈 Bullish " + (bulltrend?"Trend 🚀":"Chop 🪓"))
beartrend = rsi<r45maout and rsi<rsma and state==2
tickerstatebeartrend = ("📉 Bearish " + (beartrend?"Trend 💀":"Chop 🪓"))
chopbear = state==3 and rsi<r45maout
tickerstatechoptrend = ("🪓 Chop with " + (chopbear?"Bearish 💀":"Bullish 🚀") + " Sentiment")
trendstatedisplay = state==1?tickerstatebulltrend:state==2?tickerstatebeartrend:state==3?tickerstatechoptrend:na
// Trend State Text Color
tstextcol = state==1 and bulltrend ?brightgreen : 
  state==1 and not bulltrend?green : 
  state==2 and beartrend ? brightred : 
  state==2 and not beartrend ? red : 
  state==3 and chopbear ? red : 
  state==3 and not chopbear ? green : na

// ADX & DI Data
// Code Author: Currently unknown. Please help identify the author if you know who it is.
[_, _, adx1] = ta.dmi(17, 4)
adxlen = 14
dilen = 14
dirmov(len) =>
    up = ta.change(high)
    down = -ta.change(low)
    truerange = ta.rma(ta.tr, len)
    plus = fixnan(100 * ta.rma(up > down and up > 0 ? up : 0, len) / truerange)
    minus = fixnan(100 * ta.rma(down > up and down > 0 ? down : 0, len) / truerange)
    [plus, minus]
adx(dilen, adxlen) =>
    [plus, minus] = dirmov(dilen)
    sum = plus + minus
    adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
    adx
adxHigh(dilen, adxlen) =>
    [plus, minus] = dirmov(dilen)
    plus
adxLow(dilen, adxlen) =>
    [plus, minus] = dirmov(dilen)
    minus
sig = adx(dilen, adxlen)
sigHigh = adxHigh(dilen, adxlen)
sigLow = adxLow(dilen, adxlen)
sigTop = sigHigh>sigLow?sigHigh:sigLow
// Text
adxtext = 'ADX ' + str.tostring(truncatepercent(adx1, percentdecimals)) 
  + (adx1>adx1[1] ? ' & 📈' : ' & 📉') 
  + (adx1<25?' 💤':adx1>25 and adx1<50 ?' 💪':adx1>50 and adx1<75 ?' 🔥':adx1>75 and adx1<100 ?' 🚀':'')
ditext = 'DI ' + str.tostring(truncatepercent(sigTop, percentdecimals)) 
  + (sigTop>sigTop[1] and sigHigh>sigLow? ' & 📈 🐮' : sigTop<sigTop[1] and sigHigh>sigLow ? ' & 📉 🪓': sigTop>sigTop[1] and sigHigh<sigLow ? ' & 📈 🐻' : sigTop<sigTop[1] and sigHigh<sigLow ? ' & 📉 🪓':na) 
// Text Color
adxtextcol = color.new(
  sigHigh > sigLow and adx1 < 25 ? green: 
  sigHigh > sigLow and adx1 > 25 ? brightgreen: 
  sigHigh < sigLow and adx1 > 25 ? brightred: 
  sigHigh < sigLow and adx1 < 25 ? red: 
  gray, 0)
ditextcol = color.new(
  sigHigh > sigLow and sigTop<sigTop[1] ? green: 
  sigHigh > sigLow and sigTop>sigTop[1] ? brightgreen: 
  sigHigh < sigLow and sigTop>sigTop[1] ? brightred: 
  sigHigh < sigLow and sigTop<sigTop[1] ? red: 
  gray, 0)
  
// Volatility
lowvolcol = input.color(color.rgb(250,237,56,1), "Low Volatility Gradient Color", group=grtk)
highvolcol = input.color(color.rgb(255,37,174,1), "High Volatility Gradient Color", group=grtk)
f_volatility() =>
	atr = ta.atr(14)
	stdAtr = 2*ta.stdev(atr,20)
	smaAtr = ta.sma(atr,20)
	topAtrDev = smaAtr+stdAtr
	bottomAtrDev = smaAtr-stdAtr
	calcDev = (atr-bottomAtrDev)/(topAtrDev-bottomAtrDev)
	percentVol = (40*calcDev+30)
volatility = f_volatility()
volatilitydir = volatility>volatility[1]?" & 📈":" & 📉"
volemoji = volatility > 0 and volatility < 20 ? "😴" : volatility > 20 and volatility < 40 ? " 😐" : volatility > 40 and volatility < 60 ? " 😬" : volatility > 60 and volatility < 80 ? " 😮" : volatility > 80 and volatility < 100 ? " 😵" : " 🤯" 
voltxt = "Volatility = " + str.tostring(truncatepercent(volatility, percentdecimals)) + " %" + volemoji + volatilitydir 
volcol = color.from_gradient(volatility,25,75,lowvolcol,highvolcol)

// Dual Ticker Display
// Code Author: © dgtrd
watermark = input("Your name", title="Custom Trader WaterMark Text", group=grtk, tooltip="Emojis allowed!")
WMtxtcol = input(gray, title="WaterMark Text Color", group=grtk)
Ttransp=input(20, title="Ticker Text Transparency", group=grtk)

position = input.string(position.top_center, "Ticker 1 Position", [position.top_center, position.top_right, position.middle_right, position.bottom_right, position.bottom_center, position.bottom_left, position.middle_left, position.top_left], group=grtk)
size = input.string(size.small, "Ticker 1 Size", [size.tiny, size.small, size.normal, size.large, size.huge], group=grtk)
var table Ticker = na
Ticker := table.new(position, 2, 1)
if barstate.islast and showticker
    table.cell(Ticker, 0, 0, 
      text = datatype=="RSI to Price"?tickerstateob:datatype=="MA Price"?tickerstaterwma:datatype=="Trend End" and state ==1?tickerstateendbull:datatype=="Trend End" and state ==3?tickerstateendbullchop:datatype=="ADX & DI+/-"?adxtext:datatype=="Watermark"?watermark:na, //datatype=="Trend State"?"Trend: ":
      text_size = size, 
      text_color = color.new(datatype=="RSI to Price"?roblcol:datatype=="MA Price"?rwmatcol2:datatype=="Trend End" and (state==3 or state==1)?green:datatype=="ADX & DI+/-"?adxtextcol:gray,Ttransp),
      tooltip=datatype=="Watermark"?q3:na)
    table.cell(Ticker, 1, 0, 
      text = datatype=="RSI to Price"?tickerstateos:datatype=="MA Price"?tickerstatersma:datatype=="Trend End" and state ==2?tickerstateendbear:datatype=="Trend End" and state ==3?tickerstateendbearchop:datatype=="ADX & DI+/-"?ditext:datatype=="Trend State"?trendstatedisplay:datatype=="Volatility"?voltxt:na, 
      text_size = size, 
      text_color = color.new(datatype=="RSI to Price"?roslcol:datatype=="MA Price"?rsmatcol2:datatype=="Trend End" and (state==3 or state==2)?red:datatype=="ADX & DI+/-"?ditextcol:datatype=="Trend State"?tstextcol:datatype=="Volatility" ? volcol :gray,Ttransp))
position2 = input.string(position.bottom_center, "Ticker 2 Position", [position.top_center, position.top_right, position.middle_right, position.bottom_right, position.bottom_center, position.bottom_left, position.middle_left, position.top_left], group=grtk)
size2 = input.string(size.small, "Ticker 2 Size", [size.tiny, size.small, size.normal, size.large, size.huge], group=grtk)
var table Ticker2 = na
Ticker2 := table.new(position2, 2, 1)
if barstate.islast and showticker
    table.cell(Ticker2, 0, 0,
      text = datatype2=="RSI to Price"?tickerstateob:datatype2=="MA Price"?tickerstaterwma:datatype2=="Trend End" and state ==1?tickerstateendbull:datatype2=="Trend End" and state ==3?tickerstateendbullchop:datatype2=="ADX & DI+/-"?adxtext:datatype2=="Watermark"?watermark:na, //datatype=="Trend State"?"Trend: ":
      text_size = size2, 
      text_color = color.new(datatype2=="RSI to Price"?roblcol:datatype2=="MA Price"?rwmatcol2:datatype2=="Trend End" and (state==3 or state==1)?green:datatype2=="ADX & DI+/-"?adxtextcol:gray,Ttransp),
      tooltip=datatype=="Watermark"?q3:na)
    table.cell(Ticker2, 1, 0, 
      text = datatype2=="RSI to Price"?tickerstateos:datatype2=="MA Price"?tickerstatersma:datatype2=="Trend End" and state ==2?tickerstateendbear:datatype2=="Trend End" and state ==3?tickerstateendbearchop:datatype2=="ADX & DI+/-"?ditext:datatype2=="Trend State"?trendstatedisplay:datatype2=="Volatility"?voltxt:na, 
      text_size = size2, 
      text_color = color.new(datatype2=="RSI to Price"?roslcol:datatype2=="MA Price"?rsmatcol2:datatype2=="Trend End" and (state==3 or state==2)?red:datatype2=="ADX & DI+/-"?ditextcol:datatype2=="Trend State"?tstextcol:datatype2=="Volatility" ? volcol :gray,Ttransp))

// EoS. Made w/ ❤ by © 🦶BarefootJoey