//@version=5 indicator('Divergence for Many Indicators v4', overlay=true, max_bars_back=1000, max_lines_count=400, max_labels_count=400) min_num = 2 prd = input.int(defval=5, title='Pivot Period', minval=1, maxval=50, group="Divergence for Many Indicators v4") source = input.string(defval='Close', title='Source for Pivot Points', options=['Close', 'High/Low'], group="Divergence for Many Indicators v4") searchdiv = input.string(defval='Regular', title='Divergence Type', options=['Regular', 'Hidden', 'Regular/Hidden'], group="Divergence for Many Indicators v4") showindis = 'Full' // input.string(defval='Full', title='Show Indicator Names', options=['Full', 'First Letter', 'Don\'t Show'], group="Divergence for Many Indicators v4") showlimit = 2 //input.int(2, title='Minimum Number of Divergence', minval=1, maxval=11, group="Divergence for Many Indicators v4") maxpp = input.int(defval=10, title='Maximum Pivot Points to Check', minval=1, maxval=20, group="Divergence for Many Indicators v4") maxbars = input.int(defval=100, title='Maximum Bars to Check', minval=30, maxval=200, group="Divergence for Many Indicators v4") shownum = false //input(defval=true, title='Show Divergence Number', group="Divergence for Many Indicators v4") showlast = false //input(defval=false, title='Show Only Last Divergence', group="Divergence for Many Indicators v4") dontconfirm = false //input(defval=false, title='Don\'t Wait for Confirmation', group="Divergence for Many Indicators v4") showlines = false //input(defval=true, title='Show Divergence Lines', group="Divergence for Many Indicators v4") showpivot = false //input(defval=false, title='Show Pivot Points', group="Divergence for Many Indicators v4") calcmacd = true //input(defval=true, title='MACD', group="Divergence for Many Indicators v4") calcmacda = false //input(defval=true, title='MACD Histogram', group="Divergence for Many Indicators v4") calcrsi = true //input(defval=true, title='RSI', group="Divergence for Many Indicators v4") calcstoc = false //input(defval=true, title='Stochastic', group="Divergence for Many Indicators v4") calccci = false //input(defval=true, title='CCI', group="Divergence for Many Indicators v4") calcmom = false //input(defval=true, title='Momentum', group="Divergence for Many Indicators v4") calcobv = false //input(defval=true, title='OBV', group="Divergence for Many Indicators v4") calcvwmacd = false //input(true, title='VWmacd', group="Divergence for Many Indicators v4") calccmf = false //input(true, title='Chaikin Money Flow', group="Divergence for Many Indicators v4") calcmfi = false //input(true, title='Money Flow Index', group="Divergence for Many Indicators v4") calcext = false //input(false, title='Check External Indicator', group="Divergence for Many Indicators v4") externalindi = close//input(defval=close, title='External Indicator', group="Divergence for Many Indicators v4") pos_reg_div_col = color.yellow //input(defval=color.yellow, title='Positive Regular Divergence', group="Divergence for Many Indicators v4") neg_reg_div_col = color.navy //input(defval=color.navy, title='Negative Regular Divergence', group="Divergence for Many Indicators v4") pos_hid_div_col = color.lime //input(defval=color.lime, title='Positive Hidden Divergence', group="Divergence for Many Indicators v4") neg_hid_div_col = color.red //input(defval=color.red, title='Negative Hidden Divergence', group="Divergence for Many Indicators v4") pos_div_text_col = color.black //input(defval=color.black, title='Positive Divergence Text Color', group="Divergence for Many Indicators v4") neg_div_text_col = color.white //input(defval=color.white, title='Negative Divergence Text Color', group="Divergence for Many Indicators v4") reg_div_l_style_ = 'Solid' //input.string(defval='Solid', title='Regular Divergence Line Style', options=['Solid', 'Dashed', 'Dotted'], group="Divergence for Many Indicators v4") hid_div_l_style_ = 'Dashed' //input.string(defval='Dashed', title='Hdden Divergence Line Style', options=['Solid', 'Dashed', 'Dotted'], group="Divergence for Many Indicators v4") reg_div_l_width = 2 //input.int(defval=2, title='Regular Divergence Line Width', minval=1, maxval=5, group="Divergence for Many Indicators v4") hid_div_l_width = 1 //input.int(defval=1, title='Hidden Divergence Line Width', minval=1, maxval=5, group="Divergence for Many Indicators v4") showmas = input.bool(defval=false, title='Show MAs 50 & 200', inline='ma12', group="Divergence for Many Indicators v4") cma1col = input.color(defval=color.lime, title='', inline='ma12', group="Divergence for Many Indicators v4") cma2col = input.color(defval=color.red, title='', inline='ma12', group="Divergence for Many Indicators v4") 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)) // alertcondition(pos_reg_div_detected, title='Positive Regular Divergence Detected', message='Positive Regular Divergence Detected') // alertcondition(neg_reg_div_detected, title='Negative Regular Divergence Detected', message='Negative Regular Divergence Detected') // alertcondition(pos_hid_div_detected, title='Positive Hidden Divergence Detected', message='Positive Hidden Divergence Detected') // alertcondition(neg_hid_div_detected, title='Negative Hidden Divergence Detected', message='Negative Hidden Divergence Detected') // alertcondition(pos_reg_div_detected or pos_hid_div_detected, title='Positive Divergence Detected', message='Positive Divergence Detected') // alertcondition(neg_reg_div_detected or neg_hid_div_detected, title='Negative Divergence Detected', message='Negative Divergence Detected') // indicator(title="Moving Average Exponential", shorttitle="EMA", overlay=true, timeframe="", timeframe_gaps=true) len = input.int(9, minval=1, title="Length", group="EMA") src = input(close, title="Source", group="EMA") offset = input.int(title="Offset", defval=0, minval=-500, maxval=500, group="EMA") out = ta.ema(src, len) plot(out, title="EMA", color=color.blue, offset=offset) ma(source, length, type) => switch type "SMA" => ta.sma(source, length) "EMA" => ta.ema(source, length) "SMMA (RMA)" => ta.rma(source, length) "WMA" => ta.wma(source, length) "VWMA" => ta.vwma(source, length) typeMA = input.string(title = "Method", defval = "SMA", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="Smoothing") smoothingLength = input.int(title = "Length", defval = 5, minval = 1, maxval = 100, group="Smoothing") smoothingLine = ma(out, smoothingLength, typeMA) plot(smoothingLine, title="Smoothing Line", color=#f37f20, offset=offset, display=display.none) ema_buy = close>=out ema_sell = close<=out long = dnumdiv_bottom >= min_num and ema_buy short= dnumdiv_top >= min_num and ema_sell plotshape(long , title="Buy", text="Buy", location=location.belowbar, style=shape.labelup, size=size.tiny, color=color.green, textcolor=color.white) plotshape(short , title="Sell", text="Sell", location=location.abovebar, style=shape.labeldown , size=size.tiny, color=color.red, textcolor=color.white) alertcondition(long , "Buy") alertcondition(short , "Sell") alertcondition(long or short, "Buy or Sell") // Buy signal buySignal = ta.crossover(close, smoothingLine) plotshape(buySignal, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.tiny, title="Buy") // Sell signal sellSignal = ta.crossunder(close, smoothingLine) plotshape(sellSignal, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.tiny, title="Sell")