Support Resistance Zones using confluence & Std. Deviation
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Badshah.E.Alam

//@version=5
indicator('Support Resistance Zones using confluence & Std. Deviation', shorttitle='S/R Zone & Confluences', overlay=true, max_bars_back=1000, max_lines_count=400, max_labels_count=400)

//////////////////////////////////////////////////////////////////
srnum = input.int(defval = 6, title = "Number of Support/Resistance", minval = 1, maxval = 6, confirm=true, group = "Setup", tooltip = "you can set the number of S/R levels to be shown")

// get SR levels interactively and assign it to the array
var float [] srarray = array.from(
 srnum > 0 ? input.price(0.0, title="S/R level 1", confirm=true, group = "Setup") : na,
 srnum > 1 ? input.price(0.0, title="S/R level 2", confirm=true, group = "Setup") : na,
 srnum > 2 ? input.price(0.0, title="S/R level 3", confirm=true, group = "Setup") : na,
 srnum > 3 ? input.price(0.0, title="S/R level 4", confirm=true, group = "Setup") : na,
 srnum > 4 ? input.price(0.0, title="S/R level 5", confirm=true, group = "Setup") : na,
 srnum > 5 ? input.price(0.0, title="S/R level 6", confirm=true, group = "Setup") : na)
seprator8 = input.bool(true, '=====================================================',group="Setup")

////////////////////////////////////////////////////////
//Confluence settings
t_or_f_zone=input(true,"Display Zones",group="Confluence settings")
display_line=input(false,"Display Individual confluences",group="Confluence settings")
shift_box = input.int(100, "Shift box left by 'x' bars",group="Confluence settings",minval=0,maxval=400)
shift_box_r = input.int(100, "Shift box Right by 'x' bars",group="Confluence settings",minval=0,maxval=400)
st_deviation_input_val=input.float(20,"Minimum standard deviation",group="Confluence settings")
nearest_n_values=input.int(4,"Number of confluence to check",minval=2,maxval=30,group="Confluence settings")
resistancecol = input(defval = color.red, title = "Zone Resistance Color",group="Confluence settings")
resistancecol_ = input(defval =color.new( color.red,80), title = "Zone background Resistance Color",group="Confluence settings")
supportcol = input(defval =color.lime, title = "Zone Support Color",group="Confluence settings")
supportcol_ = input(defval =color.new(color.lime,80), title = "Zone background Support Color",group="Confluence settings")
individual_level_color= input(defval = color.blue, title = "individual level Color",group="Confluence settings")
seprator5 = input.bool(true, '=====================================================',group="Confluence settings")


/////////////////////////////////////////////////////////////////////////////////////////////////////////
//ATH, ATL, Weekly High, Weekly Low, two days ago high, two days ago low, previous day high , previous day low
styleOption = input.string(title="Line Style",
     options=["solid (─)", "dotted (┈)", "dashed (╌)",
     "arrow left (←)", "arrow right (→)", "arrows both (↔)"],
     defval="solid (─)",group="Levels settings")

lineStyle = (styleOption == "dotted (┈)") ? line.style_dotted :
     (styleOption == "dashed (╌)") ? line.style_dashed :
     (styleOption == "arrow left (←)") ? line.style_arrow_left :
     (styleOption == "arrow right (→)") ? line.style_arrow_right :
     (styleOption == "arrows both (↔)") ? line.style_arrow_both :
         line.style_solid
         
styleOption_r = input.string(title="Line Style",
     options=["Right stretch", "Left stretch", "Full stretch"],
     defval="Full stretch",group="Levels settings")

lineStyle_r = (styleOption_r == "Right stretch") ? extend.right :
     (styleOption_r == "Left stretch") ?extend.left:
     (styleOption_r == "Full stretch") ? extend.both :extend.none
     
                  
         
         
line_w=input.int(1,"Line Width",minval=1,maxval=5)

col_ath=input.color(color.maroon,"ATH/ATH",group="Levels settings")
col_atl=input.color(color.red,"Weekly H/L",group="Levels settings")
col_atl_d=input.color(color.blue,"Daily H/L",group="Levels settings")
col_atl_d_=input.color(color.yellow,"Two day ago H/L",group="Levels settings")

remove_ath=input(false,"Display ATH",group="Levels settings")
remove_atl=input(false,"Display ATL",group="Levels settings")

remove_wklyh=input(false,"Display Weekly high",group="Levels settings")
remove_wklyl=input(false,"Display Weekly Low",group="Levels settings")

remove_pdh=input(false,"Display Pre Day High",group="Levels settings")
remove_pdl=input(false,"Display Pre Day low",group="Levels settings")

remove_2pdh=input(false,"Display two days High",group="Levels settings")
remove_2pdl=input(false,"Display two days low",group="Levels settings")

no_of_bars=ta.barssince(ta.change(time("D")))

/////////////////////////////////////////////////////////
//calculate ATH and ATL    

g = bar_index == 1
ath() =>
    a = 0.0
    a := g ? high : high > a[1] ? high : a[1]
    

a_ = request.security(syminfo.tickerid, 'M', ath(), lookahead=barmerge.lookahead_on)

atl() =>
    r = 0.0
    r := g ? low : low < r[1] ? low : r[1]
    

r_ = request.security(syminfo.tickerid, 'M', atl(), lookahead=barmerge.lookahead_on)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Calculate WH/WL
ftwh() =>
    h = ta.highest(high[1], 1)
    

h = request.security(syminfo.tickerid, 'W', ftwh(), lookahead=barmerge.lookahead_on)

ftwl() =>
    l = ta.lowest(low[1], 1)
    

l = request.security(syminfo.tickerid, 'W', ftwl(), lookahead=barmerge.lookahead_on)

////////////////////////////////////////////////////////////////////////////////////////////////

r_y = request.security(syminfo.tickerid, 'D', high[1], lookahead=barmerge.lookahead_on)
_y_l = request.security(syminfo.tickerid, 'D', low[1], lookahead=barmerge.lookahead_on)

//////////////////////////////////////
r_y_l = request.security(syminfo.tickerid, 'D', low[1], lookahead=barmerge.lookahead_on)

r_y_2 = request.security(syminfo.tickerid, 'D', high[2], lookahead=barmerge.lookahead_on)
r_y_l_2 = request.security(syminfo.tickerid, 'D', low[2], lookahead=barmerge.lookahead_on)


//Plotting lines for All above levels
line ln1=na
label lb1=na
line ln2=na
label lb2=na
line ln3=na
label lb3=na
line ln4=na
label lb4=na
line ln5=na
label lb5=na
line ln6=na
label lb6=na
line ln7=na
label lb7=na
line ln8=na
label lb8=na

if (barstate.islast)
    if remove_ath
        ln1:=line.new(x1=bar_index[no_of_bars], y1=a_,
             x2=bar_index, y2=a_, width=line_w, color=col_ath,
             style=lineStyle,extend=lineStyle_r)
        lb1:=label.new(bar_index, a_, '                       ATH=' + str.tostring(a_), color=color.new(color.green, 100), textcolor=col_ath, size=size.small, style=label.style_label_up)

    if remove_atl
        ln2:=line.new(x1=bar_index[no_of_bars], y1=r_,
             x2=bar_index, y2=r_, width=line_w, color=col_ath,
             style=lineStyle,extend=lineStyle_r)
        lb2:=label.new(bar_index, r_, '                       ATL=' + str.tostring(r_), color=color.new(color.red, 100), textcolor=col_ath, size=size.small, style=label.style_label_up)



    if remove_wklyh
        ln3:=line.new(x1=bar_index[no_of_bars], y1=h,
             x2=bar_index, y2=h, width=line_w, color=col_atl,
             style=lineStyle,extend=lineStyle_r)
        lb3:=label.new(bar_index, h, '                       Weekly High=' + str.tostring(h), color=color.new(color.green, 100), textcolor=col_atl, size=size.small, style=label.style_label_up)

    if remove_wklyl
        ln4:=line.new(x1=bar_index[no_of_bars], y1=l,
             x2=bar_index, y2=l, width=line_w, color=col_atl,
             style=lineStyle,extend=lineStyle_r)
        lb4:=label.new(bar_index, l, '                       Weekly Low=' + str.tostring(l), color=color.new(color.red, 100), textcolor=col_atl, size=size.small, style=label.style_label_up)




    if remove_pdh
        ln5:=line.new(x1=bar_index[no_of_bars], y1=r_y,
             x2=bar_index, y2=r_y, width=line_w, color=col_atl_d,
             style=lineStyle,extend=lineStyle_r)
        lb5:=label.new(bar_index, r_y, '                       Pre Day High=' + str.tostring(r_y), color=color.new(color.green, 100), textcolor=col_atl_d, size=size.small, style=label.style_label_up)

    if remove_pdl
        ln6:=line.new(x1=bar_index[no_of_bars], y1=r_y_l,
             x2=bar_index, y2=r_y_l, width=line_w, color=col_atl_d,
             style=lineStyle,extend=lineStyle_r)
        lb6:=label.new(bar_index, r_y_l, '                       Pre Day Low=' + str.tostring(r_y_l), color=color.new(color.red, 100), textcolor=col_atl_d, size=size.small, style=label.style_label_up)



    if remove_2pdh
        ln7:=line.new(x1=bar_index[no_of_bars], y1=r_y_l_2,
             x2=bar_index, y2=r_y_l_2, width=line_w, color=col_atl_d_,
             style=lineStyle,extend=lineStyle_r)
        lb7:=label.new(bar_index, r_y_l_2, '                       Two Day ago Low=' + str.tostring(r_y_l_2 ), color=color.new(color.red, 100), textcolor=col_atl_d_, size=size.small, style=label.style_label_up)

    if remove_2pdl
        ln8:=line.new(x1=bar_index[no_of_bars], y1=r_y_2,
             x2=bar_index, y2=r_y_2, width=line_w, color=col_atl_d_,
             style=lineStyle,extend=lineStyle_r)
        lb8:=label.new(bar_index, r_y_2, '                       Two Day ago High=' + str.tostring(r_y_2), color=color.new(color.green, 100), textcolor=col_atl_d_, size=size.small, style=label.style_label_up)

line.delete(ln1[1]) 
label.delete(lb1[1]) 

line.delete(ln2[1]) 
label.delete(lb2[1]) 

line.delete(ln3[1]) 
label.delete(lb3[1]) 

line.delete(ln4[1]) 
label.delete(lb4[1]) 

line.delete(ln5[1]) 
label.delete(lb5[1]) 

line.delete(ln6[1]) 
label.delete(lb6[1]) 

line.delete(ln7[1]) 
label.delete(lb7[1]) 

line.delete(ln8[1]) 
label.delete(lb8[1]) 

////////////////////////////////////////////////////////
// code to get the divergence levels 
prd = input.int(defval=5, title='Pivot Period', minval=1, maxval=50,group="Divergence settings",group="Divergence settings")
source = input.string(defval='Close', title='Source for Pivot Points', options=['Close', 'High/Low'],group="Divergence settings")
searchdiv = input.string(defval='Regular', title='Divergence Type', options=['Regular', 'Hidden', 'Regular/Hidden'],group="Divergence settings")
showindis = input.string(defval='Don\'t Show', title='Show Indicator Names', options=['Full', 'First Letter', 'Don\'t Show'],group="Divergence settings")
showlimit = input.int(1, title='Minimum Number of Divergence', minval=1, maxval=11,group="Divergence settings")
maxpp = input.int(defval=10, title='Maximum Pivot Points to Check', minval=1, maxval=20,group="Divergence settings")
maxbars = input.int(defval=100, title='Maximum Bars to Check', minval=30, maxval=200,group="Divergence settings")
shownum = input(defval=false, title='Show Divergence Number',group="Divergence settings")
showlast = input(defval=false, title='Show Only Last Divergence',group="Divergence settings")
dontconfirm = input(defval=false, title='Don\'t Wait for Confirmation',group="Divergence settings")
showlines = input(defval=false, title='Show Divergence Lines',group="Divergence settings")
showpivot = input(defval=false, title='Show Pivot Points',group="Divergence settings")
calcmacd = input(defval=true, title='MACD',group="Divergence settings")
calcmacda = input(defval=true, title='MACD Histogram',group="Divergence settings")
calcrsi = input(defval=true, title='RSI',group="Divergence settings")
calcstoc = input(defval=true, title='Stochastic',group="Divergence settings")
calccci = input(defval=true, title='CCI',group="Divergence settings")
calcmom = input(defval=true, title='Momentum',group="Divergence settings")
calcobv = input(defval=true, title='OBV',group="Divergence settings")
calcvwmacd = input(true, title='VWmacd',group="Divergence settings")
calccmf = input(true, title='Chaikin Money Flow',group="Divergence settings")
calcmfi = input(true, title='Money Flow Index',group="Divergence settings")
calcext = input(false, title='Check External Indicator',group="Divergence settings")
externalindi = input(defval=close, title='External Indicator',group="Divergence settings")
pos_reg_div_col = input(defval=color.yellow, title='Positive Regular Divergence',group="Divergence settings")
neg_reg_div_col = input(defval=color.navy, title='Negative Regular Divergence',group="Divergence settings")
pos_hid_div_col = input(defval=color.lime, title='Positive Hidden Divergence',group="Divergence settings")
neg_hid_div_col = input(defval=color.red, title='Negative Hidden Divergence',group="Divergence settings")
pos_div_text_col = input(defval=color.black, title='Positive Divergence Text Color',group="Divergence settings")
neg_div_text_col = input(defval=color.white, title='Negative Divergence Text Color',group="Divergence settings")
reg_div_l_style_ = input.string(defval='Solid', title='Regular Divergence Line Style', options=['Solid', 'Dashed', 'Dotted'],group="Divergence settings")
hid_div_l_style_ = input.string(defval='Dashed', title='Hdden Divergence Line Style', options=['Solid', 'Dashed', 'Dotted'],group="Divergence settings")
reg_div_l_width = input.int(defval=2, title='Regular Divergence Line Width', minval=1, maxval=5,group="Divergence settings")
hid_div_l_width = input.int(defval=1, title='Hidden Divergence Line Width', minval=1, maxval=5,group="Divergence settings")
showmas = input.bool(defval=false, title='Show MAs 50 & 200', inline='ma12',group="Divergence settings")
cma1col = input.color(defval=color.lime, title='', inline='ma12',group="Divergence settings")
cma2col = input.color(defval=color.red, title='', inline='ma12',group="Divergence settings")

plot(showmas ? ta.sma(close, 50) : na, color=showmas ? cma1col : na)
plot(showmas ? ta.sma(close, 200) : na, color=showmas ? cma2col : na)

// set line styles
var reg_div_l_style = reg_div_l_style_ == 'Solid' ? line.style_solid : reg_div_l_style_ == 'Dashed' ? line.style_dashed : line.style_dotted
var hid_div_l_style = hid_div_l_style_ == 'Solid' ? line.style_solid : hid_div_l_style_ == 'Dashed' ? line.style_dashed : line.style_dotted


// get indicators
rsi = ta.rsi(close, 14)  // RSI
[macd, signal, deltamacd] = ta.macd(close, 12, 26, 9)  // MACD
moment = ta.mom(close, 10)  // Momentum
cci = ta.cci(close, 10)  // CCI
Obv = ta.obv  // OBV
stk = ta.sma(ta.stoch(close, high, low, 14), 3)  // Stoch
maFast = ta.vwma(close, 12)  // volume weighted macd
maSlow = ta.vwma(close, 26)
vwmacd = maFast - maSlow
Cmfm = (close - low - (high - close)) / (high - low)  // Chaikin money flow
Cmfv = Cmfm * volume
cmf = ta.sma(Cmfv, 21) / ta.sma(volume, 21)
Mfi = ta.mfi(close, 14)  // Moneyt Flow Index

// keep indicators names and colors in arrays
var indicators_name = array.new_string(11)
var div_colors = array.new_color(4)
if barstate.isfirst
    // names
    array.set(indicators_name, 0, showindis == 'Full' ? 'MACD' : 'M')
    array.set(indicators_name, 1, showindis == 'Full' ? 'Hist' : 'H')
    array.set(indicators_name, 2, showindis == 'Full' ? 'RSI' : 'E')
    array.set(indicators_name, 3, showindis == 'Full' ? 'Stoch' : 'S')
    array.set(indicators_name, 4, showindis == 'Full' ? 'CCI' : 'C')
    array.set(indicators_name, 5, showindis == 'Full' ? 'MOM' : 'M')
    array.set(indicators_name, 6, showindis == 'Full' ? 'OBV' : 'O')
    array.set(indicators_name, 7, showindis == 'Full' ? 'VWMACD' : 'V')
    array.set(indicators_name, 8, showindis == 'Full' ? 'CMF' : 'C')
    array.set(indicators_name, 9, showindis == 'Full' ? 'MFI' : 'M')
    array.set(indicators_name, 10, showindis == 'Full' ? 'Extrn' : 'X')
    //colors
    array.set(div_colors, 0, pos_reg_div_col)
    array.set(div_colors, 1, neg_reg_div_col)
    array.set(div_colors, 2, pos_hid_div_col)
    array.set(div_colors, 3, neg_hid_div_col)

// Check if we get new Pivot High Or Pivot Low
float ph = ta.pivothigh(source == 'Close' ? close : high, prd, prd)
float pl = ta.pivotlow(source == 'Close' ? close : low, prd, prd)
plotshape(ph and showpivot, text='H', style=shape.labeldown, color=color.new(color.white, 100), textcolor=color.new(color.red, 0), location=location.abovebar, offset=-prd)
plotshape(pl and showpivot, text='L', style=shape.labelup, color=color.new(color.white, 100), textcolor=color.new(color.lime, 0), location=location.belowbar, offset=-prd)

// keep values and positions of Pivot Highs/Lows in the arrays
var int maxarraysize = 20
var ph_positions = array.new_int(maxarraysize, 0)
var pl_positions = array.new_int(maxarraysize, 0)
var ph_vals = array.new_float(maxarraysize, 0.)
var pl_vals = array.new_float(maxarraysize, 0.)

// add PHs to the array
if ph
    array.unshift(ph_positions, bar_index)
    array.unshift(ph_vals, ph)
    if array.size(ph_positions) > maxarraysize
        array.pop(ph_positions)
        array.pop(ph_vals)

// add PLs to the array
if pl
    array.unshift(pl_positions, bar_index)
    array.unshift(pl_vals, pl)
    if array.size(pl_positions) > maxarraysize
        array.pop(pl_positions)
        array.pop(pl_vals)

// functions to check Regular Divergences and Hidden Divergences

// function to check positive regular or negative hidden divergence
// cond == 1 => positive_regular, cond == 2=> negative_hidden
positive_regular_positive_hidden_divergence(src, cond) =>
    divlen = 0
    prsc = source == 'Close' ? close : low
    // if indicators higher than last value and close price is higher than las close 
    if dontconfirm or src > src[1] or close > close[1]
        startpoint = dontconfirm ? 0 : 1  // don't check last candle
        // we search last 15 PPs
        for x = 0 to maxpp - 1 by 1
            len = bar_index - array.get(pl_positions, x) + prd
            // if we reach non valued array element or arrived 101. or previous bars then we don't search more
            if array.get(pl_positions, x) == 0 or len > maxbars
                break
            if len > 5 and (cond == 1 and src[startpoint] > src[len] and prsc[startpoint] < nz(array.get(pl_vals, x)) or cond == 2 and src[startpoint] < src[len] and prsc[startpoint] > nz(array.get(pl_vals, x)))
                slope1 = (src[startpoint] - src[len]) / (len - startpoint)
                virtual_line1 = src[startpoint] - slope1
                slope2 = (close[startpoint] - close[len]) / (len - startpoint)
                virtual_line2 = close[startpoint] - slope2
                arrived = true
                for y = 1 + startpoint to len - 1 by 1
                    if src[y] < virtual_line1 or nz(close[y]) < virtual_line2
                        arrived := false
                        break
                    virtual_line1 -= slope1
                    virtual_line2 -= slope2
                    virtual_line2

                if arrived
                    divlen := len
                    break
    divlen

// function to check negative regular or positive hidden divergence
// cond == 1 => negative_regular, cond == 2=> positive_hidden
negative_regular_negative_hidden_divergence(src, cond) =>
    divlen = 0
    prsc = source == 'Close' ? close : high
    // if indicators higher than last value and close price is higher than las close 
    if dontconfirm or src < src[1] or close < close[1]
        startpoint = dontconfirm ? 0 : 1  // don't check last candle
        // we search last 15 PPs
        for x = 0 to maxpp - 1 by 1
            len = bar_index - array.get(ph_positions, x) + prd
            // if we reach non valued array element or arrived 101. or previous bars then we don't search more
            if array.get(ph_positions, x) == 0 or len > maxbars
                break
            if len > 5 and (cond == 1 and src[startpoint] < src[len] and prsc[startpoint] > nz(array.get(ph_vals, x)) or cond == 2 and src[startpoint] > src[len] and prsc[startpoint] < nz(array.get(ph_vals, x)))
                slope1 = (src[startpoint] - src[len]) / (len - startpoint)
                virtual_line1 = src[startpoint] - slope1
                slope2 = (close[startpoint] - nz(close[len])) / (len - startpoint)
                virtual_line2 = close[startpoint] - slope2
                arrived = true
                for y = 1 + startpoint to len - 1 by 1
                    if src[y] > virtual_line1 or nz(close[y]) > virtual_line2
                        arrived := false
                        break
                    virtual_line1 -= slope1
                    virtual_line2 -= slope2
                    virtual_line2

                if arrived
                    divlen := len
                    break
    divlen

// calculate 4 types of divergence if enabled in the options and return divergences in an array
calculate_divs(cond, indicator_1) =>
    divs = array.new_int(4, 0)
    array.set(divs, 0, cond and (searchdiv == 'Regular' or searchdiv == 'Regular/Hidden') ? positive_regular_positive_hidden_divergence(indicator_1, 1) : 0)
    array.set(divs, 1, cond and (searchdiv == 'Regular' or searchdiv == 'Regular/Hidden') ? negative_regular_negative_hidden_divergence(indicator_1, 1) : 0)
    array.set(divs, 2, cond and (searchdiv == 'Hidden' or searchdiv == 'Regular/Hidden') ? positive_regular_positive_hidden_divergence(indicator_1, 2) : 0)
    array.set(divs, 3, cond and (searchdiv == 'Hidden' or searchdiv == 'Regular/Hidden') ? negative_regular_negative_hidden_divergence(indicator_1, 2) : 0)
    divs

// array to keep all divergences
var all_divergences = array.new_int(44)  // 11 indicators * 4 divergence = 44 elements
// set related array elements
array_set_divs(div_pointer, index) =>
    for x = 0 to 3 by 1
        array.set(all_divergences, index * 4 + x, array.get(div_pointer, x))

// set divergences array 
array_set_divs(calculate_divs(calcmacd, macd), 0)
array_set_divs(calculate_divs(calcmacda, deltamacd), 1)
array_set_divs(calculate_divs(calcrsi, rsi), 2)
array_set_divs(calculate_divs(calcstoc, stk), 3)
array_set_divs(calculate_divs(calccci, cci), 4)
array_set_divs(calculate_divs(calcmom, moment), 5)
array_set_divs(calculate_divs(calcobv, Obv), 6)
array_set_divs(calculate_divs(calcvwmacd, vwmacd), 7)
array_set_divs(calculate_divs(calccmf, cmf), 8)
array_set_divs(calculate_divs(calcmfi, Mfi), 9)
array_set_divs(calculate_divs(calcext, externalindi), 10)

// check minimum number of divergence, if less than showlimit then delete all divergence
total_div = 0
for x = 0 to array.size(all_divergences) - 1 by 1
    total_div += math.round(math.sign(array.get(all_divergences, x)))
    total_div

if total_div < showlimit
    array.fill(all_divergences, 0)

// keep line in an array
var pos_div_lines = array.new_line(0)
var neg_div_lines = array.new_line(0)
var pos_div_labels = array.new_label(0)
var neg_div_labels = array.new_label(0)

// remove old lines and labels if showlast option is enabled
delete_old_pos_div_lines() =>
    if array.size(pos_div_lines) > 0
        for j = 0 to array.size(pos_div_lines) - 1 by 1
            line.delete(array.get(pos_div_lines, j))
        array.clear(pos_div_lines)

delete_old_neg_div_lines() =>
    if array.size(neg_div_lines) > 0
        for j = 0 to array.size(neg_div_lines) - 1 by 1
            line.delete(array.get(neg_div_lines, j))
        array.clear(neg_div_lines)

delete_old_pos_div_labels() =>
    if array.size(pos_div_labels) > 0
        for j = 0 to array.size(pos_div_labels) - 1 by 1
            label.delete(array.get(pos_div_labels, j))
        array.clear(pos_div_labels)

delete_old_neg_div_labels() =>
    if array.size(neg_div_labels) > 0
        for j = 0 to array.size(neg_div_labels) - 1 by 1
            label.delete(array.get(neg_div_labels, j))
        array.clear(neg_div_labels)

// delete last creted lines and labels until we met new PH/PV 
delete_last_pos_div_lines_label(n) =>
    if n > 0 and array.size(pos_div_lines) >= n
        asz = array.size(pos_div_lines)
        for j = 1 to n by 1
            line.delete(array.get(pos_div_lines, asz - j))
            array.pop(pos_div_lines)
        if array.size(pos_div_labels) > 0
            label.delete(array.get(pos_div_labels, array.size(pos_div_labels) - 1))
            array.pop(pos_div_labels)

delete_last_neg_div_lines_label(n) =>
    if n > 0 and array.size(neg_div_lines) >= n
        asz = array.size(neg_div_lines)
        for j = 1 to n by 1
            line.delete(array.get(neg_div_lines, asz - j))
            array.pop(neg_div_lines)
        if array.size(neg_div_labels) > 0
            label.delete(array.get(neg_div_labels, array.size(neg_div_labels) - 1))
            array.pop(neg_div_labels)

// variables for Alerts
pos_reg_div_detected = false
neg_reg_div_detected = false
pos_hid_div_detected = false
neg_hid_div_detected = false

// to remove lines/labels until we met new // PH/PL
var last_pos_div_lines = 0
var last_neg_div_lines = 0
var remove_last_pos_divs = false
var remove_last_neg_divs = false
if pl
    remove_last_pos_divs := false
    last_pos_div_lines := 0
    last_pos_div_lines
if ph
    remove_last_neg_divs := false
    last_neg_div_lines := 0
    last_neg_div_lines

// draw divergences lines and labels
divergence_text_top = ''
divergence_text_bottom = ''
distances = array.new_int(0)
dnumdiv_top = 0
dnumdiv_bottom = 0
top_label_col = color.white
bottom_label_col = color.white
old_pos_divs_can_be_removed = true
old_neg_divs_can_be_removed = true
startpoint = dontconfirm ? 0 : 1  // used for don't confirm option

for x = 0 to 10 by 1
    div_type = -1
    for y = 0 to 3 by 1
        if array.get(all_divergences, x * 4 + y) > 0  // any divergence?
            div_type := y
            if y % 2 == 1
                dnumdiv_top += 1
                top_label_col := array.get(div_colors, y)
                top_label_col
            if y % 2 == 0
                dnumdiv_bottom += 1
                bottom_label_col := array.get(div_colors, y)
                bottom_label_col
            if not array.includes(distances, array.get(all_divergences, x * 4 + y))  // line not exist ?
                array.push(distances, array.get(all_divergences, x * 4 + y))
                new_line = showlines ? line.new(x1=bar_index - array.get(all_divergences, x * 4 + y), y1=source == 'Close' ? close[array.get(all_divergences, x * 4 + y)] : y % 2 == 0 ? low[array.get(all_divergences, x * 4 + y)] : high[array.get(all_divergences, x * 4 + y)], x2=bar_index - startpoint, y2=source == 'Close' ? close[startpoint] : y % 2 == 0 ? low[startpoint] : high[startpoint], color=array.get(div_colors, y), style=y < 2 ? reg_div_l_style : hid_div_l_style, width=y < 2 ? reg_div_l_width : hid_div_l_width) : na
                if y % 2 == 0
                    if old_pos_divs_can_be_removed
                        old_pos_divs_can_be_removed := false
                        if not showlast and remove_last_pos_divs
                            delete_last_pos_div_lines_label(last_pos_div_lines)
                            last_pos_div_lines := 0
                            last_pos_div_lines
                        if showlast
                            delete_old_pos_div_lines()
                    array.push(pos_div_lines, new_line)
                    last_pos_div_lines += 1
                    remove_last_pos_divs := true
                    remove_last_pos_divs

                if y % 2 == 1
                    if old_neg_divs_can_be_removed
                        old_neg_divs_can_be_removed := false
                        if not showlast and remove_last_neg_divs
                            delete_last_neg_div_lines_label(last_neg_div_lines)
                            last_neg_div_lines := 0
                            last_neg_div_lines
                        if showlast
                            delete_old_neg_div_lines()
                    array.push(neg_div_lines, new_line)
                    last_neg_div_lines += 1
                    remove_last_neg_divs := true
                    remove_last_neg_divs

            // set variables for alerts
            if y == 0
                pos_reg_div_detected := true
                pos_reg_div_detected
            if y == 1
                neg_reg_div_detected := true
                neg_reg_div_detected
            if y == 2
                pos_hid_div_detected := true
                pos_hid_div_detected
            if y == 3
                neg_hid_div_detected := true
                neg_hid_div_detected
    // get text for labels
    if div_type >= 0
        divergence_text_top += (div_type % 2 == 1 ? showindis != 'Don\'t Show' ? array.get(indicators_name, x) + '\n' : '' : '')
        divergence_text_bottom += (div_type % 2 == 0 ? showindis != 'Don\'t Show' ? array.get(indicators_name, x) + '\n' : '' : '')
        divergence_text_bottom

// draw labels
if showindis != 'Don\'t Show' or shownum
    if shownum and dnumdiv_top > 0
        divergence_text_top += str.tostring(dnumdiv_top)
        divergence_text_top
    if shownum and dnumdiv_bottom > 0
        divergence_text_bottom += str.tostring(dnumdiv_bottom)
        divergence_text_bottom
    if divergence_text_top != ''
        if showlast
            delete_old_neg_div_labels()
        array.push(neg_div_labels, label.new(x=bar_index, y=math.max(high, high[1]), text=divergence_text_top, color=top_label_col, textcolor=neg_div_text_col, style=label.style_label_down))

    if divergence_text_bottom != ''
        if showlast
            delete_old_pos_div_labels()
        array.push(pos_div_labels, label.new(x=bar_index, y=math.min(low, low[1]), text=divergence_text_bottom, color=bottom_label_col, textcolor=pos_div_text_col, style=label.style_label_up))

seprator = input.bool(true, '=====================================================',group="Divergence settings")



/////////////////////////FIB levels By DGT
// -Inputs ══════════════════════════════════════════════════════════════════════════════════════ //
tooltip_threshold = 'Deviation is a multiplier that affects how much the price should deviate from the previous pivot in order for the bar to become a new pivot' + '\n\nDepth affects the minimum number of bars that will be taken into account when building'

// ---------------------------------------------------------------------------------------- //
// pivots threshold

threshold_multiplier = input.float(9, 'Deviation', minval=0, inline='Pivots', tooltip=tooltip_threshold,group="FIB by DGT settings")
dev_threshold = ta.atr(10) / close * 100 * threshold_multiplier
depth = input.int(1, 'Depth', minval=1, inline='Pivots',group="FIB by DGT settings")

// pivots threshold
// ---------------------------------------------------------------------------------------- //
// Zig Zag

ZigZag = input.bool(false, 'Zig Zag', inline='ZZ', group='Zig Zag Settings')
zzColor = input.color(color.orange, '', inline='ZZ', group='Zig Zag Settings')
zzWidth = input.int(1, '', minval=1, inline='ZZ', group='Zig Zag Settings')
zzStyle = input.string('Solid', '', options=['Dashed', 'Dotted', 'Solid'], inline='ZZ', group='Zig Zag Settings')

// Zig Zag
// ---------------------------------------------------------------------------------------- //
// Fibonacci 

group_fib_RetExt = 'Channel / Retracement-Extention Settings'

isFibChannel = input.bool(false, 'Fib Channel     |   ', inline='FIB', group=group_fib_RetExt)
fibExtRet = input.string('Fib Retracement', '', options=['Fib Retracement', 'Fib Extention'], inline='FIB', group=group_fib_RetExt)

isFibRetOrExt = input.bool(true, '', inline='FIB', group=group_fib_RetExt)

prevPivot = input.bool(false, 'Historical Channels / Retracements-Extentions', inline='hPVT', group=group_fib_RetExt)
histPivot = input.int(1, '', minval=1, inline='hPVT', group=group_fib_RetExt)
extendL = input.bool(false, 'Extend Lines', group=group_fib_RetExt)
reverse = input.bool(false, 'Reverse Retracement-Extention Levels', group=group_fib_RetExt)

channelLevels = input.bool(true, 'Level Labels : Channel | Retracement-Extention', inline='Levels', group=group_fib_RetExt)
retExtLevels = input.bool(true, '', inline='Levels', group=group_fib_RetExt)
levelPrices = input.bool(true, 'Prices    |    Levels', inline='Levels2', group=group_fib_RetExt)
levelLevels = input.bool(true, '', inline='Levels2', group=group_fib_RetExt)
levelFormat = input.string('Values', '', options=['Values', 'Percent'], inline='Levels2', group=group_fib_RetExt)

uniColor = input.bool(false, 'UniColor : Channels | Retracements-Extentions', inline='uni', group=group_fib_RetExt)
uniColor1 = input.color(#0ac9f0, '', inline='uni', group=group_fib_RetExt)
uniColor2 = input.color(#ffa726, '', inline='uni', group=group_fib_RetExt)
// Fibonacci 
// ---------------------------------------------------------------------------------------- //

// -Calculations ════════════════════════════════════════════════════════════════════════════════ //

var line lineLast = na
var int iLast = 0
var int iPrev = 0
var float pLast = 0
var isHighLast = false  // otherwise the last pivot is a low pivot

var iPrevPivot = 0
var pPrevPivot = 0.
var iLastPivot = 0
var pLastPivot = 0.

pivots(src, length, isHigh) =>
    l2 = length * 2
    c = nz(src[length])
    ok = true

    for i = 0 to l2 by 1
        if isHigh and src[i] > c
            ok := false
            ok

        if not isHigh and src[i] < c
            ok := false
            ok
    if ok
        [bar_index[length], c]
    else
        [int(na), float(na)]

[iH, pH] = pivots(high, depth / 2, true)
[iL, pL] = pivots(low, depth / 2, false)

calc_dev(base_price, price) =>
    100 * (price - base_price) / price

pivotFound(dev, isHigh, index, price) =>
    if isHighLast == isHigh and not na(lineLast)
        // same direction
        if isHighLast ? price > pLast : price < pLast
            line.set_xy2(lineLast, index, price)
            [lineLast, isHighLast]
        else
            [line(na), bool(na)]
    else
        // reverse the direction (or create the very first line)
        if math.abs(dev) > dev_threshold
            // price move is significant

            // ---------------------------------------------------------------------------------------- //
            [zzCol, zzWid, zzSty] = if not ZigZag
                [na, 1, line.style_dashed]
            else
                [zzColor, zzWidth, zzStyle == 'Solid' ? line.style_solid : zzStyle == 'Dotted' ? line.style_dotted : line.style_dashed]
            // ---------------------------------------------------------------------------------------- //

            id = line.new(iLast, pLast, index, price, color=zzCol, width=zzWid, style=zzSty)
            [id, isHigh]
        else
            [line(na), bool(na)]

if not na(iH)
    dev = calc_dev(pLast, pH)
    [id, isHigh] = pivotFound(dev, true, iH, pH)

    if not na(id)
        if id != lineLast
            // ---------------------------------------------------------------------------------------- //
            iPrevPivot := line.get_x1(lineLast)
            pPrevPivot := line.get_y1(lineLast)
            iLastPivot := line.get_x2(lineLast)
            pLastPivot := line.get_y2(lineLast)

            if not ZigZag
            // ---------------------------------------------------------------------------------------- //

                line.delete(lineLast)

        lineLast := id
        isHighLast := isHigh
        iPrev := iLast
        iLast := iH
        pLast := pH
        pLast
else
    if not na(iL)
        dev = calc_dev(pLast, pL)
        [id, isHigh] = pivotFound(dev, false, iL, pL)

        if not na(id)
            if id != lineLast
                // ---------------------------------------------------------------------------------------- //
                iPrevPivot := line.get_x1(lineLast)
                pPrevPivot := line.get_y1(lineLast)
                iLastPivot := line.get_x2(lineLast)
                pLastPivot := line.get_y2(lineLast)

                if not ZigZag
                // ---------------------------------------------------------------------------------------- //

                    line.delete(lineLast)

            lineLast := id
            isHighLast := isHigh
            iPrev := iLast
            iLast := iL
            pLast := pL
            pLast

iStartBase = prevPivot ? ta.valuewhen(ta.change(iPrevPivot), iPrevPivot, histPivot) : ta.valuewhen(ta.change(iPrevPivot), iPrevPivot, 0)
pStartBase = prevPivot ? ta.valuewhen(ta.change(pPrevPivot), pPrevPivot, histPivot) : ta.valuewhen(ta.change(pPrevPivot), pPrevPivot, 0)
iEndBase = prevPivot ? ta.valuewhen(ta.change(iLastPivot), iLastPivot, histPivot - 1) : line.get_x2(lineLast)
pEndBase = prevPivot ? ta.valuewhen(ta.change(pLastPivot), pLastPivot, histPivot - 1) : line.get_y2(lineLast)
iMidPivot = prevPivot ? ta.valuewhen(ta.change(iPrevPivot), iPrevPivot, histPivot - 1) : line.get_x1(lineLast)
pMidPivot = prevPivot ? ta.valuewhen(ta.change(pPrevPivot), pPrevPivot, histPivot - 1) : line.get_y1(lineLast)

slope = (pEndBase - pStartBase) / (iEndBase - iStartBase)

iPivotDiff = iMidPivot - iStartBase
pPivotDiff = math.abs(pMidPivot - pStartBase)

_crossing_level(sr, r) =>
    r > sr and r < sr[1] or r < sr and r > sr[1]

var a_ln = array.new_line()

if array.size(a_ln) > 0
    a_ln_size = array.size(a_ln)
    for i = 1 to a_ln_size by 1
        ln = array.shift(a_ln)
        line.delete(ln)

f_draw_line(_iStart, _pStart, _iEnd, _pEnd, _color, _width, _style, _extend, _level) =>
    style = _style == 'Solid' ? line.style_solid : _style == 'Dotted' ? line.style_dotted : line.style_dashed

    if _iStart < bar_index
        array.push(a_ln, line.new(_iStart, _pStart, _iEnd, _pEnd, xloc.bar_index, extendL ? extend.both : extend.right, _color, style, _width))

_draw_line(_price, _color, _ext) =>
    var id = line.new(iLast, _price, bar_index, _price, xloc.bar_index, extendL ? extend.both : extend.right, _color, line.style_solid, 1)
    if not na(lineLast)
        line.set_xy1(id, _ext ? iMidPivot : iStartBase, _price)
        line.set_xy2(id, line.get_x2(lineLast), _price)

_draw_label(index, price, txt, txtColor, style, align) =>

    labelsAlignStr = txt + '\n ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏ \n'

    var id = label.new(index, price, txt, textcolor=txtColor, style=style, textalign=align, color=#00000000)
    label.set_xy(id, index, price)
    label.set_text(id, labelsAlignStr)
    label.set_textcolor(id, txtColor)

_label_txt(level, price) =>
    l = levelFormat == 'Values' ? str.tostring(level) : str.tostring(level * 100) + '%'
    (levelLevels ? l : '') + (levelPrices ? ' (' + str.tostring(math.round(price / syminfo.mintick) * syminfo.mintick) + ')' : '')

processLevel(show, value, colorL) =>
    array.push(a_ln, line.new(iStartBase, pStartBase, iMidPivot, pMidPivot, xloc.bar_index, extend.none, color.gray, line.style_dashed, 1))
    var float pass_value = na
    if isFibChannel
        array.push(a_ln, line.new(iMidPivot, pMidPivot, iEndBase, pEndBase, xloc.bar_index, extend.none, color.gray, line.style_dashed, 1))

        if show
            iStart = int(math.round(iStartBase + iPivotDiff * value))
            intercept = pStartBase < pMidPivot ? pStartBase + pPivotDiff * value - slope * iStart : pStartBase - pPivotDiff * value - slope * iStart
            pStart = slope * iStart + intercept
            iEnd = iStart < iEndBase ? iEndBase : bar_index
            pEnd = slope * iEnd + intercept

            f_draw_line(iStart, pStart, iEnd, pEnd, uniColor ? uniColor1 : colorL, 1, 'Solid', true, value)

            if channelLevels
                _draw_label(bar_index, slope * bar_index + intercept, _label_txt(value, slope * bar_index + intercept), uniColor ? uniColor1 : colorL, label.style_label_left, text.align_left)

    if isFibRetOrExt
        r = 0.
        isExt = false

        if fibExtRet == 'Fib Extention'
            array.push(a_ln, line.new(iMidPivot, pMidPivot, iEndBase, pEndBase, xloc.bar_index, extend.none, color.gray, line.style_dashed, 1))
            isExt := true
            offset = math.abs(pMidPivot - pEndBase)
            r := pEndBase < pMidPivot ? pMidPivot - offset + (reverse ? -1 : 1) * pPivotDiff * value : pMidPivot + offset - (reverse ? -1 : 1) * pPivotDiff * value
            r
        else
            r := pStartBase < pMidPivot ? (reverse ? pMidPivot : pStartBase) + (reverse ? -1 : 1) * pPivotDiff * value : (reverse ? pMidPivot : pStartBase) - (reverse ? -1 : 1) * pPivotDiff * value
            r
        pass_value := r
        if show
            _draw_line(r, uniColor ? uniColor2 : colorL, isExt)

            if retExtLevels
                _draw_label(isExt ? iMidPivot : iStartBase, r, _label_txt(value, r), uniColor ? uniColor2 : colorL, label.style_label_right, text.align_right)
    [pass_value]
group_fib_levels = 'Channel / Retracement-Extention Levels'

show_0 = input.bool(false, '', inline='Level1', group=group_fib_levels)
value_0 = input.float(0., '', inline='Level1', group=group_fib_levels)
color_0 = input.color(#787b86, '', inline='Level1', group=group_fib_levels)
[r0] = processLevel(show_0, value_0, color_0)

show_0_236 = input.bool(false, '', inline='Level2', group=group_fib_levels)
value_0_236 = input.float(0.236, '', inline='Level2', group=group_fib_levels)
color_0_236 = input.color(#f44336, '', inline='Level2', group=group_fib_levels)
[r236] = processLevel(show_0_236, value_0_236, color_0_236)

show_0_5 = input.bool(false, '', inline='Level3', group=group_fib_levels)
value_0_5 = input.float(0.5, '', inline='Level3', group=group_fib_levels)
color_0_5 = input.color(#4caf50, '', inline='Level3', group=group_fib_levels)
[r5] = processLevel(show_0_5, value_0_5, color_0_5)

show_0_618 = input.bool(false, '', inline='Level4', group=group_fib_levels)
value_0_618 = input.float(0.618, '', inline='Level4', group=group_fib_levels)
color_0_618 = input.color(#009688, '', inline='Level4', group=group_fib_levels)
[r618] = processLevel(show_0_618, value_0_618, color_0_618)

show_0_786 = input.bool(false, '', inline='Level5', group=group_fib_levels)
value_0_786 = input.float(0.786, '', inline='Level5', group=group_fib_levels)
color_0_786 = input.color(#64b5f6, '', inline='Level5', group=group_fib_levels)
[r786] = processLevel(show_0_786, value_0_786, color_0_786)

seprator_ = input.bool(true, '=====================================================',group=group_fib_levels)

////////////////////////////////////////////////////
//Pivot calcuation part
pivot_w_tf=input.timeframe("W","Select Pivot two timeframe",group="Pivot 'W' settings")
[sec_open_w, sec_high_w, sec_low_w, sec_close_w] = request.security(syminfo.tickerid, pivot_w_tf, [open, high, low, close], lookahead=barmerge.lookahead_on)
sec_open_gaps_on_w = request.security(syminfo.tickerid, pivot_w_tf, open, gaps=barmerge.gaps_on, lookahead=barmerge.lookahead_on)


DEF_COLOR_w=color.red

p_show_w = input.bool(false, 'P‏  ‏  ‏  ‏  ‏  ‏  ‏  ‏', inline='P',group="Pivot 'W' settings")
p_color_w = DEF_COLOR_w


s1r1_show_w = input.bool(false, 'S1/R1', inline='S1/R1',group="Pivot 'W' settings")
s1r1_color_w = DEF_COLOR_w


s2r2_show_w = input.bool(false, 'S2/R2', inline='S2/R2',group="Pivot 'W' settings")
s2r2_color_w = DEF_COLOR_w


s3r3_show_w = input.bool(false, 'S3/R3', inline='S3/R3',group="Pivot 'W' settings")
s3r3_color_w = DEF_COLOR_w

pivotX_Median_w = (sec_high_w + sec_low_w + sec_close_w) / 3
pivot_range_w = sec_high_w - sec_low_w

p_w=ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w),1)
r1_w= ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w * 2 - sec_low_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w * 2 - sec_low_w),1)
s1_w= ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w * 2 - sec_high_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w * 2 - sec_high_w),1)
r2_w= ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w + 1 * pivot_range_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w + 1 * pivot_range_w),1)
s2_w= ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w - 1 * pivot_range_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w - 1 * pivot_range_w),1)
r3_w= ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w + 2 * pivot_range_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w + 2 * pivot_range_w),1)
s3_w= ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w - 2 * pivot_range_w),1)<0?0:ta.valuewhen(ta.change(time(pivot_w_tf)),(pivotX_Median_w - 2 * pivot_range_w),1)

plot(p_show_w and not ta.change(p_w)?p_w:na,color=p_color_w, style=plot.style_linebr,linewidth=2,title="P 'W'")
plot(s1r1_show_w and not ta.change(r1_w)?r1_w:na,color=s1r1_color_w, style=plot.style_linebr,linewidth=2,title="S1 'W'")
plot(s2r2_show_w and not ta.change(r2_w)?r2_w:na,color=s2r2_color_w, style=plot.style_linebr,linewidth=2,title="S2 'W'")
plot(s3r3_show_w and not ta.change(r3_w)?r3_w:na,color=s3r3_color_w, style=plot.style_linebr,linewidth=2,title="S3 'W'")

plot(s1r1_show_w and not ta.change(s1_w)?s1_w:na,color=s1r1_color_w, style=plot.style_linebr,linewidth=2,title="R1 'W'")
plot(s2r2_show_w and not ta.change(s2_w)?s2_w:na,color=s2r2_color_w, style=plot.style_linebr,linewidth=2,title="R2 'W'")
plot(s3r3_show_w and not ta.change(s3_w)?s3_w:na,color=s3r3_color_w, style=plot.style_linebr,linewidth=2,title="R3 'W'")

seprator2 = input.bool(true, '=====================================================',group="Pivot 'W' settings")

// ////////////////////////////////////////////////////////////////////////////////////////
//EMA calculation
disable_emas=input.bool(false,"Plot EMA",group="EMA setting")


color_200 = #4caf50
color_50 = #ff0000
color_21 = #2962ff
mtfM = input.timeframe(title='EMA', defval='',group="EMA setting")

ma_length200M = input(200, title='EMA Period ',group="EMA setting")
ma200M = request.security(syminfo.tickerid, mtfM, ta.ema(close, ma_length200M))
p_200M = plot(disable_emas?ma200M:na, color=color_200, linewidth=1, offset=0, style=plot.style_linebr,title="EMA 200")

ma_length100M = input(100, title='EMA Period ',group="EMA setting")
ma100M = request.security(syminfo.tickerid, mtfM, ta.ema(close, ma_length100M))
p_100M = plot(disable_emas?ma100M:na, color=color_50, linewidth=1, offset=0, style=plot.style_linebr,title="EMA 100")

ma_length50M = input(50, title='EMA Period ',group="EMA setting")
ma50M = request.security(syminfo.tickerid, mtfM, ta.ema(close, ma_length50M))
p_50M = plot(disable_emas?ma50M:na, color=color_50, linewidth=1, offset=0, style=plot.style_linebr,title="EMA 50")

ma_length20M = input(20, title='EMA Period ',group="EMA setting")
ma20M = request.security(syminfo.tickerid, mtfM, ta.ema(close, ma_length20M))
p_20M = plot(disable_emas?ma20M:na, color=color_50, linewidth=1, offset=0, style=plot.style_linebr,title="EMA 20")
seprator3 = input.bool(true, '=====================================================',group="EMA setting")


//////////////////////////////////////////////////////////////////
//assigning values to each level

//recent positive divergence levels
level_01 = ta.valuewhen(pos_reg_div_detected, close, 0)
level_02 = ta.valuewhen(pos_reg_div_detected, close, 1)
level_03 = ta.valuewhen(pos_reg_div_detected, close, 2)
level_21 =ta.valuewhen(pos_reg_div_detected, close, 3)

//recent negative divergence levels 
level_04 = ta.valuewhen(neg_reg_div_detected, close, 0)
level_05 = ta.valuewhen(neg_reg_div_detected, close, 1)
level_06 = ta.valuewhen(neg_reg_div_detected, close, 2)
level_25 =ta.valuewhen(neg_reg_div_detected, close, 3)


//Fibonacci levels 
level_07 =r0
level_08 =r236
level_09 =r5
level_10 =r618
level_11 =r786


//Interative S/R levels input from the user
level_12 =array.get(srarray,0)
level_13 =array.get(srarray,1)
level_14 =array.get(srarray,2)
level_15 =array.get(srarray,3)
level_16 =array.get(srarray,4)


//Pivot levels 
level_17 =p_w

level_18 =r1_w
level_19 =r2_w
level_20 =r3_w

level_22 =s1_w
level_23 =s2_w
level_24 =s3_w

//EMA levels
level_26 =ma200M
level_27 =ma50M
level_28 =ma20M
level_29 =ma100M

//ATH, ATL, Weekly High, Weekly Low, two days ago high, two days ago low, previous day high , previous day low
level_30 =a_
level_31 =r_

level_32 =h
level_33 =l

level_34 =r_y
level_35 =r_y_l

level_36 =r_y_l_2
level_37 =r_y_2
level_38 =100000000


//function to call names  and the points for each confluence
score_nomen(value)=>
    score=0
    abb=""

    if value==level_01
        score:=1
        abb:=" DP1"
    else if value==level_02
        score:=1
        abb:=" DP2"
    else if value==level_03
        score:=1
        abb:=" DP3"
    else if value==level_04
        score:=1
        abb:=" DN1"
    else if value==level_05
        score:=1
        abb:=" DN2"
    else if value==level_06
        score:=1
        abb:=" DN3"
        
        
        
    else if value==level_07
        score:=1
        abb:=" Fib0"
    else if value==level_08
        score:=1
        abb:=" Fib236"
    else if value==level_09
        score:=1
        abb:=" Fib5"
    else if value==level_10
        score:=1
        abb:=" Fib618"
    else if value==level_11
        score:=1
        abb:=" Fib786"
        
        
        
    else if value==level_12
        score:=1
        abb:=" SR1"
    else if value==level_13
        score:=1
        abb:=" SR2"
    else if value==level_14
        score:=1
        abb:=" SR3"
    else if value==level_15
        score:=1
        abb:=" SR4"
    else if value==level_16
        score:=1
        abb:=" SR5"
        
        
    else if value==level_17
        score:=1
        abb:=" P"
    else if value==level_18
        score:=1
        abb:=" PR1"
    else if value==level_19
        score:=1
        abb:=" PR2"
    else if value==level_20
        score:=1
        abb:=" PR3"
        
    else if value==level_21
        score:=1
        abb:=" DP4"
    else if value==level_22
        score:=1
        abb:=" PS1"
    else if value==level_23
        score:=1
        abb:=" PS2"
    else if value==level_24
        score:=1
        abb:=" PS3"
    else if value==level_25
        score:=1
        abb:=" DN4"
        
        
    else if value==level_26
        score:=1
        abb:=" E"+str.tostring(ma_length200M)
    else if value==level_27
        score:=1
        abb:=" E"+str.tostring(ma_length50M)
    else if value==level_28
        score:=1
        abb:=" E"+str.tostring(ma_length20M)
    else if value==level_29
        score:=1
        abb:=" E"+str.tostring(ma_length100M)
        
        
    else if value==level_30
        score:=1
        abb:=" ATH"
    else if value==level_31
        score:=1
        abb:=" ATL"
    else if value==level_32
        score:=1
        abb:=" WH"
    else if value==level_33
        score:=1
        abb:=" WL"
    else if value==level_34
        score:=1
        abb:=" PDH"
    else if value==level_35
        score:=1
        abb:=" PDL"
        
        
    else if value==level_36
        score:=1
        abb:=" TDH"
    else if value==level_37
        score:=1
        abb:=" TDL"
    else if value==level_38
        score:=1
        abb:=" "

    if value==0
        score:=0
        abb:=" "
                
        
    [score,abb]

//defining array for inputing the levels
var levels_array = array.new_float()

//Funtion to plot individual levels
line_label_plot(y_,total_score,abbrevation,t_or_f)=>
    if t_or_f and not y_==0
        line.new(bar_index-shift_box, y_ , bar_index + shift_box_r, y_, color=individual_level_color, width=1, extend=extend.none)
        label.new(x=bar_index, y=y_, text="                            "+str.tostring(total_score)+"- " +abbrevation, textcolor=individual_level_color, style=label.style_none,textalign=text.align_left)

//funtion to plot zones
label_box_plot(zone_array_size,first_zone_val,first_zone_high_val,total_score,abbrevation,t_or_f)=>
    zone_color=close>first_zone_high_val and close>first_zone_val?supportcol:resistancecol
    zone_color_bg=close>first_zone_high_val and close>first_zone_val?supportcol_:resistancecol_
    if not zone_array_size==0  and total_score>=nearest_n_values and t_or_f and (not first_zone_high_val==0 or not first_zone_val==0)
        var id = label.new(x=bar_index, y=first_zone_val, text="                            "+str.tostring(total_score)+"- " +abbrevation, textcolor=zone_color, style=label.style_none,textalign=text.align_left)
        var openBox1 = box.new(left=bar_index-shift_box, top=first_zone_high_val , right=bar_index + shift_box_r, bottom=first_zone_val, bgcolor=zone_color_bg,border_color=zone_color ,border_width=1, extend=extend.none)
        label.set_textalign(id, text.align_left)


//funtion to calculate nearest 'k' confluence levels
findKClosestElements(nums, k, target)=>
    levels_array_zones = array.new_float()
    left = 0
    right = array.size(nums) - 1
     
    while right - left >= k
        if math.abs(array.get(nums,left) - target) > math.abs(array.get(nums,right) - target)
            left := left + 1
        else
            right := right - 1

    for i=left to left + k
        if left<array.size(nums) - 1
            array.push(levels_array_zones,array.get(nums,i))

    if array.size(levels_array_zones) > k
        array.pop(levels_array_zones)
    [levels_array_zones,left , left + k]

//funtion to calculate STD. deviation of the 'k' levels in around the input level 
st_deviation(src) =>
    sample = array.new_float(0)
    length= array.size(src)
    sampleMean = array.avg(src)
    
    for i=0 to length-1
        array.push(sample, math.pow(array.get(src,i) - sampleMean, 2))
    sum = array.sum(sample)
    st_deviation_=math.sqrt(sum / (length-1))


//getting each individual confluence name  
ploting_zones_levels(nearest_array_set_a,st_deviation_value_rs1,left,right)=>
    size_a=array.size(nearest_array_set_a)-1
    first_zone_val=array.get(nearest_array_set_a,0)
    first_zone_high_val=array.get(nearest_array_set_a,size_a)
    
    total_score=0
    abbrevation=" "

    for i=left to right
        [score,abbre]=score_nomen(array.get(levels_array, i))
        total_score:=score+total_score
        abbrevation:=abbre+abbrevation            

    if st_deviation_value_rs1<st_deviation_input_val
        label_box_plot(1,first_zone_val,first_zone_high_val,total_score,abbrevation,t_or_f_zone)

    for i=0 to array.size(levels_array)-1 
        if  array.get(levels_array,i)!=array.max(levels_array) and array.get(levels_array,i)!=0 
            [score_non,abbre_non]=score_nomen(array.get(levels_array, i))
            line_label_plot(array.get(levels_array, i),score_non,abbre_non,display_line)


if barstate.islastconfirmedhistory
    //pushing all confluence level in the array 
    array.push(levels_array, level_01)
    array.push(levels_array, level_02)
    array.push(levels_array, level_03)

    array.push(levels_array, level_04)
    array.push(levels_array, level_05)
    array.push(levels_array, level_06)

    array.push(levels_array, level_07)
    array.push(levels_array, level_08)
    array.push(levels_array, level_09)

    array.push(levels_array, level_10)
    array.push(levels_array, level_11)
    array.push(levels_array, level_12)

    array.push(levels_array, level_13)
    array.push(levels_array, level_14)
    array.push(levels_array, level_15)


    array.push(levels_array,level_16)
    array.push(levels_array,level_17)
    array.push(levels_array,level_18)
    array.push(levels_array,level_19)
    array.push(levels_array,level_20)
    array.push(levels_array,level_21)
    array.push(levels_array,level_22)
    array.push(levels_array,level_23)
    array.push(levels_array,level_24)

    array.push(levels_array,level_25)
    array.push(levels_array,level_26) 
    array.push(levels_array,level_27) 
    array.push(levels_array,level_28) 
    array.push(levels_array,level_29) 
    array.push(levels_array,level_30) 
    array.push(levels_array,level_31) 
    array.push(levels_array,level_32) 
    array.push(levels_array,level_33) 
    
    array.push(levels_array,level_34) 
    array.push(levels_array,level_35) 
    array.push(levels_array,level_36) 
    array.push(levels_array,level_37) 
    array.push(levels_array,level_38) 


    if array.size(levels_array) > 38
        array.pop(levels_array)

    array.sort(levels_array, order.ascending)
    
    //calling function to get nearest conflunece levels
    [nearest_array_set_a,left,right]=findKClosestElements(levels_array, nearest_n_values, level_12)
    st_deviation_value_rs1=st_deviation(nearest_array_set_a)

    [nearest_array_set_b,left_b,right_b]=findKClosestElements(levels_array, nearest_n_values, level_13)
    st_deviation_value_rs2=st_deviation(nearest_array_set_b)

    [nearest_array_set_c,left_c,right_c]=findKClosestElements(levels_array, nearest_n_values, level_14)
    st_deviation_value_rs3=st_deviation(nearest_array_set_c)

    [nearest_array_set_d,left_d,right_d]=findKClosestElements(levels_array, nearest_n_values, level_15)
    st_deviation_value_rs4=st_deviation(nearest_array_set_d)

    [nearest_array_set_e,left_e,right_e]=findKClosestElements(levels_array, nearest_n_values, level_16)
    st_deviation_value_rs5=st_deviation(nearest_array_set_e)

    
    //calling function to plot nearest conflunece name and points
    ploting_zones_levels(nearest_array_set_a,st_deviation_value_rs1,left,right)
    ploting_zones_levels(nearest_array_set_b,st_deviation_value_rs2,left_b,right_b)
    ploting_zones_levels(nearest_array_set_c,st_deviation_value_rs3,left_c,right_c)
    ploting_zones_levels(nearest_array_set_d,st_deviation_value_rs4,left_d,right_d)
    ploting_zones_levels(nearest_array_set_e,st_deviation_value_rs5,left_e,right_e)
    
    //to get maximum and minimum value of the Std deviation 
    max_st_deviation=math.max(st_deviation_value_rs1,st_deviation_value_rs2,st_deviation_value_rs3,st_deviation_value_rs4,st_deviation_value_rs5)
    min_st_deviation=math.min(st_deviation_value_rs1,st_deviation_value_rs2,st_deviation_value_rs3,st_deviation_value_rs4,st_deviation_value_rs5)

    var t = table.new(
         position=position.top_right, columns=5, rows=21, bgcolor=color.silver, 
         frame_color=color.gray, frame_width=2, border_color=color.black, border_width=1)

    text_size = input.string("SMALL", "Table Size", options=["AUTO", "TINY","SMALL", "NORMAL", "LARGE", "HUGE"],group="Display setting")
    //table_size = input.int(6, "Table Width:")
    
    text_ =text_size == "TINY"?size.tiny:
             text_size == "SMALL"?size.small:
             text_size == "NORMAL"?size.normal:
             text_size == "LARGE"?size.large:
             text_size == "HUGE"? size.huge:size.auto

    table.cell(t, 0, 0, "Title", bgcolor = color.blue,text_size=text_)
    table.cell(t, 0, 1, "Max Std. Deviation",text_size=text_)
    table.cell(t, 0, 2, "Min Std. Deviation",text_size=text_)
    table.cell(t, 0, 3, "Input value Std. Deviation",text_size=text_)
    
    table.cell(t, 1, 0, "Value", bgcolor = color.blue,text_size=text_)
    table.cell(t, 1, 1, str.tostring(math.round(max_st_deviation,2)), width = 15, bgcolor = color.green,text_size=text_)
    table.cell(t, 1, 2, str.tostring(math.round(min_st_deviation,2)), width = 15, bgcolor = color.green,text_size=text_)
    table.cell(t, 1, 3, str.tostring(math.round(st_deviation_input_val,2)), width = 15, bgcolor = color.green,text_size=text_)
