Strategy · Pine Script v5 · On the chart

Divergence for Many [Dimkud]

by zhuzp98

This strategy detects divergences in MACD, MACD histogram, and RSI indicators to generate buy and sell signals on the price chart.

View on GitHub

Repaints

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code1,354
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago17 Jan 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

1,354 lines of Pine Script v5 from PineScript/Stg_ex_DivForMany.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

Stg_ex_DivForMany.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Strategy based on "Divergence for Many Indicators v4 ST" by CannyTolany01
// which is based on "Divergence for Many Indicator" indicator by LonesomeTheBlue
//@version=5
strategy('Divergence for Many [Dimkud - v5]', overlay=true, calc_on_order_fills=true,  commission_type=strategy.commission.percent, commission_value=0.04, default_qty_type=strategy.cash, default_qty_value=200, initial_capital=1000)

// DIMAK  Static SL/TP - Begin
GRUPO_statSLTP = 'Static SL/TP'
USEdisplTPSL =  input(defval=false, title='Display Visualisation for TP/SL ?', group = GRUPO_statSLTP)
enable_long_strategy = input.bool(false, title='Use Long ?', group=GRUPO_statSLTP, inline='11')
enable_short_strategy = input.bool(true, title='Use Short ?', group=GRUPO_statSLTP, inline='11')

SLsameTP = input.bool(false, 'SL = TP ?', group=GRUPO_statSLTP)
USE_SignSL = input.bool(false, 'Use Opposite Signal SL ?', group=GRUPO_statSLTP)
USEorderOnSL =  input(defval=false, title='New Opposite-Order after SL ?', group = GRUPO_statSLTP, tooltip = 'After SL - create new order with with opposite direction')
longProfitPerc = input.float(defval=0.9, title='Take Profit (%)', group=GRUPO_statSLTP, minval=0.0, step=0.1) / 100
longSLPerc = input.float(defval=0.9, title='Stop Loss (%)', group=GRUPO_statSLTP, minval=0.0, step=0.1) / 100



longSLPerc := SLsameTP ? longProfitPerc : longSLPerc

shortProfitPerc = longProfitPerc
shortSLPerc = longSLPerc

longExitPrice = strategy.position_avg_price * (1 + longProfitPerc)
shortExitPrice = strategy.position_avg_price * (1 - shortProfitPerc)

longSLExitPrice = strategy.position_avg_price * (1 - longSLPerc)
shortSLExitPrice = strategy.position_avg_price * (1 + shortSLPerc)

// use such: limit=shortExitPrice, stop=shortSLExitPrice

// DIMAK  Static SL/TP - END
// ===================================================================================================


// DIMAK - TimeFrame request.security - Repaint-Non Repaint
f_security(_sym, _res, _src, _rep) =>
    request.security(_sym, _res, _src[not _rep and barstate.isrealtime ? 1 : 0])[_rep or barstate.isrealtime ? 0 : 1]
// DIMAK - TimeFrame request.security - Repaint-Non Repaint





// Time filter =================================
grTIMEset = "Testing Period"
testPeriod() =>
    // Testing Start dates
    testStartYear = input.int(2022, 'Start Year', inline='date1', group=grTIMEset)
    testStartMonth = input.int(5, '', inline='date1', group=grTIMEset)
    testStartDay = input.int(1, '', inline='date1', group=grTIMEset)
    testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)
    //Stop date if you want to use a specific range of dates
    testStopYear = input.int(2030, 'Stop Year', inline='date2', group=grTIMEset)
    testStopMonth = input.int(12, '', inline='date2', group=grTIMEset)
    testStopDay = input.int(30, '', inline='date2', group=grTIMEset)
    testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)

    time >= testPeriodStart and time < testPeriodStop ? true : false

    // pass some date
    //testPeriodStop2 =  timestamp(2022,6,14,0,0)
    //testPeriodStop3 =  timestamp(2022,6,16,0,0)
    //(time >= testPeriodStart) and (time < testPeriodStop) and ((time < testPeriodStop2) or (time > testPeriodStop3)) ? true : false
// Time filter =================================



grMAINset = "Main Divergence Settings"

prd = input.int(defval=9, title='Pivot Period(9)', minval=1, maxval=50, group = grMAINset)
source = input.string(defval='Close', title='Source for Pivot Points', options=['Close', 'High/Low'], group = grMAINset)
//searchdiv = input.string(defval='Regular', title='Divergence Type', options=['Regular', 'Hidden', 'Regular/Hidden'], group = grMAINset)
// works only Regular
searchdiv = 'Regular'
showindis = input.string(defval='Don\'t Show', title='Show Indicator Names', options=['Full', 'First Letter', 'Don\'t Show'], group = grMAINset)
//showlimit = input.int(1, title='Minimum Number of Divergence', minval=1, maxval=11)
// not good results and not work now
showlimit = 1
maxpp = input.int(defval=10, title='Maximum Pivot Points to Check', minval=10, maxval=20, group = grMAINset)
maxbars = input.int(defval=100, title='Maximum Bars to Check', minval=100, maxval=200, group = grMAINset)
shownum = input(defval=true, title='Show Divergence Number', group = grMAINset)
showlast = input(defval=false, title='Show Only Last Divergence', group = grMAINset)
dontconfirm = input(defval=false, title='Don\'t Wait for Confirmation', group = grMAINset)
showlines = input(defval=false, title='Show Divergence Lines', group = grMAINset)
showpivot = input(defval=false, title='Show Pivot Points', group = grMAINset)


// declaration
macd = 0.0
deltamacd = 0.0
rsi = 0.0
stk = 0.0
cci = 0.0
moment = 0.0
Obv = 0.0
vwmacd = 0.0
cmf = 0.0
Mfi = 0.0
aStDev = 0.0
wvf = 0.0
StochRSIk = 0.0
oscSMIO = 0.0
dmVWMACD_LB = 0.0
BBPower = 0.0
SmootherBOP = 0.0
rviMA = 0.0
// declaration

calcmacd = input(defval=true, title='MACD')

dimmacdFast = input.int(defval=12, title='Fast(12):', minval=1, maxval=70, inline='223')
dimmacdSlow = input.int(defval=26, title='Slow(26):', minval=1, maxval=70, inline='223')
dimmacdSignal = input.int(defval=9, title='Sign(9):', minval=1, maxval=70, inline='223')
calcmacda = input(defval=true, title='MACD Histogram')
if calcmacd or calcmacda
    //[macd, signal, deltamacd] = macd(close, 12, 26, 9) // MACD
    [macd2, signal, deltamacd2] = ta.macd(close, dimmacdFast, dimmacdSlow, dimmacdSignal)  // MACD
    macd := macd2
    deltamacd := deltamacd2
    deltamacd

calcrsi = input(defval=true, title='RSI')
dimRSI = input.int(defval=14, title='RSI period (14):', minval=1, maxval=70)
if calcrsi
    //rsi = rsi(close, 14) // RSI
    rsi := ta.rsi(close, dimRSI)  // RSI
    rsi



calcstoc = input(defval=true, title='Stochastic')
dimSTOCHlength = input.int(defval=14, title='STOCH Length(14):', minval=1, maxval=70)
if calcstoc
    //stk = sma(stoch(close, high, low, 14), 3) // Stoch
    stk := ta.sma(ta.stoch(close, high, low, dimSTOCHlength), 3)  // Stoch
    stk


calccci = input(defval=true, title='CCI')
dimCCIL = input.int(defval=10, title='CCI Length(10)', minval=1, maxval=70, inline='')
if calccci
    //cci = cci(close, 10) // CCI
    cci := ta.cci(close, dimCCIL)  // CCI
    cci


calcmom = input(defval=true, title='Momentum')
dimmomentL = input.int(defval=10, title='Momentum Length(10)', minval=1, maxval=70, inline='')
if calcmom
    //moment = mom(close, 10) // Momentum
    moment := ta.mom(close, dimmomentL)  // Momentum
    moment


calcobv = input(defval=true, title='OBV')
if calcobv
    Obv := ta.obv  // OBV
    Obv

calcvwmacd = input(true, title='VWmacd')
dimmaFast = input.int(defval=12, title='Volume Weighted Macd. Fast(12)', minval=1, maxval=70, inline='112')
dimmaSlow = input.int(defval=26, title='Slow(26)', minval=1, maxval=70, inline='112')
if calcvwmacd
    //maFast = vwma(close, 12), maSlow = vwma(close, 26), vwmacd = maFast - maSlow // volume weighted macd
    maFast = ta.vwma(close, dimmaFast)
    maSlow = ta.vwma(close, dimmaSlow)
    vwmacd := maFast - maSlow  // volume weighted macd
    vwmacd



calccmf = input(true, title='Chaikin Money Flow')
dimCMFperiod = input.int(defval=21, title='CMF period(21)', minval=1, maxval=70, inline='')
if calccmf
    //Cmfm = ((close-low) - (high-close)) / (high - low), Cmfv = Cmfm * volume, cmf = sma(Cmfv, 21) / sma(volume,21) // Chaikin money flow
    Cmfm = (close - low - (high - close)) / (high - low)
    Cmfv = Cmfm * volume
    cmf := ta.sma(Cmfv, dimCMFperiod) / ta.sma(volume, dimCMFperiod)  // Chaikin money flow
    cmf


calcmfi = input(true, title='Money Flow Index')
dimMfilength = input.int(defval=14, title='Mfi length(14)', minval=1, maxval=70, inline='')
if calcmfi
    //Mfi = mfi(close, 14) // Moneyt Flow Index
    Mfi := ta.mfi(close, dimMfilength)  // Moneyt Flow Index
    Mfi


//==================================================================================
calcWVIX = input(true, title='Williams_Vix_Fix')
pd = input(21, title='Williams_Vix_Fix Period(21)')
if calcWVIX
    wvf := (ta.highest(close, pd) - low) / ta.highest(close, pd) * -100
    wvf

//==================================================================================
calcStochRSI = input.bool(true, title='Use Stochastic RSI ?', group='Stochastic RSI')
smoothK = input.int(3, 'Stochastic K(3)', minval=1, group='Stochastic RSI')
lengthSTRSI = input.int(14, 'RSI Length(14)', minval=1, group='Stochastic RSI')
lengthStoch = input.int(14, 'Stochastic Length(14)', minval=1, group='Stochastic RSI')
if calcStochRSI
    rsi1 = ta.rsi(close, lengthSTRSI)
    StochRSIk := ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
    StochRSIk

//==================================================================================

calcSMIO = input.bool(true, title='Use SMIO ?', group='SMI Ergodic Oscillator')
longlenSMIO = input.int(20, minval=1, title='Long Length(20)', group='SMI Ergodic Oscillator')
shortlenSMIO = input.int(5, minval=1, title='Short Length(5)', group='SMI Ergodic Oscillator')
siglenSMIO = input.int(5, minval=1, title='Signal Line Length(5)', group='SMI Ergodic Oscillator')
if calcSMIO
    ergSMIO = ta.tsi(close, shortlenSMIO, longlenSMIO)
    sigSMIO = ta.ema(ergSMIO, siglenSMIO)
    oscSMIO := ergSMIO - sigSMIO
    oscSMIO


//==================================================================================
calcVWMACD_LB = input.bool(true, title='Use VWMACD_LB ?', group='Volume Weighted MACD [LazyBear]')

slowVWMACD_LB = input.int(12, 'Short period(12)', minval=1)
fastVWMACD_LB = input.int(26, 'Long period(26)', minval=1)
signalVWMACD_LB = input.int(9, 'Smoothing period(9)', minval=1)

if calcVWMACD_LB
    maFastVWMACD_LB = ta.ema(volume * close, fastVWMACD_LB) / ta.ema(volume, fastVWMACD_LB)
    maSlowVWMACD_LB = ta.ema(volume * close, slowVWMACD_LB) / ta.ema(volume, slowVWMACD_LB)
    dVWMACD_LB = maSlowVWMACD_LB - maFastVWMACD_LB
    maSignalVWMACD_LB = ta.ema(dVWMACD_LB, signalVWMACD_LB)
    dmVWMACD_LB := dVWMACD_LB - maSignalVWMACD_LB
    dmVWMACD_LB


//==================================================================================
calcBBP = input.bool(true, title='Use BBP', group='Bull Bear Power')
lengthInputBBP = input.int(13, title='BBP Length(13)', minval=1, group='Bull Bear Power')
if calcBBP
    bullPowerBBP = high - ta.ema(close, lengthInputBBP)
    bearPowerBBP = low - ta.ema(close, lengthInputBBP)
    BBPower := bullPowerBBP + bearPowerBBP
    BBPower

//==================================================================================


calcBOP = input.bool(true, title='Use BOP', group='Balance of Power')
EMA = input.int(20, 'BOP Smooth Length(20)', minval=1, group='Balance of Power')
TEMA = input.int(20, 'TRIPLE Smooth Length(20)', minval=1, group='Balance of Power')

if calcBOP
    THL = high != low ? high - low : 0.01
    BullOpen = (high - open) / THL
    BearOpen = (open - low) / THL
    BullClose = (close - low) / THL
    BearClose = (high - close) / THL
    BullOC = close > open ? (close - open) / THL : 0
    BearOC = open > close ? (open - close) / THL : 0
    BullReward = (BullOpen + BullClose + BullOC) / 3
    BearReward = (BearOpen + BearClose + BearOC) / 3
    BOP = BullReward - BearReward

    SmoothBOP = ta.ema(BOP, EMA)

    xEMA1 = ta.ema(SmoothBOP, TEMA)
    xEMA2 = ta.ema(xEMA1, TEMA)
    xEMA3 = ta.ema(xEMA2, TEMA)
    nRes = 3 * xEMA1 - 3 * xEMA2 + xEMA3
    SmootherBOP := nRes
    SmootherBOP


//==================================================================================

calcRVI = input.bool(true, title='Use RVI', group='Relative Volatility Index')

lengthRVI = input.int(10, title='RVI length(10)', minval=1, group='Relative Volatility Index')
maTypeInput = input.string('WMA', title='MA Type', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA'], group='Relative Volatility Index')
maLengthInput = input.int(14, title='MA Length(14)', group='Relative Volatility Index')

if calcRVI
    stddevRVI = ta.stdev(close, lengthRVI)
    upperRVI = ta.ema(ta.change(close) <= 0 ? 0 : stddevRVI, 14)
    lowerRVI = ta.ema(ta.change(close) > 0 ? 0 : stddevRVI, 14)
    rviRVI = upperRVI / (upperRVI + lowerRVI) * 100

    rviMA := maTypeInput == 'SMA' ? ta.sma(rviRVI, maLengthInput) : maTypeInput == 'EMA' ? ta.ema(rviRVI, maLengthInput) : maTypeInput == 'SMMA (RMA)' ? ta.rma(rviRVI, maLengthInput) : maTypeInput == 'WMA' ? ta.wma(rviRVI, maLengthInput) : maTypeInput == 'VWMA' ? ta.vwma(rviRVI, maLengthInput) : ta.wma(rviRVI, maLengthInput)
    rviMA




//==================================================================================
// Logistic Dominance
calcLD = input.bool(true, title='Logistic Dominance', group='Logistic Settings')
source2 = close
length = input.int(13, 'Map Length(13)', minval=1, inline='LOG', group='Logistic Settings')
lenLD = input.int(5, 'Dominance(5)', minval=1, inline='LOG', group='Logistic Settings')

f_logmap(_s, _r, _l) =>
    _r * _s / ta.highest(_l) * (1 - _s / ta.highest(_l))

f_map(_s, _r, _v) =>
    mapeq = f_logmap(_s, _r, length)
    lmap = mapeq
    for i = 0 to 29 by 1
        array.push(_v, lmap)
        lmap := _r * math.abs(mapeq[i]) * (1 - mapeq[i])
        lmap
    lmap

if calcLD
    r = -f_logmap(-source2, ta.change(source2, lenLD) / source2[lenLD], lenLD) - f_logmap(source2, ta.change(source2, lenLD) / source2[lenLD], lenLD)
    var v = array.new_float(0)
    val = f_map(source2, r, v)
    array.remove(v, 0)
    aStDev := math.sign(array.avg(v)) * array.stdev(v)
    array.clear(v)

// Logistic Dominance

//==================================================================================




calcext = input(false, title='Check External Indicator')
externalindi = input(defval=close, title='External Indicator')
pos_reg_div_col = input(defval=color.yellow, title='Positive Regular Divergence')
neg_reg_div_col = input(defval=color.navy, title='Negative Regular Divergence')
pos_hid_div_col = input(defval=color.lime, title='Positive Hidden Divergence')
neg_hid_div_col = input(defval=color.red, title='Negative Hidden Divergence')
pos_div_text_col = input(defval=color.black, title='Positive Divergence Text Color')
neg_div_text_col = input(defval=color.white, title='Negative Divergence Text Color')
reg_div_l_style_ = input.string(defval='Solid', title='Regular Divergence Line Style', options=['Solid', 'Dashed', 'Dotted'])
hid_div_l_style_ = input.string(defval='Dashed', title='Hdden Divergence Line Style', options=['Solid', 'Dashed', 'Dotted'])
reg_div_l_width = input.int(defval=2, title='Regular Divergence Line Width', minval=1, maxval=5)
hid_div_l_width = input.int(defval=1, title='Hidden Divergence Line Width', minval=1, maxval=5)
showmas = input.bool(defval=false, title='Show MAs 50 & 200', inline='ma12')
cma1col = input.color(defval=color.lime, title='', inline='ma12')
cma2col = input.color(defval=color.red, title='', inline='ma12')

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




// keep indicators names and colors in arrays
// !!!!!!!! DIMAK - add num of Indicators +1
var indicators_name = array.new_string(19)
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')
    array.set(indicators_name, 11, showindis == 'Full' ? 'Logist' : 'L')
    array.set(indicators_name, 12, showindis == 'Full' ? 'WVIX' : 'VIX')
    array.set(indicators_name, 13, showindis == 'Full' ? 'StochRSI' : 'SR')
    array.set(indicators_name, 14, showindis == 'Full' ? 'calcSMIO' : 'SM')
    array.set(indicators_name, 15, showindis == 'Full' ? 'VWMACD_LB' : 'VWM')
    array.set(indicators_name, 16, showindis == 'Full' ? 'BBP' : 'BBP')
    array.set(indicators_name, 17, showindis == 'Full' ? 'BOP' : 'BOP')
    array.set(indicators_name, 18, showindis == 'Full' ? 'RVI' : 'RVI')

// !!!!!!!!!!! DIMAK - num of Ind +1    

    //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
// !!!!!!!!!! DIMAK - add num of Indicators *4
var all_divergences = array.new_int(76)  // 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 
if calcmacd
    array_set_divs(calculate_divs(calcmacd, macd), 0)
if calcmacda
    array_set_divs(calculate_divs(calcmacda, deltamacd), 1)
if calcrsi
    array_set_divs(calculate_divs(calcrsi, rsi), 2)
if calcstoc
    array_set_divs(calculate_divs(calcstoc, stk), 3)
if calccci
    array_set_divs(calculate_divs(calccci, cci), 4)
if calcmom
    array_set_divs(calculate_divs(calcmom, moment), 5)
if calcobv
    array_set_divs(calculate_divs(calcobv, Obv), 6)
if calcvwmacd
    array_set_divs(calculate_divs(calcvwmacd, vwmacd), 7)
if calccmf
    array_set_divs(calculate_divs(calccmf, cmf), 8)
if calcmfi
    array_set_divs(calculate_divs(calcmfi, Mfi), 9)
if calcext
    array_set_divs(calculate_divs(calcext, externalindi), 10)
if calcLD
    array_set_divs(calculate_divs(calcLD, aStDev), 11)
if calcWVIX
    array_set_divs(calculate_divs(calcWVIX, wvf), 12)
if calcStochRSI
    array_set_divs(calculate_divs(calcStochRSI, StochRSIk), 13)
if calcSMIO
    array_set_divs(calculate_divs(calcSMIO, oscSMIO), 14)
if calcVWMACD_LB
    array_set_divs(calculate_divs(calcVWMACD_LB, dmVWMACD_LB), 15)
if calcBBP
    array_set_divs(calculate_divs(calcBBP, BBPower), 16)
if calcBOP
    array_set_divs(calculate_divs(calcBOP, SmootherBOP), 17)
if calcRVI
    array_set_divs(calculate_divs(calcRVI, rviMA), 18)



// !!!!!!! DIMAK - add num of Indicators 

// 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)))

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))
            1
        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))
            1
        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


// !!!!!!!!!!!! DIMAK - add num of Indicators 
for x = 0 to 18 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')



// ===================================================================================================
GRUPO_KC = 'Keltner Channel'

use_KC = input.bool(false, 'Use Channel ?', group=GRUPO_KC)
P_indicador = input.string('Keltner Channel', 'Channel to Use:', options=['Keltner Channel', 'Bollinger Bands'], group=GRUPO_KC)
P_cond_entrada = input.string('Wick out of band', 'Enter Conditions', options=['Wick out of band', 'Wick out of the band then close in', 'Out-of-band closure', 'Close out of the band then close in'], group=GRUPO_KC)
KC_length = input.int(title='Keltner Long.', group=GRUPO_KC, defval=14, minval=1, inline='kc')
KC_mult = input.float(title='Keltner Mult.', group=GRUPO_KC, defval=1.5, minval=0.01, step=0.05, inline='kc')

[KC_mid, KC_upper, KC_lower] = ta.kc(close, KC_length, KC_mult)

GRUPO_BB = 'Bollinger Bands Filter'
BB_length = input.int(title='BB Long. ', group=GRUPO_KC, defval=20, minval=1, inline='bb')
BB_dev = input.float(title='BB Deviation (Desv.)', group=GRUPO_KC, defval=2.0, minval=0.01, step=0.1, inline='bb')
[BB_mid, BB_upper, BB_lower] = ta.bb(close, BB_length, BB_dev)


Kanal_upper = KC_upper
Kanal_mid = KC_mid
Kanal_lower = KC_lower

if P_indicador == 'Bollinger Bands'
    Kanal_upper := BB_upper
    Kanal_mid := BB_mid
    Kanal_lower := BB_lower
    //Kanal_lower

//displ= display.none
displ = use_KC ? display.all : display.none
plot(Kanal_upper, 'UP', color.new(color.aqua, 0), display = displ)
plot(Kanal_mid, 'Mid', color.new(color.orange, 0), display = displ)
plot(Kanal_lower, 'DOWN', color.new(color.aqua, 0), display = displ)


longCondition2 = true
shortCondition2 = true

if use_KC
    longCondition2 := false
    shortCondition2 := false

    if P_cond_entrada == 'Wick out of band'
        longCondition2 := low < Kanal_lower
        shortCondition2 := high > Kanal_upper
        shortCondition2

    else if P_cond_entrada == 'Wick out of the band then close in'
        longCondition2 := low[1] < Kanal_lower and close > Kanal_lower
        shortCondition2 := high[1] > Kanal_upper and close < Kanal_upper
        shortCondition2
    else if P_cond_entrada == 'Out-of-band closure'
        longCondition2 := close < Kanal_lower
        shortCondition2 := close > Kanal_upper
        shortCondition2
    else
        // Close out of the band then close in
        longCondition2 := close[1] < Kanal_lower and close > Kanal_lower
        shortCondition2 := close[1] > Kanal_upper and close < Kanal_upper
        shortCondition2
else
    longCondition2 := true
    shortCondition2 := true
    shortCondition2


// ===================================================================================================




// ======================= dimak RSI timeframe   Begin 1111111 ====================
GRUPO_RSI_TF  = "========== RSI FILTER ============"

lengthRSI = input.int(title="RSI TF Long(14):", group=GRUPO_RSI_TF, defval=14, minval=1)
tf_rsi_indicator = input.timeframe("",title="RSI TimeFrame:", group=GRUPO_RSI_TF)

useRSITFoverSold = input.bool(false, 'Use RSI LONG Range', group=GRUPO_RSI_TF)
overSoldRSITF = input.int(title='(LONG) RSI is More', group=GRUPO_RSI_TF, defval=30, step=5, minval=1, inline='22')
overSold2RSITF = input.int(title='& RSI Less', group=GRUPO_RSI_TF, defval=70, minval=1, maxval = 100, step=5, inline='22')

useRSITFFoverBought = input.bool(false, 'Use RSI SHORT Range', group=GRUPO_RSI_TF)
overBoughtRSITF = input.int(title='(SHORT) RSI is Less', group=GRUPO_RSI_TF, defval=70, step=5, minval=1, maxval = 100, inline='33')
overBought2RSITF = input.int(title='& RSI More', group=GRUPO_RSI_TF, defval=30, minval=1, step=5, inline='33')


//rsi_tf1 = request.security(syminfo.tickerid, tf_rsi_indicator, ta.rsi(close, lengthRSI), barmerge.gaps_off)
rsi_tf1 = f_security(syminfo.tickerid, tf_rsi_indicator, ta.rsi(close, lengthRSI), false) // Repaint = false
//=====================================================    

longCondition8  = true
shortCondition8 = true

if useRSITFoverSold or useRSITFFoverBought
    longCondition8  := false
    shortCondition8 := false

    if useRSITFoverSold and (rsi_tf1 >= overSoldRSITF) and (rsi_tf1 <= overSold2RSITF)
        longCondition8  := true
    
    if useRSITFFoverBought and (rsi_tf1 <= overBoughtRSITF)  and (rsi_tf1 >= overBought2RSITF)
        shortCondition8 := true

else 
    longCondition8  := true
    shortCondition8 := true

//dimak RSI timeframe  END
//=====================================================



// ======================= dimak RSI timeframe   Begin 22222222 ====================
GRUPO_RSI_TF2  = "======= RSI FILTER - Multi TimeFrame [2] ======="

lengthRSI2 = input.int(title="RSI TF Long(14):[2]", group=GRUPO_RSI_TF2, defval=14, minval=1)
tf_rsi_indicator2 = input.timeframe("",title="RSI TimeFrame:[2]", group=GRUPO_RSI_TF2)

useRSITFoverSold2 = input.bool(false, 'Use RSI LONG Range[2]', group=GRUPO_RSI_TF2)
overSoldRSITF2 = input.int(title='(LONG) RSI is More[2]', group=GRUPO_RSI_TF2, defval=30, step=5, minval=1, inline='22')
overSold2RSITF2 = input.int(title='& RSI Less[2]', group=GRUPO_RSI_TF2, defval=70, minval=1,  maxval = 100, step=5, inline='22')

useRSITFFoverBought2 = input.bool(false, 'Use RSI SHORT Range[2]', group=GRUPO_RSI_TF2)
overBoughtRSITF2 = input.int(title='(SHORT) RSI is Less[2]', group=GRUPO_RSI_TF2, defval=70, maxval = 100, step=5, minval=1, inline='33')
overBought2RSITF2 = input.int(title='& RSI More[2]', group=GRUPO_RSI_TF2, defval=30, minval=1, step=5, inline='33')


//rsi_tf2 = request.security(syminfo.tickerid, tf_rsi_indicator2, ta.rsi(close, lengthRSI2), barmerge.gaps_off)
rsi_tf2 = f_security(syminfo.tickerid, tf_rsi_indicator2, ta.rsi(close, lengthRSI2), false) // Repaint = false
//=====================================================    

longCondition10  = true
shortCondition10 = true

if useRSITFoverSold2 or useRSITFFoverBought2 and not na(rsi_tf2)
    longCondition10  := false
    shortCondition10 := false

    if useRSITFoverSold2 and (rsi_tf2 >= overSoldRSITF2) and (rsi_tf2 <= overSold2RSITF2)
        longCondition10  := true
    
    if useRSITFFoverBought2 and (rsi_tf2 <= overBoughtRSITF2)  and (rsi_tf2 >= overBought2RSITF2)
        shortCondition10 := true

else 
    longCondition10  := true
    shortCondition10 := true

//dimak RSI timeframe  END
//=====================================================







// ============ dimak "Money Flow Index" Filter Timeframe  [111]  =============
GRUPO_MFI_TF = '=========== MFI FILTER  ==========='
lengthMFI = input.int(title='MFI TF Long:', group=GRUPO_MFI_TF, defval=14, minval=1)
tf_mfi_indicator = input.timeframe('', title='MFI TimeFrame:', group=GRUPO_MFI_TF)

useMFITFoverSold = input.bool(false, 'Use MFI LONG Range', group=GRUPO_MFI_TF)
overSold = input.int(title='(LONG) MFI is More', group=GRUPO_MFI_TF, defval=10, step=5, minval=1, inline='22')
overSold2 = input.int(title='& MFI Less', group=GRUPO_MFI_TF, defval=60, maxval = 100, step=5, minval=1, inline='22')

useMFITFoverBought = input.bool(false, 'Use MFI SHORT Range', group=GRUPO_MFI_TF)
overBought = input.int(title='(SHORT) MFI is Less', group=GRUPO_MFI_TF, defval=95, maxval = 100, step=5, minval=1, inline='33')
overBought2 = input.int(title='& MFI More', group=GRUPO_MFI_TF, defval=50, maxval = 100, step=5, minval=1, inline='33')

mfi_tf1 = f_security(syminfo.tickerid, tf_mfi_indicator, ta.mfi(hlc3, lengthMFI), true) // Repaint = false
//mfi_tf1 = request.security(syminfo.tickerid, tf_mfi_indicator, ta.mfi(hlc3, lengthMFI), barmerge.gaps_off)




// =====================================================    

longCondition4 = true
shortCondition4 = true
    
if useMFITFoverSold or useMFITFoverBought
    longCondition4 := false
    shortCondition4 := false

    if useMFITFoverSold and (mfi_tf1 > overSold) and (mfi_tf1 < overSold2)
        longCondition4 := true
      
    if useMFITFoverBought and (mfi_tf1 < overBought) and (mfi_tf1 > overBought2) 
        shortCondition4 := true
                 
else

    longCondition4 := true
    shortCondition4 := true
   
// dimak MFI timeframe [111] END


// =====================================================    


use_mfi_tf1_rising = input.bool(false, 'Use MFI TF Rising ?', group=GRUPO_MFI_TF)
mfi_tf1_rising_len = input.int(3, title='MFI TF Rising Lengh:', group=GRUPO_MFI_TF, minval=0, maxval=20)

use_mfi_tf1_falling = input.bool(false, 'Use MFI TF Falling ?', group=GRUPO_MFI_TF)
mfi_tf1_falling_len = input.int(3, title='MFI TF Falling Lengh:', group=GRUPO_MFI_TF, minval=0, maxval=20)

mfi_tf1_falling = ta.falling(mfi_tf1, mfi_tf1_falling_len)
mfi_tf1_rising = ta.rising(mfi_tf1, mfi_tf1_rising_len)

//mfi_tf1_falling_tf = request.security(syminfo.tickerid, tf_mfi_indicator, mfi_tf1_falling, barmerge.gaps_off)
//mfi_tf1_rising_tf = request.security(syminfo.tickerid, tf_mfi_indicator, mfi_tf1_rising, barmerge.gaps_off)
mfi_tf1_falling_tf = f_security(syminfo.tickerid, tf_mfi_indicator, mfi_tf1_falling, true) // Repaint = false
mfi_tf1_rising_tf = f_security(syminfo.tickerid, tf_mfi_indicator, mfi_tf1_rising, true) // Repaint = false
    

longCondition12 = true
shortCondition12 = true
    
if use_mfi_tf1_falling or use_mfi_tf1_rising


    
    longCondition12 := false
    shortCondition12 := false
      
    if (use_mfi_tf1_falling and mfi_tf1_falling_tf) or (use_mfi_tf1_rising and mfi_tf1_rising_tf)
        shortCondition12 := true
        longCondition12 := true
        
else

    longCondition12 := true
    shortCondition12 := true
   
// dimak MFI timeframe  END
// =====================================================


// =====================================================





// Two ATR (Volatility Check)
grDATR="=======Two ATR (Volatility Check) Base Settings========="
//useDATR = input(defval=false, title='Use Two ATR (Volatility Check) ?', group = grDATR)
lengthDATR = input.int(title='ATR length1 (20)(5)', defval=20, minval=1, group = grDATR)
length2DATR = input.int(title='ATR length2 (100)(20)', defval=100, minval=1, group = grDATR)
smoothingDATR = input.string(title='ATR Smoothing', defval='WMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group = grDATR)



DATR_ma_function(sourceDATR, lengthDATR1) =>
    if smoothingDATR == 'RMA'
        ta.rma(sourceDATR, lengthDATR1)
    else
        if smoothingDATR == 'SMA'
            ta.sma(sourceDATR, lengthDATR1)
        else
            if smoothingDATR == 'EMA'
                ta.ema(sourceDATR, lengthDATR1)
            else // WMA
                ta.wma(sourceDATR, lengthDATR1)

datr1 = DATR_ma_function(ta.tr(true), lengthDATR)
datr2 = DATR_ma_function(ta.tr(true), length2DATR)

// ATR Histograme
datr_hist = datr1-datr2


//plot(datr1+0.4, title='ATR', color=color.new(#77C5E1, 0))
//plot(datr2+0.4, title='ATR', color=color.new(#FF5252, 0))
//plot(datr_hist, color=color.red, style=plot.style_histogram)


// block for filters "ATR1 < ATR2" BEGIN
// "ATR1 < ATR2 - Volatility is Small in last bars, ATR1 > ATR2 - Volatility is High in last bars"
//grATR1ATR2 = "=============== Two ATR (ATR1 <> ATR2)=============="
use_atr1toart2_more_less = input(defval=false, title='Use ATR1 <> ATR2 ? ', group = grDATR)
atr1toart2_more_less = input.string(title='ATR1 to ATR2', defval='ATR1 < ATR2', options=['ATR1 < ATR2', 'ATR1 > ATR2'], group = grDATR, tooltip = "ATR1 < ATR2 - Volatility is Small in last bars, ATR1 > ATR2 - Volatility is High in last bars")
datr1todatr3 = use_atr1toart2_more_less and (atr1toart2_more_less == "ATR1 < ATR2") and (datr1 < datr2) ? true :  use_atr1toart2_more_less and (atr1toart2_more_less == "ATR1 > ATR2") and (datr1 > datr2) ? true : false

longCondition1 = true
shortCondition1 = true

if use_atr1toart2_more_less
    longCondition1 := false
    shortCondition1 := false
   
    longCondition1 := datr1todatr3
    shortCondition1 := longCondition1 

else

    longCondition1 := true
    shortCondition1 := true

// shortCondition1 and longCondition1 is if Fast ATR Must be higher (or Lower) than Slow ATR !!!
// block for filters "ATR1 < ATR2" END
// ==========================================================================
// NOTE "ATR1 < ATR2" and ( Barssince_Highest/Lowest + falling/rising ) are working separately. But Same ATR settings
// ==========================================================================


// ========== Two Average True Range ===============================







// ==================== Volume Filter =================== Begin
grVOL="=======Volume Filter========="
use_VOL_more_less = input(defval=false, title='Use VOL1 <> VOL2 ? ', group = grVOL)
VOL_more_less = input.string(title='VOL1 to VOL2', defval='VOL1 < VOL2', options=['VOL1 < VOL2', 'VOL1 > VOL2'], group = grVOL, tooltip = "VOL1 < VOL2 - Volume is Small in last bars, VOL1 > VOL2 - Volume is High in last bars")

lengthVOL = input.int(title='VOL length1 (20)(5)', defval=20, minval=1, group = grVOL)
length2VOL = input.int(title='VOL length2 (100)(20)', defval=100, minval=1, step = 5, group = grVOL)
smoothingVOL = input.string(title='VOL Smoothing', defval='WMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group = grVOL)



VOL_ma_function(sourceVOL, XlengthVOL) =>
    if smoothingVOL == 'RMA'
        ta.rma(sourceVOL, XlengthVOL)
    else
        if smoothingVOL == 'SMA'
            ta.sma(sourceVOL, XlengthVOL)
        else
            if smoothingVOL == 'EMA'
                ta.ema(sourceVOL, XlengthVOL)
            else // WMA
                ta.wma(sourceVOL, XlengthVOL)

vol1 = VOL_ma_function(volume, lengthVOL)
vol2 = VOL_ma_function(volume, length2VOL)


longCondition11 = true
shortCondition11 = true

if use_VOL_more_less
    longCondition11 := false
    shortCondition11 := false
   
    longCondition11 := use_VOL_more_less and (VOL_more_less == "VOL1 < VOL2") and (vol1 < vol2) ? true :  use_VOL_more_less and (VOL_more_less == "VOL1 > VOL2") and (vol1 > vol2) ? true : false
    shortCondition11 := longCondition11 

else

    longCondition11 := true
    shortCondition11 := true
// ==================== Volume Filter =================== END




// ======================= dimak CCI timeframe   Begin 1111111 ====================
GRUPO_CCI_TF  = "========== CCI FILTER ============"

lengthCCI = input.int(title="CCI TF Long(14):", group=GRUPO_CCI_TF, defval=14, minval=1)
tf_CCI_indicator = input.timeframe("",title="CCI TimeFrame:", group=GRUPO_CCI_TF)

useCCITFoverSold = input.bool(false, 'Use CCI LONG Range', group=GRUPO_CCI_TF)
overSoldCCITF = input.int(title='(LONG) CCI is More', group=GRUPO_CCI_TF, defval=-400, step=5, minval=-400, inline='22')
overSold2CCITF = input.int(title='& CCI Less', group=GRUPO_CCI_TF, defval=400, minval=-401, maxval = 400, step=5, inline='22')

useCCITFFoverBought = input.bool(false, 'Use CCI SHORT Range', group=GRUPO_CCI_TF)
overBoughtCCITF = input.int(title='(SHORT) CCI is Less', group=GRUPO_CCI_TF, defval=400, step=5, minval=-401, maxval = 400, inline='33')
overBought2CCITF = input.int(title='& CCI More', group=GRUPO_CCI_TF, defval=10, minval=-401, step=5, inline='33')

//CCI_tf1 = request.security(syminfo.tickerid, tf_CCI_indicator, ta.cci(close, lengthCCI), barmerge.gaps_off)
CCI_tf1 = f_security(syminfo.tickerid, tf_CCI_indicator, ta.cci(close, lengthCCI), false) // Repaint = false
//=====================================================    

longCondition9  = true
shortCondition9 = true

if useCCITFoverSold or useCCITFFoverBought
    longCondition9  := false
    shortCondition9 := false

    if useCCITFoverSold and (CCI_tf1 >= overSoldCCITF) and (CCI_tf1 <= overSold2CCITF)
        longCondition9  := true
    
    if useCCITFFoverBought and (CCI_tf1 <= overBoughtCCITF)  and (CCI_tf1 >= overBought2CCITF)
        shortCondition9 := true

else 
    longCondition9  := true
    shortCondition9 := true

//dimak CCI timeframe  END
//=====================================================





// ======================= dimak Momentum timeframe   Begin 1111111 ====================
GRUPO_MOM_TF  = "==========Momentum FILTER ============"

lengthMOM = input.int(title="Momentum TF Long(14):", group=GRUPO_MOM_TF, defval=14, minval=1)
tf_MOM_indicator = input.timeframe("",title="Momentum TimeFrame:", group=GRUPO_MOM_TF)

useMOMTFoverSold = input.bool(false, 'Use Momentum LONG Range (-100:100)', group=GRUPO_MOM_TF)
overSoldMOMTF = input.int(title='(LONG) Momentum is More', group=GRUPO_MOM_TF, defval=-100, step=5, minval=-100, maxval = 100, inline='22')
overSold2MOMTF = input.int(title='& Mom Less', group=GRUPO_MOM_TF, defval=10, minval=-100, maxval = 100, step=5, inline='22')

useMOMTFFoverBought = input.bool(false, 'Use Momentum SHORT Range (100:-100)', group=GRUPO_MOM_TF)
overBoughtMOMTF = input.int(title='(SHORT) Momentum is Less', group=GRUPO_MOM_TF, defval=95, step=5, minval=-100, maxval = 100, inline='33')
overBought2MOMTF = input.int(title='& Mom More', group=GRUPO_MOM_TF, defval=-30, minval=-100, maxval = 100, step=5, inline='33')


srcMOM = input(close, "Momentum Source", group=GRUPO_MOM_TF)
momm = ta.change(srcMOM)
f1(m) => m >= 0.0 ? m : 0.0
f2(m) => m >= 0.0 ? 0.0 : -m
m1 = f1(momm)
m2 = f2(momm)
sm1 = math.sum(m1, lengthMOM)
sm2 = math.sum(m2, lengthMOM)
percent(nom, div) => 100 * nom / div
chandeMO = percent(sm1-sm2, sm1+sm2)


//MOM_tf2 = request.security(syminfo.tickerid, tf_MOM_indicator, chandeMO, barmerge.gaps_off)
MOM_tf2 = f_security(syminfo.tickerid, tf_MOM_indicator, chandeMO, false) // Repaint = false


//=====================================================    

longCondition3  = true
shortCondition3 = true

if useMOMTFoverSold or useMOMTFFoverBought
    longCondition3  := false
    shortCondition3 := false

    if useMOMTFoverSold and (MOM_tf2 >= overSoldMOMTF) and (MOM_tf2 <= overSold2MOMTF)
        longCondition3  := true
    
    if useMOMTFFoverBought and (MOM_tf2 <= overBoughtMOMTF)  and (MOM_tf2 >= overBought2MOMTF)
        shortCondition3 := true

else 
    longCondition3  := true
    shortCondition3 := true

//dimak MOM timeframe  END
//=====================================================




// ========== Super Trend =============================== Begin 
grSUPTREND = "=============SUPER TREND FILTER============="
useSUPTREND = input(defval=false, title='Use SuperTrend ?', group = grSUPTREND)
opposite_SUPTREND = input(defval=false, title='Opposite SP Signal? (Sell on UPtrend..)', group = grSUPTREND)

PeriodsST = input.int(title='SuperTrend ATR Period', defval=10, minval=1, group=grSUPTREND)
MultiplierST = input.float(title='SuperTrend ATR Multiplier', step=0.1, defval=3.0, group=grSUPTREND)
//srcST = input(hl2, title='SuperTrend Source', group=grSUPTREND)
srcST = hl2
//changeATR = input(title='Set ATR Smoothing to SMA ?', defval=true, group=grSUPTREND)
changeATR = true
highlightingST = input(title='Show SuperTrend ?', defval=false, group=grSUPTREND)


atr2ST = ta.sma(ta.tr, PeriodsST)
atrST = changeATR ? ta.atr(PeriodsST) : atr2ST
upST = srcST - MultiplierST * atrST
up1ST = nz(upST[1], upST)
upST := close[1] > up1ST ? math.max(upST, up1ST) : upST
dnST = srcST + MultiplierST * atrST
dn1ST = nz(dnST[1], dnST)
dnST := close[1] < dn1ST ? math.min(dnST, dn1ST) : dnST

trendST = 1
trendST := nz(trendST[1], trendST)
trendST := trendST == -1 and close > dn1ST ? 1 : trendST == 1 and close < up1ST ? -1 : trendST

// check if Trend Changed. Not used now. Commented below.
buySignalST = trendST == 1 and trendST[1] == -1
sellSignalST = trendST == -1 and trendST[1] == 1
// check if Trend Changed. Not used now. Commented below.

// visual
displST = highlightingST ? display.all : display.none
upPlot = plot(trendST == 1 ? upST : na, title='Up Trend', style=plot.style_linebr, linewidth=2, color=color.new(color.green, 0), display = displST)
dnPlot = plot(trendST == 1 ? na : dnST, title='Down Trend', style=plot.style_linebr, linewidth=2, color=color.new(color.red, 0), display = displST)

mPlot = plot(ohlc4, title='', style=plot.style_circles, linewidth=0)
fill(mPlot, upPlot, title='UpTrend Highligter', color=color.rgb(76, 144, 175, 90), display = displST)
fill(mPlot, dnPlot, title='DownTrend Highligter', color=color.rgb(255, 82, 255, 90), display = displST)

// visual


longCondition5 = true
shortCondition5 = true

if useSUPTREND
    longCondition5 := false
    shortCondition5 := false
   
    longCondition5 := trendST == 1 and not opposite_SUPTREND ? true : trendST == -1 and opposite_SUPTREND ? true : false
    shortCondition5 := trendST == -1 and not opposite_SUPTREND ? true : trendST == 1 and opposite_SUPTREND ? true : false

    // signals by change trend
    //longCondition5 := not opposite_SUPTREND ? buySignalST : sellSignalST
    //shortCondition5 := not opposite_SUPTREND ? sellSignalST : buySignalST


else

    longCondition5 := true
    shortCondition5 := true


// ========== Super Trend =============================== End 




// ===================================================================================================
if USE_SignSL
    //if pos_reg_div_detected and not enable_long_strategy
    if pos_reg_div_detected and longCondition1  and longCondition2 and longCondition3 and longCondition4 and longCondition5 and longCondition8 and longCondition9  and longCondition10  and longCondition11 and longCondition12
        strategy.close('sell', comment='Close Short L-Sign', alert_message='stoploss')
        
    //if neg_reg_div_detected and not enable_short_strategy
    if neg_reg_div_detected  and shortCondition1 and shortCondition2 and shortCondition3 and shortCondition4 and shortCondition5 and shortCondition8 and shortCondition9 and shortCondition10 and shortCondition11 and shortCondition12
        strategy.close('buy', comment='Close Long S-Sign', alert_message='stoploss')
// ===================================================================================================




// ==  TEST CODE by  =================================================================================================

//reverseCond = strategy.closedtrades.exit_comment(strategy.closedtrades - 1)
//exitPrice = strategy.closedtrades.exit_price(strategy.closedtrades - 1)

//if strategy.position_size == 0 and reverseCond == 'LSL'
//    strategy.entry('sell', strategy.short, alert_message='enter_cycle')
//if strategy.position_size == 0 and reverseCond == 'SSL'
//    strategy.entry('buy', strategy.long, alert_message='enter_cycle')
// =====  TEST CODE by   ==============================================================================================



NotMultiOrders = ((strategy.closedtrades == 0) or ((bar_index != strategy.closedtrades.entry_bar_index(strategy.closedtrades - 1))))
//NotMultiOrders = true

// ============ New order after SL =======================================================================================

var wasLong = false
var wasShort = false

if USEorderOnSL and strategy.closedtrades.exit_bar_index(strategy.closedtrades-1) == bar_index and NotMultiOrders
    if wasLong
        wasLong := false
        strategy.entry('sell222', strategy.short, alert_message='enter_cycle')
        
    if wasShort
        wasShort := false
        strategy.entry('buy222', strategy.long, alert_message='enter_cycle')
 // ============= New order after SL ===================================================================       

 


// ===================================================================================================
if pos_reg_div_detected and enable_long_strategy and testPeriod()  and NotMultiOrders and longCondition1  and longCondition2 and longCondition3 and longCondition4 and longCondition5 and longCondition8 and longCondition9  and longCondition10  and longCondition11 and longCondition12
    strategy.entry('buy', strategy.long, alert_message='enter_cycle')
    //strategy.order('sell333',strategy.short,stop = longSLExitPrice, limit = longSLExitPrice, alert_message ='reverse_position')
    wasLong := true
    wasShort := false


if neg_reg_div_detected and enable_short_strategy and testPeriod()  and NotMultiOrders and shortCondition1 and shortCondition2 and shortCondition3 and shortCondition4 and shortCondition5 and shortCondition8 and shortCondition9 and shortCondition10 and shortCondition11 and shortCondition12
    strategy.entry('sell', strategy.short, alert_message='enter_cycle')
    //strategy.order('buy333',strategy.long,stop = shortSLExitPrice, limit = shortSLExitPrice, alert_message ='reverse_position')
    wasShort := true
    wasLong := false
// ===================================================================================================



// ===================================================================================================
if strategy.position_size > 0
    strategy.exit(id='Close Long %', from_entry='buy', stop=longSLExitPrice, limit=longExitPrice, alert_message='stoploss')
if strategy.position_size < 0
    strategy.exit(id='Close Short %', from_entry='sell', stop=shortSLExitPrice, limit=shortExitPrice, alert_message='stoploss')
// ===================================================================================================


displTPSL = not USEdisplTPSL ? display.none : display.all

// visual TP SL
avg_position_price_plot = plot(series=strategy.position_size != 0 ? strategy.position_avg_price : na, color=color.new(#c2bfbf, 25), style=plot.style_linebr, linewidth=2, title="Precio Entrada", display = displTPSL)

LONG_tp_plot            = plot(strategy.position_size > 0 and longExitPrice > 0.0 ? longExitPrice : na, color=color.new(color.lime, 60), style=plot.style_linebr, linewidth=2, title="LONG Take Profit", display = displTPSL)
LONG_sl_plot            = plot(strategy.position_size > 0 and longSLExitPrice > 0.0? longSLExitPrice : na, color=color.new(color.red, 60), style=plot.style_linebr, linewidth=2, title="Long Stop Loss", display = displTPSL)
fill(avg_position_price_plot, LONG_tp_plot, color=color.new(color.olive, 90), display = displTPSL)
fill(avg_position_price_plot, LONG_sl_plot, color=color.new(color.maroon, 90), display = displTPSL)

SHORT_tp_plot            = plot(strategy.position_size < 0 and shortExitPrice > 0.0 ? shortExitPrice : na, color=color.new(color.lime, 60), style=plot.style_linebr, linewidth=2, title="SHORT Take Profit", display = displTPSL)
SHORT_sl_plot            = plot(strategy.position_size < 0 and shortSLExitPrice > 0.0 ? shortSLExitPrice : na, color=color.new(color.red, 60), style=plot.style_linebr, linewidth=2, title="Short Stop Loss", display = displTPSL)
fill(avg_position_price_plot, SHORT_tp_plot, color=color.new(color.olive, 90), display = displTPSL)
fill(avg_position_price_plot, SHORT_sl_plot, color=color.new(color.maroon, 90), display = displTPSL)

Overview

Divergence for Many [Dimkud] supports long and short positions with customizable take-profit and stop-loss percentages. The main settings allow switching between long-only, short-only, or both modes, adjusting divergence parameters like pivot period and maximum checked pivots, and enabling confirmation requirements or additional visualizations such as divergence lines and pivot markers. It draws signals directly on the price chart with optional overlays for TP/SL. The testing period filter restricts backtesting to a user-defined date range. It repaints on the live bar.

Details

Published by

zhuzp98 on GitHub

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

Divergence, Oscillators & momentum

Markets

Crypto

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Display Visualisation for TP/SL ?boolfalseUSEdisplTPSL
Use Long ?boolfalseenable_long_strategy
Use Short ?booltrueenable_short_strategy
SL = TP ?boolfalseSLsameTP
Use Opposite Signal SL ?boolfalseUSE_SignSL
New Opposite-Order after SL ?boolfalseUSEorderOnSL
Take Profit (%)float0.9longProfitPerc
Stop Loss (%)float0.9longSLPerc
Start Yearint2022testStartYear
testStartMonthint5testStartMonth
testStartDayint1testStartDay
Stop Yearint2030testStopYear
Show all 40 settings
SettingTypeDefaultVariable
testStopMonthint12testStopMonth
testStopDayint30testStopDay
Pivot Period(9)int9prd
Source for Pivot PointsstringClosesource
Show Indicator NamesstringDon't Showshowindis
Maximum Pivot Points to Checkint10maxpp
Maximum Bars to Checkint100maxbars
Show Divergence Numberbooltrueshownum
Show Only Last Divergenceboolfalseshowlast
Don't Wait for Confirmationboolfalsedontconfirm
Show Divergence Linesboolfalseshowlines
Show Pivot Pointsboolfalseshowpivot
MACDbooltruecalcmacd
Fast(12):int12dimmacdFast
Slow(26):int26dimmacdSlow
Sign(9):int9dimmacdSignal
MACD Histogrambooltruecalcmacda
RSIbooltruecalcrsi
RSI period (14):int14dimRSI
Stochasticbooltruecalcstoc
STOCH Length(14):int14dimSTOCHlength
CCIbooltruecalccci
CCI Length(10)int10dimCCIL
Momentumbooltruecalcmom
Momentum Length(10)int10dimmomentL
OBVbooltruecalcobv
VWmacdbooltruecalcvwmacd
Volume Weighted Macd. Fast(12)int12dimmaFast
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

ETH_buy_3commas

by hasnocool
106 stars

This strategy overlays a Cipher B style WaveTrend study on the price chart and is titled for Ethereum buy alerts aimed at 3Commas. It calculates a WaveTrend channel and a short moving average, and can mark buy, sell, gold, and divergence dots. Settings change

Strategy v4 Oscillators & momentumDivergence
Updated 2 years ago · GPL-3.0 GitHub repository of ETH_buy_3commas
24 stars

This overlay strategy combines a Cipher B WaveTrend oscillator with two optional moving averages on the price chart. It exposes WaveTrend channel and average lengths, overbought and oversold levels, buy, sell and gold dots, and regular or hidden divergence mar

Strategy v5 Oscillators & momentumMoving averages
Updated 4 years ago · MPL-2.0 GitHub repository of Cipher B + EMAs Strategy

Divergenced A002

by ruckard
13 stars

Divergenced A002 is a momentum divergence strategy designed to identify entry opportunities using Squeeze Momentum Indicator shifts alongside price action. It enters long when momentum reaches higher lows during lower price lows and enters short on opposite di

Strategy v5 Oscillators & momentumDivergence
Updated 1 year ago · None stated GitHub repository of Divergenced A002

RSI Divergence

by muammeryldrm42
7 stars

This strategy detects bullish and bearish RSI divergences using price and RSI pivot points. A bullish divergence triggers a long entry when price forms a lower low while RSI forms a higher low below 40. A bearish divergence triggers a short entry when price fo

Strategy v5 Oscillators & momentumDivergence
Updated 3 months ago · MIT GitHub repository of RSI Divergence

This strategy executes long positions by combining a 200-period EMA trend filter, Stochastic RSI oversold crosses, and Williams Alligator retracements, supplemented by RSI divergence detection. It triggers long entries when the price trades above the 200 EMA w

Strategy v4 TrendOscillators & momentum
Updated 3 years ago · Apache-2.0 GitHub repository of 200 EMA + Alligator + Stochastic Long Strategy
4 stars

Divergence Strategy scans multiple technical oscillators to detect regular and hidden divergences against price action. It evaluates customizable indicators including MACD, RSI, Stochastic, CCI, Momentum, OBV, and Money Flow Index to trigger strategy entries o

Strategy v4 DivergenceOscillators & momentum
Updated 4 years ago · None stated GitHub repository of Divergence Strategy

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers