// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
// Modified to add confirmed buy and sell signals for https://b4indicators.com/threads/indicator-on-tv-using-hl-and-lh.238/
//@version=4
strategy("Double Zig Zag with HHLL B4Signals", overlay = true, max_bars_back = 500)
prd1 = input(defval = 8, title="ZigZag Period 1", minval = 2, maxval = 20)
prd2 = input(defval = 20, title="ZigZag Period 2", minval = 2, maxval = 50)
showzz = input(defval = "Show Both", title = "Show Zig Zags", options = ["Show Zig Zag 1", "Show Zig Zag 2", "Show Both", "Show None"])
showhhll = input(defval = "Show Both", title = "Show HHLL", options = ["Show HHLL 1", "Show HHLL 2", "Show Both", "Show None"])
upcol1 = input(defval = color.lime, title = "Zig Zag 1 Up Color")
dncol1 = input(defval = color.red, title = "Zig Zag 1 Down Color")
upcol2 = input(defval = color.blue, title = "Zig Zag 2 Up Color")
dncol2 = input(defval = color.purple, title = "Zig Zag 2 Down Color")
txtcol = input(defval = color.black, title = "Text Color")
zz1style = input(defval = "Dashed", title = "Zig Zag 1 Line Style", options = ["Dashed", "Dotted"])
zz1width = input(defval = 2, title = "Zig zag 1 Line Width", minval = 1, maxval = 4)
zz2width = input(defval = 3, title = "Zig zag 2 Line Width", minval = 1, maxval = 6)
float ph1 = highestbars(high, prd1) == 0 ? high : na
float pl1 = lowestbars(low, prd1) == 0 ? low : na
float ph2 = highestbars(high, prd2) == 0 ? high : na
float pl2 = lowestbars(low, prd2) == 0 ? low : na
var dir1 = 0
var dir2 = 0
dir1 := iff(ph1 and na(pl1), 1, iff(pl1 and na(ph1), -1, dir1))
dir2 := iff(ph2 and na(pl2), 1, iff(pl2 and na(ph2), -1, dir2))
var max_array_size = 10 // [5, 2] matrix
var zigzag1 = array.new_float(0)
var zigzag2 = array.new_float(0)
oldzigzag1 = array.copy(zigzag1)
oldzigzag2 = array.copy(zigzag2)
var direction1 = 0
var direction2 = 0
add_to_zigzag(pointer, value, bindex)=>
array.unshift(pointer, bindex)
array.unshift(pointer, value)
if array.size(pointer) > max_array_size
array.pop(pointer)
array.pop(pointer)
update_zigzag(pointer, value, bindex, dir)=>
if array.size(pointer) == 0
add_to_zigzag(pointer, value, bindex)
else
if (dir == 1 and value > array.get(pointer, 0)) or (dir == -1 and value < array.get(pointer, 0))
array.set(pointer, 0, value)
array.set(pointer, 1, bindex)
0.
dir1changed = change(dir1)
if ph1 or pl1
if dir1changed
add_to_zigzag(zigzag1, dir1 == 1 ? ph1 : pl1, bar_index)
else
update_zigzag(zigzag1, dir1 == 1 ? ph1 : pl1, bar_index, dir1)
dir2changed = change(dir2)
if ph2 or pl2
if dir2changed
add_to_zigzag(zigzag2, dir2 == 1 ? ph2 : pl2, bar_index)
else
update_zigzag(zigzag2, dir2 == 1 ? ph2 : pl2, bar_index, dir2)
if array.size(zigzag1) >= 6
var line zzline1 = na
var label zzlabel1 = na
if array.get(zigzag1, 0) != array.get(oldzigzag1, 0) or array.get(zigzag1, 1) != array.get(oldzigzag1, 1)
if array.get(zigzag1, 2) == array.get(oldzigzag1, 2) and array.get(zigzag1, 3) == array.get(oldzigzag1, 3)
line.delete(zzline1)
label.delete(zzlabel1)
direction1 := dir1 == 1 and array.get(zigzag1, 0) <= array.get(zigzag1, 4) ? -1 : dir1 == -1 and array.get(zigzag1, 0) >= array.get(zigzag1, 4) ? 1 : 0
if showzz == "Show Zig Zag 1" or showzz == "Show Both"
zzline1 := line.new( x1 = round(array.get(zigzag1, 1)), y1 = array.get(zigzag1, 0), x2 = round(array.get(zigzag1, 3)), y2 = array.get(zigzag1, 2),
color = dir1 == 1 ? upcol1 : dncol1,
width = zz1width,
style = zz1style == "Dashed" ? line.style_dashed : line.style_dotted)
if showhhll == "Show HHLL 1" or showhhll == "Show Both"
hhlltxt = dir1 == 1 ? array.get(zigzag1, 0) > array.get(zigzag1, 4) ? "HH" : "LH" : array.get(zigzag1, 0) < array.get(zigzag1, 4) ? "LL" : "HL"
labelcol = dir1 == 1 ? array.get(zigzag1, 0) > array.get(zigzag1, 4) ? upcol1 : dncol1 : array.get(zigzag1, 0) < array.get(zigzag1, 4) ? dncol1 : upcol1
zzlabel1 := label.new(x = round(array.get(zigzag1, 1)), y = array.get(zigzag1, 0), text = hhlltxt, color = labelcol, textcolor = txtcol, style = dir1 == 1 ? label.style_label_down : label.style_label_up)
if array.size(zigzag2) >= 6
var line zzline2 = na
var label zzlabel2 = na
if array.get(zigzag2, 0) != array.get(oldzigzag2, 0) or array.get(zigzag2, 1) != array.get(oldzigzag2, 1)
if array.get(zigzag2, 2) == array.get(oldzigzag2, 2) and array.get(zigzag2, 3) == array.get(oldzigzag2, 3)
line.delete(zzline2)
label.delete(zzlabel2)
if showzz == "Show Zig Zag 2" or showzz == "Show Both"
zzline2 := line.new(x1 = round(array.get(zigzag2, 1)), y1 = array.get(zigzag2, 0), x2 = round(array.get(zigzag2, 3)), y2 = array.get(zigzag2, 2), color = dir2 == 1 ? upcol2 : dncol2, width = zz2width)
if showhhll == "Show HHLL 2" or showhhll == "Show Both"
hhlltxt = dir2 == 1 ? array.get(zigzag2, 0) > array.get(zigzag2, 4) ? "HH" : "LH" : array.get(zigzag2, 0) < array.get(zigzag2, 4) ? "LL" : "HL"
labelcol = dir2 == 1 ? array.get(zigzag2, 0) > array.get(zigzag2, 4) ? upcol2 : dncol2 : array.get(zigzag2, 0) < array.get(zigzag2, 4) ? dncol2 : upcol2
zzlabel2 := label.new(x = round(array.get(zigzag2, 1)), y = array.get(zigzag2, 0), text = hhlltxt, color = labelcol, textcolor = txtcol, style = dir2 == 1 ? label.style_label_down : label.style_label_up)
barhigh5 = highestbars(close, 5)
barlow5 = lowestbars(close, 5)
plot(barhigh5, title="High/Low X Bars Line", color=color.orange)
plot(barlow5, title="High/Low X Bars Line", color=color.blue)
direction1_signal = 0
direction1_signal := direction1[1] == 1 and direction1 == 1 and close > open ? 1 : direction1[1] == -1 and direction1 == -1 and close < open ? -1 : direction1 == 0 ? 0 : direction1_signal[1]
BuySignal1 = crossover(direction1_signal, 0)
SellSignal1 = crossunder(direction1_signal, 0)
direction2_signal = 0
direction2_signal := direction2[1] == 1 and direction2 == 1 and close > open ? 1 : direction2[1] == -1 and direction2 == -1 and close < open ? -1 : direction2 == 0 ? 0 : direction2_signal[1]
BuySignal2 = crossover(direction2_signal, 0)
SellSignal2 = crossunder(direction2_signal, 0)
plotshape(BuySignal1, title="Buy1", text="Buy", style=shape.labelup, location=location.belowbar, color=color.rgb(0, 255, 0), textcolor=color.rgb(0, 0, 0), size=size.normal)
plotshape(SellSignal1, title="Sell1", text="Sell", style=shape.labeldown, location=location.abovebar, color=color.rgb(255, 0, 0), textcolor=color.rgb(255, 255, 255), size=size.normal)
plotshape(BuySignal2, title="Buy2", text="Buy2", style=shape.labelup, location=location.belowbar, color=color.rgb(0, 255, 0), textcolor=color.rgb(0, 0, 0), size=size.normal)
plotshape(SellSignal2, title="Sell2", text="Sell2", style=shape.labeldown, location=location.abovebar, color=color.rgb(255, 0, 0), textcolor=color.rgb(255, 255, 255), size=size.normal)
//Strategy
strategy.entry("long", strategy.long, when=BuySignal1)
strategy.entry("short",strategy.short, when=SellSignal1)