hurst-diamond-notation-pivots.pine
Copy
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Ā© BarefootJoey
//@version=5
indicator("Hurst Diamond Notation Pivots", overlay=false)
philo = input.string("Lows", "Highs or Lows?", options=["Highs", "Lows"])
linecolor = input.color(color.new(color.gray,0), "Label/Line Color")
ptransp = input.int(33, "Radar Transparency", minval=0, maxval=100)
ltransp = input.int(100, "Line Transparency", minval=0, maxval=100)
n = bar_index
// Input/2 (Default 5) Length Pivot Cycle
hcol = input.color(color.purple, "Half Cycle Color", inline="hc")
cych = input.int(5, "Length", inline="hc")
labh = input.bool(true, "Label?", inline="hc")
labhf = input.bool(true, "Forecast?", inline="hc")
plh = philo == "Highs" ? ta.pivothigh(cych, cych) : ta.pivotlow(cych, cych) // Define a PL or PH based on L/H Switch in settings
plhy = philo == "Highs" ? -5 : 5 // Position the pivot on the Y axis of the oscillator
plhi = ta.barssince(plh) // Bars since pivot occured?
plhp = plhi>cych // Bars since pivot occured greater than cycle length?
lowhin = philo == "Highs" ? ta.highest(close, cych*2) : ta.lowest(close, cych*2) // Highest/Lowest for the cycle
lowh = ta.barssince(plh)>cych ? lowhin : na // If the barssince pivot are greater than cycle length, show the uncomnfirmed "pivot tracker"
plot(plhy, "Half Cycle Radar Line", color=plhp?hcol:color.new(linecolor,ltransp), offset=(cych*-1), display=display.none) // Cycle detection lines v1
plotshape(plh ? plhy : na, "Half Cycle Confirmed", style=shape.diamond, location=location.absolute, color=hcol, size = size.tiny, offset=(cych*-1)) // Past Pivots
plotshape(lowh ? plhy : na, "Half Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(hcol, ptransp), size = size.tiny, offset=(cych*-1), show_last=1, display=display.none) // AKA the "Tracker/Radar" v1
// LuxAlgo pivot average calculation used for the forecast
barssince_ph = 0
ph_x2 = ta.valuewhen(plh, n - cych, 1) // x values for pivot
if plh
barssince_ph := (n - cych) - ph_x2 // if there is a pivot, then BarsSincePivot = (BarIndex - Cycle Length) - x values for pivot
avg_barssince_ph = ta.cum(barssince_ph) / ta.cum(math.sign(barssince_ph)) // AvgBarsSincePivot = Sum of the BarsSincePivot divided by (Sum of the number of signs of BarsSincePivot, AKA the number of BarsSincePivots)
// Draw a diamond forecast label and forecast range line
tooltiph = "š Pivot Cycle: " + str.tostring(cych) + " bars" +
"\nā± Last Pivot: " + str.tostring(plhi + cych) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_ph)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_ph)-(plhi + cych)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_ph/2)) + " bars"
var label fh = na
var line lh = na
if labhf
fh := label.new(n + math.min((math.round(avg_barssince_ph) - (plhi+cych)), 500), y=plhy, size=size.tiny, style=label.style_diamond, color=color.new(hcol,ptransp),tooltip =tooltiph)
label.delete(fh[1])
lh := line.new(x1=n + math.min(math.round((avg_barssince_ph - (plhi+cych))-(avg_barssince_ph/2)), 500), x2=n + math.min(math.round((avg_barssince_ph - (plhi+cych))+(avg_barssince_ph/2)), 500), y1=plhy, y2=plhy, color=color.new(hcol,ptransp))
line.delete(lh[1])
var label ch = na // Create a label
if labh // Define the label
ch := label.new(bar_index, y=plhy, text=str.tostring(cych), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(plhp?hcol:linecolor,0), tooltip=tooltiph)
label.delete(ch[1])
// Input (Default 10) Length Pivot Cycle
col = input.color(color.blue, "Full Cycle Color", inline="fc")
cyc = input.int(10, "Length", inline="fc")
labf = input.bool(true, "Label?", inline="fc")
labff = input.bool(true, "Forecast?", inline="fc")
pl = philo == "Highs" ? ta.pivothigh(cyc, cyc) : ta.pivotlow(cyc, cyc)
ply = philo == "Highs" ? -10 : 10
pli = ta.barssince(pl)
plp = pli>cyc
lowin = philo == "Highs" ? ta.highest(close, cyc*2) : ta.lowest(close, cyc*2)
lowf = ta.barssince(pl)>cyc ? lowin : na
plot(ply, "Full Cycle Radar Line", color=plp?col:color.new(linecolor,ltransp), offset=(cyc*-1), display=display.none)
plotshape(pl ? ply : na, "Full Cycle Confirmed", style=shape.diamond, location=location.absolute, color=col, size = size.tiny, offset=(cyc*-1))
plotshape(lowf ? ply : na, "Full Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(col, ptransp), size = size.tiny, offset=(cyc*-1), show_last=1, display=display.none)
// Forecast & Labels
barssince_p = 0
p_x2 = ta.valuewhen(pl, n - cyc, 1)
p_y2 = ta.valuewhen(pl, pl, 1)
if pl
barssince_p := (n - cyc) - p_x2
avg_barssince_p = ta.cum(barssince_p) / ta.cum(math.sign(barssince_p))
tooltipf = "š Pivot Cycle: " + str.tostring(cyc) + " bars" +
"\nā± Last Pivot: " + str.tostring(pli + cyc) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_p)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_p)-(pli + cyc)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_p/2)) + " bars"
var label ff = na
var line lf = na
if labff
ff := label.new(n + math.min((math.round(avg_barssince_p) - (pli+cyc)), 500), y=ply, size=size.tiny, style=label.style_diamond, color=color.new(col,ptransp),tooltip =tooltipf)
label.delete(ff[1])
lf := line.new(x1=n + math.min(math.round((avg_barssince_p - (pli+cyc))-(avg_barssince_p/2)), 500), x2=n + math.min(math.round((avg_barssince_p - (pli+cyc))+(avg_barssince_p/2)), 500), y1=ply, y2=ply, color=color.new(col,ptransp))
line.delete(lf[1])
var label cf = na
if labf
cf := label.new(bar_index, y=ply, text=str.tostring(cyc), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(plp?col:linecolor,0), tooltip=tooltipf)
label.delete(cf[1])
// Input x2 (Default 20) Length Pivot Cycle
col2 = input.color(color.aqua, "2x Cycle Color ", inline="2c")
cyc2 = input.int(20, "Length", inline="2c")
lab2 = input.bool(true, "Label?", inline="2c")
lab2f = input.bool(true, "Forecast?", inline="2c")
pl2 = philo == "Highs" ? ta.pivothigh(cyc2, cyc2) : ta.pivotlow(cyc2, cyc2)
pl2y = philo == "Highs" ? -15 : 15
pl2i = ta.barssince(pl2)
pl2p = pl2i>cyc2
low2in = philo == "Highs" ? ta.highest(close, cyc2*2) : ta.lowest(close, cyc2*2)
low2 = ta.barssince(pl2)>cyc2 ? low2in : na
plot(pl2y, "2x Cycle Radar Line", color=pl2p?col2:color.new(linecolor,ltransp), offset=(cyc2*-1), display=display.none)
plotshape(pl2 ? pl2y : na, "2x Cycle Confirmed", style=shape.diamond, location=location.absolute, color=col2, size = size.tiny, offset=(cyc2*-1))
plotshape(low2 ? pl2y : na, "2x Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(col2, ptransp), size = size.tiny, offset=(cyc2*-1), show_last=1, display=display.none)
// Forecast & Labels
barssince_p2 = 0
p2_x2 = ta.valuewhen(pl2, n - cyc2, 1)
p2_y2 = ta.valuewhen(pl2, pl2, 1)
if pl2
barssince_p2 := (n - cyc2) - p2_x2
avg_barssince_p2 = ta.cum(barssince_p2) / ta.cum(math.sign(barssince_p2))
tooltip2 = "š Pivot Cycle: " + str.tostring(cyc2) + " bars" +
"\nā± Last Pivot: " + str.tostring(pl2i + cyc2) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_p2)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_p2)-(pl2i + cyc2)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_p2/2)) + " bars"
var label f2 = na
var line l2 = na
if lab2f
f2 := label.new(n + math.min((math.round(avg_barssince_p2) - (pl2i+cyc2)), 500), y=pl2y, size=size.tiny, style=label.style_diamond, color=color.new(col2,ptransp),tooltip =tooltip2)
label.delete(f2[1])
l2 := line.new(x1=n + math.min(math.round((avg_barssince_p2 - (pl2i+cyc2))-(avg_barssince_p2/2)), 500), x2=n + math.min(math.round((avg_barssince_p2 - (pl2i+cyc2))+(avg_barssince_p2/2)), 500), y1=pl2y, y2=pl2y, color=color.new(col2,ptransp))
line.delete(l2[1])
var label c2 = na
if lab2
c2 := label.new(bar_index, y=pl2y, text=str.tostring(cyc2), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(pl2p?col2:linecolor,0), tooltip=tooltip2)
label.delete(c2[1])
// Input x4 (Default 40) Length Pivot Cycle
col4 = input.color(color.green, "4x Cycle Color ", inline="4c")
cyc4 = input.int(40, "Length", inline="4c")
lab4 = input.bool(true, "Label?", inline="4c")
lab4f = input.bool(true, "Forecast?", inline="4c")
pl4 = philo == "Highs" ? ta.pivothigh(cyc4, cyc4) : ta.pivotlow(cyc4, cyc4)
pl4y = philo == "Highs" ? -20 : 20
pl4i = ta.barssince(pl4)
pl4p = pl4i>cyc4
low4in = philo == "Highs" ? ta.highest(close, cyc4*2): ta.lowest(close, cyc4*2)
low4 = ta.barssince(pl4)>cyc4 ? low4in : na
plot(pl4y, "4x Cycle Radar Line", color=pl4p?col4:color.new(linecolor,ltransp), offset=(cyc4*-1), display=display.none)
plotshape(pl4 ? pl4y : na, "4x Cycle Confirmed", style=shape.diamond, location=location.absolute, color=col4, size = size.tiny, offset=(cyc4*-1))
plotshape(low4 ? pl4y : na, "4x Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(col4, ptransp), size = size.tiny, offset=(cyc4*-1), show_last=1, display=display.none)
// Forecast & Labels
barssince_p4 = 0
p4_x2 = ta.valuewhen(pl4, n - cyc4, 1)
p4_y2 = ta.valuewhen(pl4, pl4, 1)
if pl4
barssince_p4 := (n - cyc4) - p4_x2
avg_barssince_p4 = ta.cum(barssince_p4) / ta.cum(math.sign(barssince_p4))
tooltip4 = "š Pivot Cycle: " + str.tostring(cyc4) + " bars" +
"\nā± Last Pivot: " + str.tostring(pl4i + cyc4) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_p4)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_p4)-(pl4i + cyc4)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_p4/2)) + " bars"
var label f4 = na
var line l4 = na
if lab4f
f4 := label.new(n + math.min((math.round(avg_barssince_p4) - (pl4i+cyc4)), 500), y=pl4y, size=size.tiny, style=label.style_diamond, color=color.new(col4,ptransp),tooltip =tooltip4)
label.delete(f4[1])
l4 := line.new(x1=n + math.min(math.round((avg_barssince_p4 - (pl4i+cyc4))-(avg_barssince_p4/2)), 500), x2=n + math.min(math.round((avg_barssince_p4 - (pl4i+cyc4))+(avg_barssince_p4/2)), 500), y1=pl4y, y2=pl4y, color=color.new(col4,ptransp))
line.delete(l4[1])
var label c4 = na
if lab4
c4 := label.new(bar_index, y=pl4y, text=str.tostring(cyc4), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(pl4p?col4:linecolor,0), tooltip=tooltip4)
label.delete(c4[1])
// Input x8 (Default 80) Length Pivot Cycle
col8 = input.color(color.yellow, "8x Cycle Color ", inline="8c")
cyc8 = input.int(80, "Length", inline="8c")
lab8 = input.bool(true, "Label?", inline="8c")
lab8f = input.bool(true, "Forecast?", inline="8c")
pl8 = philo == "Highs" ? ta.pivothigh(cyc8, cyc8) : ta.pivotlow(cyc8, cyc8)
pl8y = philo == "Highs" ? -25 : 25
pl8i = ta.barssince(pl8)
pl8p = pl8i>cyc8
low8in = philo == "Highs" ? ta.highest(close, cyc8*2) : ta.lowest(close, cyc8*2)
low8t = ta.barssince(pl8)>cyc8 ? low8in : na
low8p = ta.barssince(low8in)
plot(pl8y, "8x Cycle Radar Line", color=pl8p?col8:color.new(linecolor,ltransp), offset=(cyc8*-1), display=display.none)
plotshape(pl8 ? pl8y : na, "8x Cycle Confirmed", style=shape.diamond, location=location.absolute, color=col8, size = size.tiny, offset=(cyc8*-1))
plotshape(low8t ? pl8y : na, "8x Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(col8, ptransp), size = size.tiny, offset=(cyc8*-1), show_last=1, display=display.none)
// Forecast & Labels
barssince_p8 = 0
p8_x2 = ta.valuewhen(pl8, n - cyc8, 1)
p8_y2 = ta.valuewhen(pl8, pl8, 1)
if pl8
barssince_p8 := (n - cyc8) - p8_x2
avg_barssince_p8 = ta.cum(barssince_p8) / ta.cum(math.sign(barssince_p8))
tooltip8 = "š Pivot Cycle: " + str.tostring(cyc8) + " bars" +
"\nā± Last Pivot: " + str.tostring(pl8i + cyc8) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_p8)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_p8)-(pl8i + cyc8)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_p8/2)) + " bars"
var label f8 = na
var line l8 = na
if lab8f
f8 := label.new(n + math.min((math.round(avg_barssince_p8) - (pl8i+cyc8)), 500), y=pl8y, size=size.tiny, style=label.style_diamond, color=color.new(col8,ptransp),tooltip =tooltip8)
label.delete(f8[1])
l8 := line.new(x1=n + math.min(math.round((avg_barssince_p8 - (pl8i+cyc8))-(avg_barssince_p8/2)), 500), x2=n + math.min(math.round((avg_barssince_p8 - (pl8i+cyc8))+(avg_barssince_p8/2)), 500), y1=pl8y, y2=pl8y, color=color.new(col8,ptransp))
line.delete(l8[1])
var label c8 = na
if lab8
c8 := label.new(bar_index, y=pl8y, text=str.tostring(cyc8), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(pl8p?col8:linecolor,0), tooltip=tooltip8)
label.delete(c8[1])
// Input x16 (Default 160) Length Pivot Cycle
col16 = input.color(color.orange, "16x Cycle Color", inline="16c")
cyc16 = input.int(160, "Length", inline="16c")
lab16 = input.bool(true, "Label?", inline="16c")
lab16f = input.bool(true, "Forecast?", inline="16c")
pl16 = philo == "Highs" ? ta.pivothigh(cyc16, cyc16) : ta.pivotlow(cyc16, cyc16)
pl16y = philo == "Highs" ? -30 : 30
pl16i = ta.barssince(pl16)
pl16p = pl16i>cyc16
low16in = philo == "Highs" ? ta.highest(close, cyc16*2) : ta.lowest(close, cyc16*2)
low16 = ta.barssince(pl16)>cyc16 ? low16in : na
plot(pl16y, "16x Cycle Radar Line", color=pl16p?col16:color.new(linecolor,ltransp), offset=(cyc16*-1), display=display.none)
plotshape(pl16 ? pl16y : na, "16x Cycle Confirmed", style=shape.diamond, location=location.absolute, color=col16, size = size.tiny, offset=(cyc16*-1))
plotshape(low16 ? pl16y : na, "16x Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(col16, ptransp), size = size.tiny, offset=(cyc16*-1), show_last=1, display=display.none)
// Forecast & Labels
barssince_p16 = 0
p16_x2 = ta.valuewhen(pl16, n - cyc16, 1)
p16_y2 = ta.valuewhen(pl16, pl16, 1)
if pl16
barssince_p16 := (n - cyc16) - p16_x2
avg_barssince_p16 = ta.cum(barssince_p16) / ta.cum(math.sign(barssince_p16))
tooltip16 = "š Pivot Cycle: " + str.tostring(cyc16) + " bars" +
"\nā± Last Pivot: " + str.tostring(pl16i + cyc16) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_p16)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_p16)-(pl16i + cyc16)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_p16/2)) + " bars"
var label f16 = na
var line l16 = na
if lab16f
f16 := label.new(n + math.min((math.round(avg_barssince_p16) - (pl16i+cyc16)), 500), y=pl16y, size=size.tiny, style=label.style_diamond, color=color.new(col16,ptransp),tooltip =tooltip16)
label.delete(f16[1])
l16 := line.new(x1=n + math.min(math.round((avg_barssince_p16 - (pl16i+cyc16))-(avg_barssince_p16/2)), 500), x2=n + math.min(math.round((avg_barssince_p16 - (pl16i+cyc16))+(avg_barssince_p16/2)), 500), y1=pl16y, y2=pl16y, color=color.new(col16,ptransp))
line.delete(l16[1])
var label c16 = na
if lab16
c16 := label.new(bar_index, y=pl16y, text=str.tostring(cyc16), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(pl16p?col16:linecolor,0), tooltip=tooltip16)
label.delete(c16[1])
// Input x32 (Default 230) Length Pivot Cycle
col32 = input.color(color.red, "32x Cycle Color", inline="32c")
cyc32 = input.int(320, "Length", inline="32c")
lab32 = input.bool(true, "Label?", inline="32c")
lab32f = input.bool(true, "Forecast?", inline="32c")
pl32 = philo == "Highs" ? ta.pivothigh(cyc32, cyc32) : ta.pivotlow(cyc32, cyc32)
pl32y = philo == "Highs" ? -35 : 35
pl32i = ta.barssince(pl32)
pl32p = pl32i>cyc32
low32in = philo == "Highs" ? ta.highest(close, cyc32*2) : ta.lowest(close, cyc32*2)
low32 = ta.barssince(pl32)>cyc32 ? low32in : na
plot(pl32y, "32x Cycle Radar Line", color=pl32p?col32:color.new(linecolor,ltransp), offset=(cyc32*-1), display=display.none)
plotshape(pl32 ? pl32y : na, "32x Cycle Confirmed", style=shape.diamond, location=location.absolute, color=col32, size = size.tiny, offset=(cyc32*-1))
plotshape(low32 ? pl32y : na, "32x Cycle Radar", style=shape.circle, location=location.absolute, color=color.new(col32, ptransp), size = size.tiny, offset=(cyc32*-1), show_last=1, display=display.none)
// Forecast & Labels
barssince_p32 = 0
p32_x2 = ta.valuewhen(pl32, n - cyc32, 1)
p32_y2 = ta.valuewhen(pl32, pl32, 1)
if pl32
barssince_p32 := (n - cyc32) - p32_x2
avg_barssince_p32 = ta.cum(barssince_p32) / ta.cum(math.sign(barssince_p32))
tooltip32 = "š Pivot Cycle: " + str.tostring(cyc32) + " bars" +
"\nā± Last Pivot: " + str.tostring(pl32i + cyc32) + " bars ago" +
"\nš§® Average Pivot: " + str.tostring(math.round(avg_barssince_p32)) + " bars" +
"\nš® Next Pivot: " + str.tostring(math.round(avg_barssince_p32)-(pl32i + cyc32)) + " bars" +
"\nš Range: +/- " + str.tostring(math.round(avg_barssince_p32/2)) + " bars"
var label f32 = na
var line l32 = na
if lab32f
f32 := label.new(n + math.min((math.round(avg_barssince_p32) - (pl32i+cyc32)), 500), y=pl32y, size=size.tiny, style=label.style_diamond, color=color.new(col32,ptransp),tooltip =tooltip32)
label.delete(f32[1])
l32 := line.new(x1=n + math.min(math.round((avg_barssince_p32 - (pl32i+cyc32))-(avg_barssince_p32/2)), 500), x2=n + math.min(math.round((avg_barssince_p32 - (pl32i+cyc32))+(avg_barssince_p32/2)), 500), y1=pl32y, y2=pl32y, color=color.new(col32,ptransp))
line.delete(l32[1])
var label c32 = na
if lab32
c32 := label.new(bar_index, y=pl32y, text=str.tostring(cyc32), size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(pl32p?col32:linecolor,0), tooltip=tooltip32)
label.delete(c32[1])
// Alert
alert_cycle_in = input.string("Half", "Cycle for Alerts", ['Half', 'Full', '2x', '4x', '8x', '16x', '32x'], tooltip='You must "Add alert" in order to receive alerts for the selectetd cycle. After your first alert, you can change the cycle setting and set another alert to have alerts for multiple cycle confirmation.')
alert_cycle_out = alert_cycle_in == 'Half' ? plh :
alert_cycle_in == 'Full' ? pl :
alert_cycle_in == '2x' ? pl2 :
alert_cycle_in == '4x' ? pl4 :
alert_cycle_in == '8x' ? pl8 :
alert_cycle_in == '16x' ? pl16 :
pl32
hi_lo = philo == 'Lows' ? 'Low' : 'High'
if alert_cycle_out
alert(alert_cycle_in + ' Cycle Hurst Diamond Notation Pivot ' + hi_lo + ' Confirmed', alert.freq_once_per_bar)
// EoS made w/ ⤠by @BarefootJoey āšš
Show all 299 lines