Multi-Level ZigZag Harmonic Patterns

0% found this document useful (0 votes)
360 views13 pages
This document contains source code for an indicator that detects multi-level zigzag harmonic patterns in price data. It defines inputs for configuring different zigzag levels and harmonic pa…

Uploaded by

Viswanath Palyam
  • ZigZag Harmonic Pattern Script

// This source code is subject to the terms of the Mozilla Public License 2.

0 at
[Link]
// � HeWhoMustNotBeNamed

//@version=5
indicator('Multi Level ZigZag Harmonic Patterns', shorttitle='ML - ZigZag - HP',
overlay=true, max_bars_back=1000, max_lines_count=500, max_labels_count=500)

max_array_size = [Link](200, step=20)


useZigZagChain = input(false)
showZigZag1 = input(true)
zigzag1Length = [Link](10, step=5, minval=3)
zigzag1Color = input([Link])
zigzag1Width = 1
zigzag1Style = line.style_solid

showZigZag2 = input(true)
zigzag2Length = [Link](2, step=1, minval=2)
zigzag2Color = input([Link])
zigzag2Width = 1
zigzag2Style = line.style_solid

showZigZag3 = input(true)
zigzag3Length = [Link](3, step=1, minval=2)
zigzag3Color = input([Link])
zigzag3Width = 1
zigzag3Style = line.style_solid

showZigZag4 = input(true)
zigzag4Length = [Link](4, step=1, minval=2)
zigzag4Color = input([Link])
zigzag4Width = 1
zigzag4Style = line.style_solid

abcdClassic = input(true)
abEQcd = input(true)
abcdExt = input(true)
gartley = input(true)
crab = input(true)
deepCrab = input(true)
bat = input(true)
butterfly = input(true)
shark = input(true)
cypher = input(true)
threeDrives = input(true)
fiveZero = input(true)
doubleBottomTop = input(true)
errorPercent = [Link](10, minval=5, step=5, maxval=20)
MaxRiskPerReward = [Link](30, title='Max Risk Per Reward (Double Top/Bottom)',
step=10, minval=0)

waitForConfirmation = input(true)

bullishColor = input([Link])
bearishColor = input([Link])

err_min = (100 - errorPercent) / 100


err_max = (100 + errorPercent) / 100
var zigzagpivots1 = array.new_float(0)
var zigzagpivotbars1 = array.new_int(0)
var zigzagpivotdirs1 = array.new_int(0)

var zigzagpivots2 = array.new_float(0)


var zigzagpivotbars2 = array.new_int(0)
var zigzagpivotdirs2 = array.new_int(0)

var zigzagpivots3 = array.new_float(0)


var zigzagpivotbars3 = array.new_int(0)
var zigzagpivotdirs3 = array.new_int(0)

var zigzagpivots4 = array.new_float(0)


var zigzagpivotbars4 = array.new_int(0)
var zigzagpivotdirs4 = array.new_int(0)

var wmlines1 = array.new_line(8)


var wmtype1 = array.new_int(2, 1)
var wmLabels1 = array.new_bool(13, false)
var wmLabel1 = array.new_label(1)

var wmlines2 = array.new_line(8)


var wmtype2 = array.new_int(2, 1)
var wmLabels2 = array.new_bool(13, false)
var wmLabel2 = array.new_label(1)

var wmlines3 = array.new_line(8)


var wmtype3 = array.new_int(2, 1)
var wmLabels3 = array.new_bool(13, false)
var wmLabel3 = array.new_label(1)

var wmlines4 = array.new_line(8)


var wmtype4 = array.new_int(2, 1)
var wmLabels4 = array.new_bool(13, false)
var wmLabel4 = array.new_label(1)

pivots(length) =>
float phigh = [Link](high, length) == 0 ? high : na
float plow = [Link](low, length) == 0 ? low : na
dir = 0
iff_1 = plow and na(phigh) ? -1 : dir[1]
dir := phigh and na(plow) ? 1 : iff_1
[dir, phigh, plow, bar_index, bar_index]

outerpivots(length, zigzagpivots, zigzagpivotbars) =>


zigzagminimal = [Link](zigzagpivots, 0, length - 1)
lastPivot = [Link](zigzagpivots, 0)
lastPivotBar = [Link](zigzagpivotbars, 0)
highestPivot = [Link](zigzagminimal)
lowestPivot = [Link](zigzagminimal)
float phigh = lastPivot == highestPivot ? lastPivot : na
float plow = lastPivot == lowestPivot ? lastPivot : na
int phighbar = lastPivot == highestPivot ? lastPivotBar : na
int plowbar = lastPivot == lowestPivot ? lastPivotBar : na
zdir = 0
iff_1 = plow and na(phigh) ? -1 : zdir[1]
zdir := phigh and na(plow) ? 1 : iff_1
[zdir, phigh, plow, phighbar, plowbar]
zigzagcore(dir, phigh, plow, phighbar, plowbar, zigzagpivots, zigzagpivotbars,
zigzagpivotdirs) =>
dirchanged = [Link](dir)
newZG = false
if phigh or plow
value = dir == 1 ? phigh : plow
bar = phigh ? phighbar : plowbar
newDir = dir
if not dirchanged and [Link](zigzagpivots) >= 1
pivot = [Link](zigzagpivots)
pivotbar = [Link](zigzagpivotbars)
pivotdir = [Link](zigzagpivotdirs)
useNewValues = value * pivotdir < pivot * pivotdir
value := useNewValues ? pivot : value
bar := useNewValues ? pivotbar : bar
bar

if [Link](zigzagpivots) >= 2
LastPoint = [Link](zigzagpivots, 1)
newDir := dir * value > dir * LastPoint ? dir * 2 : dir
newDir

[Link](zigzagpivots, value=value)
[Link](zigzagpivotbars, bar)
[Link](zigzagpivotdirs, newDir)
newZG := true
if [Link](zigzagpivots) > max_array_size
[Link](zigzagpivots)
[Link](zigzagpivotbars)
[Link](zigzagpivotdirs)
newZG

zigzag(length, zigzagpivots, zigzagpivotbars, zigzagpivotdirs) =>


[dir, phigh, plow, phighbar, plowbar] = pivots(length)
zigzagcore(dir, phigh, plow, phighbar, plowbar, zigzagpivots, zigzagpivotbars,
zigzagpivotdirs)

outerzigzag(outerzigzagLength, zigzagpivots, zigzagpivotbars, outerzigzagpivots,


outerzigzagpivotbars, outerzigzagpivotdirs) =>
newOuterZG = false
if [Link](zigzagpivots) >= outerzigzagLength * 2
[zdir, phigh, plow, phighbar, plowbar] = outerpivots(outerzigzagLength * 2,
zigzagpivots, zigzagpivotbars)
newOuterZG := zigzagcore(zdir, phigh, plow, phighbar, plowbar,
outerzigzagpivots, outerzigzagpivotbars, outerzigzagpivotdirs)
newOuterZG
newOuterZG

draw_zigzag(zigzaglines, zigzagpivots, zigzagpivotbars, zigzagcolor, zigzagwidth,


zigzagstyle, showZigZag) =>
if [Link](zigzagpivots) >= 2 and showZigZag
y1 = [Link](zigzagpivots, 0)
y2 = [Link](zigzagpivots, 1)
x1 = [Link](zigzagpivotbars, 0)
x2 = [Link](zigzagpivotbars, 1)

zline = [Link](x1=x1, y1=y1, x2=x2, y2=y2, color=zigzagcolor,


width=zigzagwidth, style=zigzagstyle)
if [Link](zigzaglines) >= 1
lastLine = [Link](zigzaglines, 0)
if x2 == line.get_x2(lastLine) and y2 == line.get_y2(lastLine)
[Link](lastLine)
[Link](zigzaglines, zline)

get_harmonic_label(wmLabels, dir, price, bar) =>


isGartley = [Link](wmLabels, 0)
isCrab = [Link](wmLabels, 1)
isDeepCrab = [Link](wmLabels, 2)
isBat = [Link](wmLabels, 3)
isButterfly = [Link](wmLabels, 4)
isShark = [Link](wmLabels, 5)
isCypher = [Link](wmLabels, 6)
is3Drives = [Link](wmLabels, 7)
isFiveZero = [Link](wmLabels, 8)
isAbcd = [Link](wmLabels, 9)
isAbEqCd = [Link](wmLabels, 10)
isAbcdExt = [Link](wmLabels, 11)
isDoubleTop = [Link](wmLabels, 12) and dir < 0
isDoubleBottom = [Link](wmLabels, 12) and dir > 0

labelText = isGartley ? 'Gartley' : ''


labelText := labelText + (isCrab ? (labelText == '' ? '' : '\n') + 'Crab' : '')
labelText := labelText + (isDeepCrab ? (labelText == '' ? '' : '\n') + 'Deep
Crab' : '')
labelText := labelText + (isBat ? (labelText == '' ? '' : '\n') + 'Bat' : '')
labelText := labelText + (isButterfly ? (labelText == '' ? '' : '\n') +
'Butterfly' : '')
labelText := labelText + (isShark ? (labelText == '' ? '' : '\n') + 'Shark' :
'')
labelText := labelText + (isCypher ? (labelText == '' ? '' : '\n') + 'Cypher' :
'')
labelText := labelText + (is3Drives ? (labelText == '' ? '' : '\n') + '3 Drive'
: '')
labelText := labelText + (isFiveZero ? (labelText == '' ? '' : '\n') + '5-0' :
'')
labelText := labelText + (isAbcd ? (labelText == '' ? '' : '\n') + 'ABCD' : '')
labelText := labelText + (isAbEqCd ? (labelText == '' ? '' : '\n') + 'AB=CD' :
'')
labelText := labelText + (isAbcdExt ? (labelText == '' ? '' : '\n') + 'ABCD
Extension' : '')
labelText := labelText + (isDoubleTop ? (labelText == '' ? '' : '\n') + 'Double
Top' : '')
labelText := labelText + (isDoubleBottom ? (labelText == '' ? '' : '\n') +
'Double Bottom' : '')
trendColor = dir > 0 ? bullishColor : bearishColor

baseLabel = [Link](x=bar, y=price, text=labelText, yloc=[Link],


color=trendColor, style=dir < 1 ? label.style_label_down : label.style_label_up,
textcolor=[Link], size=[Link])
baseLabel

detect_harmonic_pattern(zigzagpivots, zigzagpivotbars, zigzagpivotdirs, wmlines,


wmlabel, wmtype, wmLabels, zigzagColor, zigzagWidth, zigzagStyle, showZigZag) =>
start = waitForConfirmation ? 1 : 0
wm_pattern = false
abcd_pattern = false
double_pattern = false
if [Link](zigzagpivots) >= 6 + start and showZigZag
d = [Link](zigzagpivots, start + 0)
dBar = [Link](zigzagpivotbars, start + 0)
dDir = [Link](zigzagpivotdirs, start + 0)

c = [Link](zigzagpivots, start + 1)
cBar = [Link](zigzagpivotbars, start + 1)
cDir = [Link](zigzagpivotdirs, start + 1)

b = [Link](zigzagpivots, start + 2)
bBar = [Link](zigzagpivotbars, start + 2)
bDir = [Link](zigzagpivotdirs, start + 2)

a = [Link](zigzagpivots, start + 3)
aBar = [Link](zigzagpivotbars, start + 3)
aDir = [Link](zigzagpivotdirs, start + 3)

x = [Link](zigzagpivots, start + 4)
xBar = [Link](zigzagpivotbars, start + 4)
xDir = [Link](zigzagpivotdirs, start + 4)

y = [Link](zigzagpivots, start + 5)
yBar = [Link](zigzagpivotbars, start + 5)
yDir = [Link](zigzagpivotdirs, start + 5)

highPoint = [Link](x, a, b, c, d)
lowPoint = [Link](x, a, b, c, d)
dir = c > d ? 1 : -1

xabRatio = [Link](b - a) / [Link](x - a)


abcRatio = [Link](c - b) / [Link](a - b)
bcdRatio = [Link](d - c) / [Link](b - c)
xadRatio = [Link](d - a) / [Link](x - a)
yxaRatio = [Link](a - x) / [Link](y - x)

abTime = [Link](aBar - bBar)


cdTime = [Link](cBar - dBar)
abPrice = [Link](a - b)
cdPrice = [Link](c - d)

time_ratio = cdTime / abTime


price_ratio = cdPrice / abPrice
abcdDirection = a < b and a < c and c < b and c < d and a < d and b < d ? 1
: a > b and a > c and c > b and c > d and a > d and b > d ? -1 : 0

risk = [Link](b - d)
reward = [Link](c - d)
riskPerReward = risk * 100 / (risk + reward)

if b < highPoint and b > lowPoint


//gartley
if gartley and xabRatio >= 0.618 * err_min and xabRatio <= 0.618 *
err_max and abcRatio >= 0.382 * err_min and abcRatio <= 0.886 * err_max and
(bcdRatio >= 1.272 * err_min and bcdRatio <= 1.618 * err_max or xadRatio >= 0.786 *
err_min and xadRatio <= 0.786 * err_max)
wm_pattern := true
[Link](wmLabels, 0, true)
else
[Link](wmLabels, 0, false)
//Crab
if crab and xabRatio >= 0.382 * err_min and xabRatio <= 0.618 * err_max
and abcRatio >= 0.382 * err_min and abcRatio <= 0.886 * err_max and (bcdRatio >=
2.24 * err_min and bcdRatio <= 3.618 * err_max or xadRatio >= 1.618 * err_min and
xadRatio <= 1.618 * err_max)
wm_pattern := true
[Link](wmLabels, 1, true)
else
[Link](wmLabels, 1, false)
//Deep Crab
if deepCrab and xabRatio >= 0.886 * err_min and xabRatio <= 0.886 *
err_max and abcRatio >= 0.382 * err_min and abcRatio <= 0.886 * err_max and
(bcdRatio >= 2.00 * err_min and bcdRatio <= 3.618 * err_max or xadRatio >= 1.618 *
err_min and xadRatio <= 1.618 * err_max)
wm_pattern := true
[Link](wmLabels, 2, true)
else
[Link](wmLabels, 2, false)
//Bat
if bat and xabRatio >= 0.382 * err_min and xabRatio <= 0.50 * err_max
and abcRatio >= 0.382 * err_min and abcRatio <= 0.886 * err_max and (bcdRatio >=
1.618 * err_min and bcdRatio <= 2.618 * err_max or xadRatio >= 0.886 * err_min and
xadRatio <= 0.886 * err_max)
wm_pattern := true
[Link](wmLabels, 3, true)
else
[Link](wmLabels, 3, false)
//Butterfly
if butterfly and xabRatio >= 0.786 * err_min and xabRatio <= 0.786 *
err_max and abcRatio >= 0.382 * err_min and abcRatio <= 0.886 * err_max and
(bcdRatio >= 1.618 * err_min and bcdRatio <= 2.618 * err_max or xadRatio >= 1.272 *
err_min and xadRatio <= 1.618 * err_max)
wm_pattern := true
[Link](wmLabels, 4, true)
else
[Link](wmLabels, 4, false)
//Shark
if shark and abcRatio >= 1.13 * err_min and abcRatio <= 1.618 * err_max
and bcdRatio >= 1.618 * err_min and bcdRatio <= 2.24 * err_max and xadRatio >=
0.886 * err_min and xadRatio <= 1.13 * err_max
wm_pattern := true
[Link](wmLabels, 5, true)
else
[Link](wmLabels, 5, false)
//Cypher
if cypher and xabRatio >= 0.382 * err_min and xabRatio <= 0.618 *
err_max and abcRatio >= 1.13 * err_min and abcRatio <= 1.414 * err_max and
(bcdRatio >= 1.272 * err_min and bcdRatio <= 2.00 * err_max or xadRatio >= 0.786 *
err_min and xadRatio <= 0.786 * err_max)
wm_pattern := true
[Link](wmLabels, 6, true)
else
[Link](wmLabels, 6, false)
//3 drive
if threeDrives and yxaRatio >= 0.618 * err_min and yxaRatio <= 0.618 *
err_max and xabRatio >= 1.27 * err_min and xabRatio <= 1.618 * err_max and abcRatio
>= 0.618 * err_min and abcRatio <= 0.618 * err_max and bcdRatio >= 1.27 * err_min
and bcdRatio <= 1.618 * err_max
wm_pattern := true
[Link](wmLabels, 7, true)
else
[Link](wmLabels, 7, false)
//5-0
if fiveZero and xabRatio >= 1.13 * err_min and xabRatio <= 1.618 * err_max
and abcRatio >= 1.618 * err_min and abcRatio <= 2.24 * err_max and bcdRatio >= 0.5
* err_min and bcdRatio <= 0.5 * err_max
wm_pattern := true
[Link](wmLabels, 8, true)
else
[Link](wmLabels, 8, false)
//ABCD Classic
if abcdClassic and abcRatio >= 0.618 * err_min and abcRatio <= 0.786 *
err_max and bcdRatio >= 1.272 * err_min and bcdRatio <= 1.618 * err_max and
abcdDirection != 0
abcd_pattern := true
[Link](wmLabels, 9, true)
else
[Link](wmLabels, 9, false)
//AB=CD
if abEQcd and time_ratio >= err_min and time_ratio <= err_max and
price_ratio >= err_min and price_ratio <= err_max and abcdDirection != 0
abcd_pattern := true
[Link](wmLabels, 10, true)
else
[Link](wmLabels, 10, false)
//ABCD Ext
if abcdExt and price_ratio >= 1.272 * err_min and price_ratio <= 1.618 *
err_max and abcRatio >= 0.618 * err_min and abcRatio <= 0.786 * err_max and
abcdDirection != 0
abcd_pattern := true
[Link](wmLabels, 11, true)
else
[Link](wmLabels, 11, false)
//Double Top/Bottom
if doubleBottomTop and (dDir == 1 and bDir == 2 and cDir == -1 or dDir == -
1 and bDir == -2 and cDir == 1) and riskPerReward < MaxRiskPerReward
double_pattern := true
[Link](wmLabels, 12, true)
else
[Link](wmLabels, 12, false)

cancelW = false
cancelA = false
cancelD = false
if wm_pattern[1] and x == x[1] and a == a[1] and b == b[1] and c == c[1]
[Link]([Link](wmlines, 0))
[Link]([Link](wmlines, 1))
[Link]([Link](wmlines, 2))
[Link]([Link](wmlines, 3))
[Link]([Link](wmlines, 4))
[Link]([Link](wmlines, 5))
[Link]([Link](wmlines, 6))
[Link]([Link](wmlines, 7))
[Link]([Link](wmlabel, 0))
cancelW := true
cancelW

if abcd_pattern[1] and a == a[1] and b == b[1] and c == c[1]


[Link]([Link](wmlines, 1))
[Link]([Link](wmlines, 2))
[Link]([Link](wmlines, 3))
[Link]([Link](wmlabel, 0))
cancelA := true
cancelA

if double_pattern[1] and a == a[1] and b == b[1] and c == c[1]


[Link]([Link](wmlines, 5))
[Link]([Link](wmlabel, 0))
cancelD := true
cancelD

if wm_pattern
xa = [Link](y1=x, y2=a, x1=xBar, x2=aBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
ab = [Link](y1=a, y2=b, x1=aBar, x2=bBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
bc = [Link](y1=b, y2=c, x1=bBar, x2=cBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
cd = [Link](y1=c, y2=d, x1=cBar, x2=dBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
xb = [Link](y1=x, y2=b, x1=xBar, x2=bBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
bd = [Link](y1=b, y2=d, x1=bBar, x2=dBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
xd = [Link](y1=x, y2=d, x1=xBar, x2=dBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
ac = [Link](y1=a, y2=c, x1=aBar, x2=cBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
[Link](wmlines, 0, xa)
[Link](wmlines, 1, ab)
[Link](wmlines, 2, bc)
[Link](wmlines, 3, cd)
[Link](wmlines, 4, xb)
[Link](wmlines, 5, bd)
[Link](wmlines, 6, xd)
[Link](wmlines, 7, ac)
[Link](wmtype, 0, dir)
if abcd_pattern and not wm_pattern
ab = [Link](y1=a, y2=b, x1=aBar, x2=bBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
bc = [Link](y1=b, y2=c, x1=bBar, x2=cBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
cd = [Link](y1=c, y2=d, x1=cBar, x2=dBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
[Link](wmlines, 1, ab)
[Link](wmlines, 2, bc)
[Link](wmlines, 3, cd)
[Link](wmtype, 0, dir)
if double_pattern and not wm_pattern
bd = [Link](y1=b, y2=d, x1=bBar, x2=dBar, color=zigzagColor,
width=zigzagWidth, style=zigzagStyle)
[Link](wmlines, 5, bd)
[Link](wmtype, 0, dir)

if wm_pattern or abcd_pattern or double_pattern


[Link](wmlabel, 0, get_harmonic_label(wmLabels, dir, d, dBar))
pattern = wm_pattern and not wm_pattern[1] or abcd_pattern and not
abcd_pattern[1] or double_pattern and not double_pattern[1]
pattern

level1ZG = zigzag(zigzag1Length, zigzagpivots1, zigzagpivotbars1, zigzagpivotdirs1)


level2ZG = outerzigzag(zigzag2Length, zigzagpivots1, zigzagpivotbars1,
zigzagpivots2, zigzagpivotbars2, zigzagpivotdirs2)
level3ZG = outerzigzag(useZigZagChain ? zigzag3Length : zigzag2Length +
zigzag3Length, useZigZagChain ? zigzagpivots2 : zigzagpivots1, useZigZagChain ?
zigzagpivotbars2 : zigzagpivotbars1, zigzagpivots3, zigzagpivotbars3,
zigzagpivotdirs3)
level4ZG = outerzigzag(useZigZagChain ? zigzag4Length : zigzag2Length +
zigzag3Length + zigzag4Length, useZigZagChain ? zigzagpivots3 : zigzagpivots1,
useZigZagChain ? zigzagpivotbars3 : zigzagpivotbars1, zigzagpivots4,
zigzagpivotbars4, zigzagpivotdirs4)

wm_pattern1 = detect_harmonic_pattern(zigzagpivots1, zigzagpivotbars1,


zigzagpivotdirs1, wmlines1, wmLabel1, wmtype1, wmLabels1, zigzag1Color,
zigzag1Width, zigzag1Style, showZigZag1)
wm_pattern2 = detect_harmonic_pattern(zigzagpivots2, zigzagpivotbars2,
zigzagpivotdirs2, wmlines2, wmLabel2, wmtype2, wmLabels2, zigzag2Color,
zigzag2Width, zigzag2Style, showZigZag2)
wm_pattern3 = detect_harmonic_pattern(zigzagpivots3, zigzagpivotbars3,
zigzagpivotdirs3, wmlines3, wmLabel3, wmtype3, wmLabels3, zigzag3Color,
zigzag3Width, zigzag3Style, showZigZag3)
wm_pattern4 = detect_harmonic_pattern(zigzagpivots4, zigzagpivotbars4,
zigzagpivotdirs4, wmlines4, wmLabel4, wmtype4, wmLabels4, zigzag4Color,
zigzag4Width, zigzag4Style, showZigZag4)

alertcondition(wm_pattern1 or wm_pattern2 or wm_pattern3 or wm_pattern4, title='New


harmonic pattern alert', message='New harmonic pattern detected on {{ticker}}')

//end of this part

//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 at
[Link]
// � ZenAndTheArtOfTrading / Pine Script Mastery Course
// Dynamic Structure Indicator v2.0
// Last Updated: 8th January, 2021
//indicator('Dynamic Structure Indicator v2.0', shorttitle='DSI', overlay=true)

// Get user input


atrMovement = input(title='ATR Movement Required', defval=1.0)
lookback = [Link](title='High/Low Lookback', defval=25, step=5)
maxZoneSize = [Link](title='Max Zone Size (Compared to ATR)', defval=2.5,
step=0.5)
newStructureReset = [Link](title='Zone Update Count Before Reset', defval=25,
step=5)
drawPreviousStructure = input(title='Draw Previous Structure', defval=true)

// Get current ATR value


atr = [Link](14)

// Get highest body and lowest body for the current candle
highestBody = open > close ? open : close
lowestBody = open > close ? close : open

// Set up our persistent S&R variables (1 = the wick and 2 = the body)
var res1 = 0.0
var res2 = 0.0
var sup1 = 0.0
var sup2 = 0.0
var lookForNewResistance = true
var lookForNewSupport = true

// Set up our *previous* support & resistance variables (for drawing support-
turned-resistance etc)
var previousRes1 = 0.0
var previousRes2 = 0.0
var previousSup1 = 0.0
var previousSup2 = 0.0

// Set up our ATR variables (for identifying significant declines/rallies to


validate S&R zones)
var atrSaved = 0.0
var potentialR1 = 0.0
var potentialR2 = 0.0
var potentialS1 = 0.0
var potentialS2 = 0.0

// Detect fractal swing highs for resistance


// We're looking for this pattern: .|.
if high[1] == [Link](high, lookback) and high < high[1] and
lookForNewResistance
r1 = high[1]
r2 = highestBody[2] > highestBody[1] ? highestBody[2] : highestBody >
highestBody[1] ? highestBody : highestBody[1]
if (r1 - r2) / atr <= maxZoneSize
lookForNewResistance := false
potentialR1 := r1
potentialR2 := r2
atrSaved := atr
atrSaved

// Detect fractal swing lows for support


// We're looking for this pattern: *|*
if low[1] == [Link](low, lookback) and low > low[1] and lookForNewSupport
s1 = low[1]
s2 = lowestBody[2] < lowestBody[1] ? lowestBody[2] : lowestBody < lowestBody[1]
? lowestBody : lowestBody[1]
if (s2 - s1) / atr <= maxZoneSize
lookForNewSupport := false
potentialS1 := s1
potentialS2 := s2
atrSaved := atr
atrSaved

// Check if potential resistance zone has already been violated. If it has, reset
our potential R1 & R2
if close > potentialR1 and [Link]
potentialR1 := na
potentialR2 := na
potentialR2

// Check if potential support zone has already been violated. If it has, reset our
potential S1 & S2
if close < potentialS1 and [Link]
potentialS1 := na
potentialS2 := na
potentialS2

// Check if we've had a significant decline since detecting swing high


if potentialR1 - low >= atrSaved * atrMovement
previousRes1 := na(previousRes1) ? potentialR1 : previousRes1 // Store
previous resistance if we're not already drawing it
previousRes2 := na(previousRes2) ? potentialR2 : previousRes2
res1 := potentialR1
res2 := potentialR2
potentialR1 := na
potentialR2 := na
potentialR2

// Check if we've had a significant rally since detecting swing low


if high - potentialS1 >= atrSaved * atrMovement
previousSup1 := na(previousSup1) ? potentialS1 : previousSup1 // Store
previous support if we're not already drawing it
previousSup2 := na(previousSup2) ? potentialS2 : previousSup2
sup1 := potentialS1
sup2 := potentialS2
potentialS1 := na
potentialS2 := na
potentialS2

// Declare support & resistance update counters


// This is used for forcing a zone reset if a zone is not violated within a
reasonable period of time
var supCount = 0
var resCount = 0

// If the previous resistance high has been violated then begin searching for a new
resistance zone
if close >= res1 and [Link]
lookForNewResistance := true
lookForNewSupport := true
resCount += 1
resCount

// If the previous support low has been violated then begin searching for a new
support zone
if close <= sup1 and [Link]
lookForNewSupport := true
lookForNewResistance := true
supCount += 1
supCount

// If our current resistance zone has been violated, store its values to draw new
*potential* support zone
// The idea being that once a major resistance zone is violated it often becomes
future support
// But we only save previous S&R if we don't already have one saved (or our zone
update count exceeds newStructureReset)
if close > res1 and na(previousRes1) and [Link] or previousRes1 ==
0.0 or supCount >= newStructureReset
previousRes1 := res1
previousRes2 := res2
supCount := 0
supCount

// If our current support zone has been violated, store its values to draw new
*potential* resistance zone
// The idea being that once a major support zone is violated it often becomes
future resistance
// But we only save previous S&R if we don't already have one saved (or our zone
update count exceeds newStructureReset)
if close < sup1 and na(previousSup1) and [Link] or previousSup1 ==
0.0 or resCount >= newStructureReset
previousSup1 := sup1
previousSup2 := sup2
resCount := 0
resCount

// If our resistance-turned-support zone has been violated, reset our saved


resistance variables
if close < previousRes2 and [Link]
previousRes1 := na
previousRes2 := na
previousRes2

// If our support-turned-resistance zone has been violated, reset our saved support
variables
if close > previousSup2 and [Link]
previousSup1 := na
previousSup2 := na
previousSup2

// Draw our current resistance zone


r1 = plot(res1 == res1[1] ? res1 : na, color=close >= res1 ? [Link] :
[Link], style=plot.style_linebr, title='R1')
r2 = plot(res1 == res1[1] ? res2 : na, color=close >= res1 ? [Link] :
[Link], style=plot.style_linebr, title='R2')
fill(r1, r2, color=close > res1 ? [Link] : [Link], title='Resistance Zone',
transp=50)

// Draw our current support zone


s1 = plot(sup1 == sup1[1] ? sup1 : na, color=close < sup1 ? [Link] :
[Link], style=plot.style_linebr, title='S1')
s2 = plot(sup1 == sup1[1] ? sup2 : na, color=close < sup1 ? [Link] :
[Link], style=plot.style_linebr, title='S2')
fill(s1, s2, color=close < sup1 ? [Link] : [Link], title='Support Zone',
transp=50)

// Draw our previous support zone (turned potential resistance)


ps1 = plot(previousSup1 == previousSup1[1] and previousSup1 != sup1 and
drawPreviousStructure ? previousSup1 : na, color=[Link]([Link], 0),
style=plot.style_linebr, title='PS1')
ps2 = plot(previousSup1 == previousSup1[1] and previousSup1 != sup1 and
drawPreviousStructure ? previousSup2 : na, color=[Link]([Link], 0),
style=plot.style_linebr, title='PS2')
fill(ps1, ps2, color=[Link]([Link], 10), title='Previous Support Zone')

// Draw our previous resistance zone (turned potential support)


pr1 = plot(previousRes1 == previousRes1[1] and previousRes1 != res1 and
drawPreviousStructure ? previousRes1 : na, color=[Link]([Link], 0),
style=plot.style_linebr, title='PR1')
pr2 = plot(previousRes1 == previousRes1[1] and previousRes1 != res1 and
drawPreviousStructure ? previousRes2 : na, color=[Link]([Link], 0),
style=plot.style_linebr, title='PR2')
fill(pr1, pr2, color=[Link]([Link], 10), title='Previous Resistance Zone')

// Check alert conditions


alertResistance = high >= res2
alertSupport = low <= sup2
alertResistanceBO = close >= res1
alertSupportBO = close <= sup1

// Trigger alerts
alertcondition(alertResistance or alertSupport or alertResistanceBO or
alertSupportBO, title='[DSI] Alert!', message='DSI alert for {{ticker}}')
alertcondition(alertResistance, title='[DSI] Resistance Alert', message='Price has
entered current potential resistance zone for {{ticker}}')
alertcondition(alertSupport, title='[DSI] Support Alert', message='Price has
entered current potential support zone for {{ticker}}')
alertcondition(alertResistanceBO, title='[DSI] Resistance Breakout', message='Price
has broken past potential resistance zone for {{ticker}}')
alertcondition(alertSupportBO, title='[DSI] Support Breakout', message='Price has
broken past potential support zone for {{ticker}}')

// This source code is subject to the terms of the Mozilla Public License 2.0 at 
https://mozilla.org/MPL/2.0/
//  HeWhoMustN
var zigzagpivots1 = array.new_float(0)
var zigzagpivotbars1 = array.new_int(0)
var zigzagpivotdirs1 = array.new_int(0)
var zi
zigzagcore(dir, phigh, plow, phighbar, plowbar, zigzagpivots, zigzagpivotbars, 
zigzagpivotdirs) =>
    dirchanged = ta.chang
lastLine = array.get(zigzaglines, 0)
            if x2 == line.get_x2(lastLine) and y2 == line.get_y2(lastLine)
d = array.get(zigzagpivots, start + 0)
        dBar = array.get(zigzagpivotbars, start + 0)
        dDir = array.get(
//Crab
            if crab and xabRatio >= 0.382 * err_min and xabRatio <= 0.618 * err_max
and abcRatio >= 0.382
array.set(wmLabels, 7, true)
        else
            array.set(wmLabels, 7, false)
        //5-0
        if five
line.delete(array.get(wmlines, 1))
            line.delete(array.get(wmlines, 2))
            line.delete(array.g
pattern = wm_pattern and not wm_pattern[1] or abcd_pattern and not 
abcd_pattern[1] or double_pattern and not double_patt
var res1 = 0.0
var res2 = 0.0
var sup1 = 0.0
var sup2 = 0.0
var lookForNewResistance = true
var lookForNewSupport = true
// S

You might also like