TICK Divergence + Heikin Ashi [Pt]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © PtGambler

//@version=5
indicator(title='TICK Divergence + Heikin Ashi [Pt]', shorttitle='[Pt] TICK Dvg', overlay=false)

// ----------------------------------- Inputs ------------------------------------------

tick_symbol = input.symbol("USI:TICK", "Symbol")
display = input.string("Line", "Show TICK as:", options = ["Line", "Bar", "Heikin Ashi"], inline = "tick")
line_col = input.color(color.white, "─", inline = "tick")
bar_up_col = input.color(color.lime, "↑", inline = "tick")
bar_down_col = input.color(color.red, "↓", inline = "tick")

// Dual MA
showma1 = input.bool(true, "Fast MA", inline = "grp1len1", group = "Dual Moving Average")
matype1 = input.string("EMA", "", ["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA", "HMA"], inline = "grp1len1", group = "Dual Moving Average")
malen1 = input.int(9, "Length", inline = "grp1len1", group = "Dual Moving Average")
ma_col1 = input.color(color.yellow, "", inline = "grp1len1", group = "Dual Moving Average")

showma2 = input.bool(true, "Slow MA", inline = "grp1len2", group = "Dual Moving Average")
matype2 = input.string("EMA", "", ["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA", "HMA"], inline = "grp1len2", group = "Dual Moving Average")
malen2 = input.int(21, "Length", inline = "grp1len2", group = "Dual Moving Average")
ma_col2 = input.color(color.orange, "", inline = "grp1len2", group = "Dual Moving Average")

show_ma_x1 = input.bool(true, "Show MA cross", inline = "x1",  group = "Dual Moving Average")
x_up_col1 = input.color(color.green, "▲", inline = "x1",  group = "Dual Moving Average")
x_down_col1 = input.color(color.red, "▼", inline = "x1",  group = "Dual Moving Average")

// MA and Smoothed MA
showma3 = input.bool(true, "Base MA", inline = "grp2len1", group = "Moving Average / Smoothed MA")
matype3 = input.string("HMA", "", ["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA", "HMA"], inline = "grp2len1", group = "Moving Average / Smoothed MA")
malen3 = input.int(21, "Length", inline = "grp2len1", group = "Moving Average / Smoothed MA")
ma_col3 = input.color(color.aqua, "", inline = "grp2len1", group = "Moving Average / Smoothed MA")

showma4 = input.bool(true, "Smoothed MA", inline = "grp2len2", group = "Moving Average / Smoothed MA")
matype4 = input.string("EMA", "", ["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA", "HMA"], inline = "grp2len2", group = "Moving Average / Smoothed MA")
malen4 = input.int(5, "Length", inline = "grp2len2", group = "Moving Average / Smoothed MA")
ma_col4 = input.color(color.red, "", inline = "grp2len2", group = "Moving Average / Smoothed MA")

show_ma_x2 = input.bool(true, "Show MA cross", inline = "x2" , group = "Moving Average / Smoothed MA")
x_up_col2 = input.color(color.blue, "▲", inline = "x2",  group =  "Moving Average / Smoothed MA")
x_down_col2 = input.color(color.orange, "▼", inline = "x2",  group =  "Moving Average / Smoothed MA")

// Divergence
dvg_src = input.string('High/Low', 'Source', options = ['High/Low', 'Close'], group = "Divergence - Pivot based")
lbR = input(2, title='Pivot Lookback Right', group = "Divergence - Pivot based")
lbL = input(5, title='Pivot Lookback Left', group = "Divergence - Pivot based")

rangeUpper = input(60, title='Max of Lookback Range', group = "Divergence - Pivot based")
rangeLower = input(5, title='Min of Lookback Range', group = "Divergence - Pivot based")
plotBull = input(true, title='Plot Bullish', group = "Divergence - Pivot based")
plotHiddenBull = input(true, title='Plot Hidden Bullish', group = "Divergence - Pivot based")
plotBear = input(true, title='Plot Bearish', group = "Divergence - Pivot based")
plotHiddenBear = input(true, title='Plot Hidden Bearish', group = "Divergence - Pivot based")

//Backgroun colors
bg_ma = input.string("Slow MA", "Change Background Color based on:", options = ["Fast MA", "Slow MA", "Base MA", "Smoothed MA", "TICK", "None"], group = "Background Color")
bg_bull_col = input.color(color.new(color.green, 90), "Bullish BG Color", group = "Background Color", tooltip = "Above zero line")
bg_bear_col = input.color(color.new(color.red, 90), "Bearish BG Color", group = "Background Color", tooltip = "Below zero line")

// Significant levels
neutralH = input.int(200, title="Neutral zone +/- from 0", minval = 0, step=10, inline = "neutral",  group = "Significant Levels")
neutral_col = input.color(color.new(color.gray,90), "", inline = "neutral",  group = "Significant Levels")
neutralL = -neutralH
BullishH = input.int(500, title="Trend zone +/- from 0", minval = 0, step=10, inline = "trend", group = "Significant Levels", tooltip = "Background will turn Bullish color if TICK is above this level, Bearish color if below negative of this level")
uptrend_col = input.color(color.new(color.green,70), "", inline = "trend",  group = "Significant Levels")
downtrend_col = input.color(color.new(color.red,70), "", inline = "trend",  group = "Significant Levels")
showtrend = input.bool(true, "", inline = "trend",  group = "Significant Levels")
BearishL = -BullishH
OverH = input.int(800, title="OB/OS extremes +/- from 0", minval = 0, step=10, inline = "over", group = "Significant Levels", tooltip = "Background will turn bright Bullish color if TICK is above this level indicating Overbought, bright Bearish color if below negative of this level indicating Oversold")
ob_col = input.color(color.new(color.green,30), "", inline = "over",  group = "Significant Levels")
os_col = input.color(color.new(color.red,30), "", inline = "over",  group = "Significant Levels")
showOBOS = input.bool(true, "", inline = "over",  group = "Significant Levels")
OverL = -OverH

// ---------------------------------------------- Functions -----------------------------------------------

f_hma(_src, _length) =>
    _return = ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length)))
    _return

f_ma(_src, _length, _type) =>
    switch _type
        "SMA" => ta.sma(_src, _length)
        "EMA" => ta.ema(_src, _length)
        "SMMA (RMA)" => ta.rma(_src, _length)
        "WMA" => ta.wma(_src, _length)
        "VWMA" => ta.vwma(_src, _length)
        "HMA" => f_hma(_src, _length)

// --------------------------------------------- Calculations -------------------------------------------------

//get TICK data
[tickO, tickH, tickL, tickC, tickfb, ticklb] = request.security(tick_symbol, timeframe.period, [open, high, low, close, session.isfirstbar, session.islastbar])
[ha_tickO, ha_tickH, ha_tickL, ha_tickC] = request.security(ticker.heikinashi(tick_symbol), timeframe.period, [open, high, low, close])

tickMA1 = f_ma(tickC, malen1, matype1)
tickMA2 = f_ma(tickC, malen2, matype2)

tickMA3 = f_ma(tickC, malen3, matype3)
tickMA4 = f_ma(tickMA3, malen4, matype4)

// ------------------------------------------------- Plots ----------------------------------------------------

var in_session = false
in_session := tickfb ? true : ticklb[1] ? false : in_session[1]

float O = na
float H = na
float L = na
float C = na

if in_session
    O := display == "Bar" ? tickO : display == "Heikin Ashi" ? ha_tickO : na
    H := display == "Bar" ? tickH : display == "Heikin Ashi" ? ha_tickH : na
    L := display == "Bar" ? tickL : display == "Heikin Ashi" ? ha_tickL : na
    C := display == "Bar" ? tickC : display == "Heikin Ashi" ? ha_tickC : na
    
plot(display == "Line" and in_session ? tickC : na, title='TICK', color = line_col , style=plot.style_linebr, linewidth = 2)
plotcandle(O, H, L, C, "TICK", color = C > O ? bar_up_col : bar_down_col, wickcolor = C > O ? bar_up_col : bar_down_col, bordercolor = C > O ? bar_up_col : bar_down_col)
plot(showma1 ? tickMA1 : na, title='TICK Fast MA', color = ma_col1, style=plot.style_line, linewidth = 2)
plot(showma2 ? tickMA2 : na, title='TICK Slow MA', color = ma_col2, style=plot.style_line, linewidth = 2)
plot(showma3 ? tickMA3 : na, title='TICK Base MA', color = ma_col3, style=plot.style_line, linewidth = 3)
plot(showma4 ? tickMA4 : na, title='TICK Smoothed MA', color = ma_col4, style=plot.style_line, linewidth = 3)

OB          = hline(OverH, color=color.gray, linestyle=hline.style_dashed)
upperbull   = hline(BullishH, color=color.gray, linestyle=hline.style_dashed)
lowerbull   = hline(neutralH, color=color.gray, linestyle=hline.style_dashed)
median      = hline(0, color=color.orange, linestyle = hline.style_dotted,  linewidth = 2)
upperbear   = hline(neutralL, color=color.gray, linestyle=hline.style_dashed)
lowerbear   = hline(BearishL, color=color.gray, linestyle=hline.style_dashed)
OS          = hline(OverL, color=color.gray, linestyle=hline.style_dashed)

fill( upperbull, OB, color.new(color.green,90), title = "Upper Bull trend zone")
fill( lowerbull, upperbull, color.new(color.green,80), title = "Lower Bull trend zone")
fill( upperbear, lowerbear, color.new(color.red,80), title = "Upper Bear trend zone")
fill( lowerbear, OS, color.new(color.red,90), title = "Lower Bear trend zone")

dma_bullx = ta.crossover(tickMA1,tickMA2)
dma_bearx = ta.crossunder(tickMA1,tickMA2)
smma_bullx = ta.crossover(tickMA3,tickMA4)
smma_bearx = ta.crossunder(tickMA3,tickMA4)

plotshape(show_ma_x1 ? dma_bearx : na ,"Cross down", color=x_down_col1, style=shape.triangledown, location = location.top, size =size.tiny)
plotshape(show_ma_x1 ? dma_bullx : na ,"Cross up", color=x_up_col1, style=shape.triangleup, location = location.bottom, size =size.tiny)
plotshape(show_ma_x2 ? smma_bearx : na ,"Cross down", color=x_down_col2, style=shape.triangledown, location = location.top, size =size.tiny)
plotshape(show_ma_x2 ? smma_bullx : na ,"Cross up", color=x_up_col2, style=shape.triangleup, location = location.bottom, size =size.tiny)

//Background
bg_ma_src = switch bg_ma
    "Fast MA" => tickMA1
    "Slow MA" => tickMA2
    "Base MA" => tickMA3
    "Smoothed MA" => tickMA4
    "TICK" => tickC
    "None" => na
bgcolor(in_session and bg_ma_src > 0 ? bg_bull_col : in_session and bg_ma_src < 0 ? bg_bear_col : na)
bgcolor(in_session and showtrend and tickC > BullishH ? uptrend_col : na)
bgcolor(in_session and showtrend and tickC < BearishL ? downtrend_col : na)
bgcolor(in_session and showOBOS and tickC > OverH ? ob_col : na)
bgcolor(in_session and showOBOS and tickC < OverL ? os_col : na)


// ------------------------------------------------ Divergence ------------------------------------
bearColor = color.red
bullColor = color.green
hiddenBullColor = color.new(color.green, 80)
hiddenBearColor = color.new(color.red, 80)
textColor = color.white
noneColor = color.new(color.white, 100)

osc_src_H = tickH
osc_src_L = tickL 

if dvg_src == "Close"
    osc_src_H := tickC
    osc_src_L := tickC

plFound = na(ta.pivotlow(osc_src_L, lbL, lbR)) ? false : true
phFound = na(ta.pivothigh(osc_src_H, lbL, lbR)) ? false : true

_inRange(cond) =>
    bars = ta.barssince(cond == true)
    rangeLower <= bars and bars <= rangeUpper

//------------------------------------------------------------------------------
// Regular Bullish

// Osc: Higher Low
oscHL = osc_src_L[lbR] > ta.valuewhen(plFound, osc_src_L[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low
priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1)

bullCond = plotBull and priceLL and oscHL and plFound

plot(plFound ? osc_src_L[lbR] : na, offset=-lbR, title='Regular Bullish', linewidth=2, color=bullCond ? bullColor : noneColor)

plotshape(bullCond ? osc_src_L[lbR] : na, offset=-lbR, title='Regular Bullish Label', text=' Bull ', style=shape.labelup, location=location.absolute, color=color.new(bullColor, 0), textcolor=color.new(textColor, 0))

//------------------------------------------------------------------------------
// Hidden Bullish

// Osc: Lower Low
oscLL = osc_src_L[lbR] < ta.valuewhen(plFound, osc_src_L[lbR], 1) and _inRange(plFound[1])

// Price: Higher Low
priceHL = low[lbR] > ta.valuewhen(plFound, low[lbR], 1)

hiddenBullCond = plotHiddenBull and priceHL and oscLL and plFound

plot(plFound ? osc_src_L[lbR] : na, offset=-lbR, title='Hidden Bullish', linewidth=2, color=hiddenBullCond ? hiddenBullColor : noneColor)

plotshape(hiddenBullCond ? osc_src_L[lbR] : na, offset=-lbR, title='Hidden Bullish Label', text=' H Bull ', style=shape.labelup, location=location.absolute, color=color.new(bullColor, 0), textcolor=color.new(textColor, 0))


//------------------------------------------------------------------------------
// Regular Bearish

// Osc: Lower High
oscLH = osc_src_H[lbR] < ta.valuewhen(phFound, osc_src_H[lbR], 1) and _inRange(phFound[1])

// Price: Higher High
priceHH = high[lbR] > ta.valuewhen(phFound, high[lbR], 1)

bearCond = plotBear and priceHH and oscLH and phFound

plot(phFound ? osc_src_H[lbR] : na, offset=-lbR, title='Regular Bearish', linewidth=2, color=bearCond ? bearColor : noneColor)

plotshape(bearCond ? osc_src_H[lbR] : na, offset=-lbR, title='Regular Bearish Label', text=' Bear ', style=shape.labeldown, location=location.absolute, color=color.new(bearColor, 0), textcolor=color.new(textColor, 0))

//------------------------------------------------------------------------------
// Hidden Bearish

// Osc: Higher High
oscHH = osc_src_H[lbR] > ta.valuewhen(phFound, osc_src_H[lbR], 1) and _inRange(phFound[1])

// Price: Lower High
priceLH = high[lbR] < ta.valuewhen(phFound, high[lbR], 1)

hiddenBearCond = plotHiddenBear and priceLH and oscHH and phFound

plot(phFound ? osc_src_H[lbR] : na, offset=-lbR, title='Hidden Bearish', linewidth=2, color=hiddenBearCond ? hiddenBearColor : noneColor)

plotshape(hiddenBearCond ? osc_src_H[lbR] : na, offset=-lbR, title='Hidden Bearish Label', text=' H Bear ', style=shape.labeldown, location=location.absolute, color=color.new(bearColor, 0), textcolor=color.new(textColor, 0))


// Alerts ---------------------------------------------------------------------------------

alertcondition(dma_bullx, "Dual MA Bullish Crossover", 'Dual MA Bullish Crossover')
alertcondition(dma_bearx, "Dual MA Bearish Crossover", 'Dual MA Bearish Crossover')
alertcondition(smma_bullx, "Smoothed MA Bullish Crossover", 'Smoothed MA Bullish Crossover')
alertcondition(smma_bullx, "Smoothed MA Bearish Crossover", 'Smoothed MA Bearish Crossover')

alertcondition(bullCond, "Bullish Divergence", 'Bullish Divergence')
alertcondition(bearCond, "Bearish Divergence", 'Bearish Divergence')
alertcondition(hiddenBullCond, "Hidden Bullish Divergence", 'Bullish Divergence')
alertcondition(hiddenBearCond, "Hidden Bearish Divergence", 'Bearish Divergence')
