Untitled

mail@pastecode.io avatar
unknown
plain_text
2 months ago
13 kB
6
Indexable
Never
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue

//@version=5
indicator('Support Resistance - Dynamic', overlay=true, max_bars_back=600)
rb = input.int(10, title='Period for Pivot Points', minval=10)
prd = input.int(284, title='Loopback Period', minval=100, maxval=500)
nump = input.int(2, title='S/R strength', minval=1)
ChannelW = input.int(10, title='Channel Width %', minval=5)
label_location = input.int(10, title='Label Location +-', tooltip='0 means last bar. for example if you set it -5 then label is shown on last 5. bar. + means future bars')
linestyle = input.string('Dashed', title='Line Style', options=['Solid', 'Dotted', 'Dashed'])
LineColor = input(color.blue, title='Line Color')
drawhl = input(true, title='Draw Highest/Lowest Pivots in Period')
showpp = input(false, title='Show Point Points')

ph = ta.pivothigh(rb, rb)
pl = ta.pivotlow(rb, rb)
plotshape(ph and showpp, text='PH', style=shape.labeldown, color=color.new(color.white, 100), textcolor=color.new(color.red, 0), location=location.abovebar, offset=-rb)
plotshape(pl and showpp, text='PL', style=shape.labelup, color=color.new(color.white, 100), textcolor=color.new(color.lime, 0), location=location.belowbar, offset=-rb)

// S/R levels
sr_levels = array.new_float(21, na)

// if number of bars is less then the loop then pine highest() fundtion brings 'na'. we need highest/lowest to claculate channel size
// so you cannot see S/R until the number of bars is equal/greater then the "Loopback Period" 
prdhighest = ta.highest(prd)
prdlowest = ta.lowest(prd)
cwidth = (prdhighest - prdlowest) * ChannelW / 100

//availability of the PPs
aas = array.new_bool(41, true)

// last privot points have more priority to be support/resistance, so we start from them
// if we met new Pivot Point then we calculate all supports/resistances again
u1 = 0.0
u1 := nz(u1[1])
d1 = 0.0
d1 := nz(d1[1])
highestph = 0.0
lowestpl = 0.0
highestph := highestph[1]
lowestpl := lowestpl[1]
if ph or pl
    //old S/Rs not valid anymore
    for x = 0 to array.size(sr_levels) - 1 by 1
        array.set(sr_levels, x, na)

    highestph := prdlowest
    lowestpl := prdhighest
    countpp = 0  // keep position of the PP
    for x = 0 to prd by 1
        if na(close[x])
            break
        if not na(ph[x]) or not na(pl[x])  // is it PP?
            highestph := math.max(highestph, nz(ph[x], prdlowest), nz(pl[x], prdlowest))
            lowestpl := math.min(lowestpl, nz(ph[x], prdhighest), nz(pl[x], prdhighest))
            countpp += 1
            if countpp > 40
                break
            if array.get(aas, countpp)  // if PP is not used in a channel
                upl = (ph[x] ? high[x + rb] : low[x + rb]) + cwidth
                dnl = (ph[x] ? high[x + rb] : low[x + rb]) - cwidth
                u1 := countpp == 1 ? upl : u1
                d1 := countpp == 1 ? dnl : d1
                // to keep the PPs which will be in current channel
                tmp = array.new_bool(41, true)

                cnt = 0  // keep which pivot point we are on
                tpoint = 0  // number of PPs in the channel 
                for xx = 0 to prd by 1
                    if na(close[xx])
                        break
                    if not na(ph[xx]) or not na(pl[xx])
                        chg = false
                        cnt += 1
                        if cnt > 40
                            break
                        if array.get(aas, cnt)  // if PP not used in other channels
                            if not na(ph[xx])
                                if high[xx + rb] <= upl and high[xx + rb] >= dnl  // PP is in the channel?
                                    tpoint += 1
                                    chg := true
                                    chg

                            if not na(pl[xx])
                                if low[xx + rb] <= upl and low[xx + rb] >= dnl  // PP is in the channel?
                                    tpoint += 1
                                    chg := true
                                    chg
                        // set if PP is used in the channel
                        if chg and cnt < 41
                            array.set(tmp, cnt, false)

                if tpoint >= nump  // met enough PP in the channel? mark the PP as used for a channel and set the SR level
                    for g = 0 to 40 by 1
                        if not array.get(tmp, g)
                            array.set(aas, g, false)

                    if ph[x] and countpp < 21
                        array.set(sr_levels, countpp, high[x + rb])
                    if pl[x] and countpp < 21
                        array.set(sr_levels, countpp, low[x + rb])

setline(level) =>
    LineStyle = linestyle == 'Solid' ? line.style_solid : linestyle == 'Dotted' ? line.style_dotted : line.style_dashed
    _ret = line.new(bar_index - 1, level, bar_index, level, color=LineColor, width=2, style=LineStyle, extend=extend.both)
    _ret

if ph or pl
    var line highest_ = na
    var line lowest_ = na
    line.delete(highest_)
    line.delete(lowest_)
    if drawhl
        highest_ := line.new(bar_index - 1, highestph, bar_index, highestph, color=color.blue, style=line.style_dashed, width=1, extend=extend.both)
        lowest_ := line.new(bar_index - 1, lowestpl, bar_index, lowestpl, color=color.blue, style=line.style_dashed, width=1, extend=extend.both)
        lowest_

    var sr_lines = array.new_line(21, na)
    for x = 0 to array.size(sr_lines) - 1 by 1
        line.delete(array.get(sr_lines, x))
        if array.get(sr_levels, x)
            array.set(sr_lines, x, setline(array.get(sr_levels, x)))

// set new labels if changed
var sr_levs = array.new_float(21, na)
if ph or pl
    for x = 0 to array.size(sr_levs) - 1 by 1
        array.set(sr_levs, x, array.get(sr_levels, x))

// define and delete old labels
label hlabel = na
label llabel = na
label.delete(hlabel[1])
label.delete(llabel[1])
var sr_labels = array.new_label(21, na)
bool resistance_broken = false
bool support_broken = false
float r_s_level = na
// set labels
for x = 0 to array.size(sr_labels) - 1 by 1
    label.delete(array.get(sr_labels, x))
    if array.get(sr_levs, x)
        if close[1] <= array.get(sr_levs, x) and close > array.get(sr_levs, x)
            resistance_broken := true
            r_s_level := array.get(sr_levs, x)
            r_s_level
        if close[1] >= array.get(sr_levs, x) and close < array.get(sr_levs, x)
            support_broken := true
            r_s_level := array.get(sr_levs, x)
            r_s_level
        lab_loc = close >= array.get(sr_levs, x) ? label.style_label_up : label.style_label_down
        array.set(sr_labels, x, label.new(x=bar_index + label_location, y=array.get(sr_levs, x), text=str.tostring(math.round_to_mintick(array.get(sr_levs, x))), color=color.lime, textcolor=color.black, style=lab_loc))

hlabel := drawhl ? label.new(x=bar_index + label_location + math.round(math.sign(label_location)) * 20, y=highestph, text='Highest PH ' + str.tostring(highestph), color=color.silver, textcolor=color.black, style=label.style_label_down) : na
llabel := drawhl ? label.new(x=bar_index + label_location + math.round(math.sign(label_location)) * 20, y=lowestpl, text='Lowest PL ' + str.tostring(lowestpl), color=color.silver, textcolor=color.black, style=label.style_label_up) : na

plot(r_s_level, title='RS_level', display=display.none)
alertcondition(resistance_broken, title='Resistance Broken', message='Resistance Broken, Close Price: {{close}}, Resistance level = {{plot("RS_level")}}')
alertcondition(support_broken, title='Support Broken', message='Support Broken, Close Price: {{close}}, Support level = {{plot("RS_level")}}')


srch = input(high, 'Highs Source')
srcl = input(low, 'Lows Source')
mx = input.int(300, 'Max Range', minval=2, maxval=300)
nr = input.int(0, 'Noise Reduction', minval=0)
sm = nr + 1
sr = input(true, 'Show Resistance (Red)')
ss = input(true, 'Show Support (Green)')
sa = input(true, 'Show Average (Yellow)')
rl = input(true, 'Show Reference Lines')
cr = input(false, 'Show Criss-cross')
tl = input(false, 'Show Trace Lines')
exp = input(true, 'Set logarithmic')

SRCH = ta.ema(srch, sm)
SRCL = ta.ema(srcl, sm)

gap = 2
if barstate.islast
    if mx > bar_index - gap
        mx := bar_index - gap
        mx

hhh = 0.0
lll = 1000000000000.0

h2 = hhh
th2 = 0
l2 = lll
tl2 = 0
h1 = hhh
th1 = 0
l1 = lll
tl1 = 0
for i = mx + gap to gap by 1
    // find farthest high
    h1 := math.max(h1, SRCH[i])
    if h1 == SRCH[i]
        th1 := i
        th1
    // find farthest low
    l1 := math.min(l1, SRCL[i])
    if l1 == SRCL[i]
        tl1 := i
        tl1

for i = mx + gap to gap by 1
    if i < math.min(tl1, th1 / 2)  // find closest high
        h2 := math.max(h2, SRCH[i])
        if h2 == SRCH[i]
            th2 := i
            th2
    if i < math.min(th1, tl1 / 2)  // find closest low
        l2 := math.min(l2, SRCL[i])
        if l2 == SRCL[i]
            tl2 := i
            tl2

if th1 <= gap
    h1 := hhh
    th1 := 0
    for i = mx + gap to math.round(mx / 1.4669) + gap by 1
        // find closest high
        h1 := math.max(h1, SRCH[i])
        if h1 == SRCH[i]
            th1 := i
            th1
if tl1 <= gap
    l1 := lll
    tl1 := 0
    for i = mx + gap to math.round(mx / 1.4669) + gap by 1
        // find closest low
        l1 := math.min(l1, SRCL[i])
        if l1 == SRCL[i]
            tl1 := i
            tl1

if th2 <= gap
    h2 := hhh
    th2 := 0
    for i = gap to math.round(mx / 2.9338) + gap by 1
        // find closest high
        h2 := math.max(h2, SRCH[i])
        if h2 == SRCH[i]
            th2 := i
            th2
if tl2 <= gap
    l2 := lll
    tl2 := 0
    for i = gap to math.round(mx / 2.9338) + gap by 1
        // find closest low
        l2 := math.min(l2, SRCL[i])
        if l2 == SRCL[i]
            tl2 := i
            tl2

a1 = math.avg(h1, l1)
ta1 = math.round(math.avg(th1, tl1))
a2 = math.avg(h2, l2)
ta2 = math.round(math.avg(th2, tl2))

PLT(P1, P2, T1, T2) =>
    if exp
        t = T1 - T2
        slope = (math.log10(P1) - math.log10(P2)) / (0 - t)
        y = slope * T1 + math.log10(P1)
        math.pow(10, y)
    else
        (P2 - P1) / (T1 - T2) * T1 + P1


PLC = barstate.islast or tl

PLTh = PLC ? PLT(h1, h2, th1, th2) : na
PLTl = PLC ? PLT(l1, l2, tl1, tl2) : na
PLTa = PLC ? PLT(a1, a2, ta1, ta2) : na

sty = tl ? plot.style_stepline : plot.style_circles
lin = tl ? 1 : 2

plot(PLTh, 'Res', color=color.new(#ff0088, 0), style=sty, linewidth=lin)
plot(PLTa, 'Avg', color=color.new(#ffff00, 0), style=sty, linewidth=lin)
plot(PLTl, 'Sup', color=color.new(#00ff88, 0), style=sty, linewidth=lin)

bgcolor(close > PLTh ? color.new(#ff0088, 95) : color.new(#ff0088, 100), title='Close over Resistance', transp=90)
bgcolor(close < PLTl ? color.new(#00ff88, 95) : color.new(#00ff88, 100), title='Close under Support', transp=90)

L(T1, H1, T2, H2, CLR, W, X) =>
    line.new(bar_index - math.max(T1, 0), H1, bar_index - math.max(T2, 0), H2, color=CLR, width=W, extend=X ? extend.both : extend.none)

if sr
    L1b = L(th1, h1, th2, h2, #ff0088, 1, true)
    line.delete(L1b[1])
    if rl
        L1a = L(th1, h1, th2, h2, #ff0088, 3, false)
        line.delete(L1a[1])
if ss
    L2b = L(tl1, l1, tl2, l2, #00ff88, 1, true)
    line.delete(L2b[1])
    if rl
        L2a = L(tl1, l1, tl2, l2, #00ff88, 3, false)
        line.delete(L2a[1])
if sa
    L3b = L(ta1, a1, ta2, a2, #ffff00, 1, true)
    line.delete(L3b[1])
    if rl
        L3a = L(ta1, a1, ta2, a2, #ffff00, 3, false)
        line.delete(L3a[1])
if cr
    L4b = L(th1, h1, tl2, l2, #cccccc, 1, false)
    line.delete(L4b[1])
    L5b = L(tl1, l1, th2, h2, #cccccc, 1, false)
    line.delete(L5b[1])


length = input(title='Length', defval=14)
fastLength = input(title='Fast EMA Length', defval=2)
slowLength = input(title='Slow EMA Length', defval=30)
src = input(title='Source', defval=close)
highlight = input(title='Highlight ?', defval=true)
awaitBarConfirmation = input(title='Await Bar Confirmation ?', defval=true)

mom = math.abs(ta.change(src, length))
volatility = math.sum(math.abs(ta.change(src)), length)

// Efficiency Ratio
er = volatility != 0 ? mom / volatility : 0

fastAlpha = 2 / (fastLength + 1)
slowAlpha = 2 / (slowLength + 1)

alpha = math.pow(er * (fastAlpha - slowAlpha) + slowAlpha, 2)

kama = 0.0
kama := alpha * src + (1 - alpha) * nz(kama[1], src)

await = awaitBarConfirmation ? barstate.isconfirmed : true

maColor = highlight ? kama > kama[1] and await ? color.green : color.red : #6d1e7f
plot(kama, title='KAMA', linewidth=2, color=maColor, transp=0)

alertCond = maColor != maColor[1]
alertcondition(alertCond, title='Color Change', message='KAMA has changed its color!')

Leave a Comment