//@version=5
indicator("Auto Pivots and 50%", "Auto Pivots and 50%", overlay=true, max_lines_count=500, max_labels_count=500)
//This version combines two older versions. The auto pivots feature originally coded by @infinity trading and the traditional pivots indicator with 50% levels added by ERD74.
//Now 2 indicators are not needed.
// Constants
AUTO = "Auto"
DAILY = "Daily"
WEEKLY = "Weekly"
MONTHLY = "Monthly"
QUARTERLY = "Quarterly"
YEARLY = "Yearly"
BIYEARLY = "Biyearly"
TRIYEARLY = "Triyearly"
QUINQUENNIALLY = "Quinquennially"
DECENNIALLY = "Decennially"
TRADITIONAL = "Traditional"
FIBONACCI = "Fibonacci"
WOODIE = "Woodie"
CLASSIC = "Classic"
DEMARK = "DM"
CAMARILLA = "Camarilla"
// Inputs
kind = input.string(title="Type", defval="Traditional", options=[TRADITIONAL, FIBONACCI, WOODIE, CLASSIC, DEMARK, CAMARILLA])
pivot_time_frame = input.string(title="Pivots Timeframe", defval=AUTO, options=[AUTO, DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY, BIYEARLY, TRIYEARLY, QUINQUENNIALLY, DECENNIALLY])
look_back = input.int(title="Number of Pivots Back", defval=15, minval=1, maxval=5000)
is_daily_based = input.bool(title="Use Daily-based Values", defval=true, tooltip="Uncheck to use intraday data on intraday charts.")
auto_pivots = input.bool(title="Auto Pivots", defval=true, tooltip="Only show next pivot level after the previous is breached.")
show_labels = input.bool(title="Show Labels", defval=true, inline="labels")
position_labels = input.string("Left", "", options=["Left", "Right"], inline="labels")
var DEF_COLOR = #FB8C00
var arr_time = array.new_int()
var p = array.new_float()
p_show = input.bool(true, "P ", inline="P")
p_color = input.color(DEF_COLOR, "", inline="P")
var P_R1 = array.new_float()
P_R1_show = input.bool(true, "P_R1", inline="P_R1")
P_R1_color = input.color(DEF_COLOR, "", inline="P_R1")
var R1_R2 = array.new_float()
R1_R2_show = input.bool(true, "R1_R2", inline="R1_R2")
R1_R2_color = input.color(DEF_COLOR, "", inline="R1_R2")
var R2_R3 = array.new_float()
R2_R3_show = input.bool(true, "R2_R3", inline="R2_R3")
R2_R3_color = input.color(DEF_COLOR, "", inline="R2_R3")
var R3_R4 = array.new_float()
R3_R4_show = input.bool(true, "R3_R4", inline="R3_R4")
R3_R4_color = input.color(DEF_COLOR, "", inline="R3_R4")
var R4_R5 = array.new_float()
R4_R5_show = input.bool(true, "R4_R5", inline="R4_R5")
R4_R5_color = input.color(DEF_COLOR, "", inline="R4_R5")
var P_S1 = array.new_float()
P_S1_show = input.bool(true, "P_S1", inline="P_S1")
P_S1_color = input.color(DEF_COLOR, "", inline="P_S1")
var S1_S2 = array.new_float()
S1_S2_show = input.bool(true, "S1_S2", inline="S1_S2")
S1_S2_color = input.color(DEF_COLOR, "", inline="S1_S2")
var S2_S3 = array.new_float()
S2_S3_show = input.bool(true, "S2_S3", inline="S2_S3")
S2_S3_color = input.color(DEF_COLOR, "", inline="S2_S3")
var S3_S4 = array.new_float()
S3_S4_show = input.bool(true, "S3_S4", inline="S3_S4")
S3_S4_color = input.color(DEF_COLOR, "", inline="S3_S4")
var S4_S5 = array.new_float()
S4_S5_show = input.bool(true, "S4_S5", inline="S4_S5")
S4_S5_color = input.color(DEF_COLOR, "", inline="S4_S5")
var r1 = array.new_float()
var s1 = array.new_float()
s1r1_show = input.bool(true, "S1/R1", inline="S1/R1")
s1r1_color = input.color(DEF_COLOR, "", inline="S1/R1")
var r2 = array.new_float()
var s2 = array.new_float()
s2r2_show = input.bool(true, "S2/R2", inline="S2/R2")
s2r2_color = input.color(DEF_COLOR, "", inline="S2/R2")
var r3 = array.new_float()
var s3 = array.new_float()
s3r3_show = input.bool(true, "S3/R3", inline="S3/R3")
s3r3_color = input.color(DEF_COLOR, "", inline="S3/R3")
var r4 = array.new_float()
var s4 = array.new_float()
s4r4_show = input.bool(true, "S4/R4", inline="S4/R4")
s4r4_color = input.color(DEF_COLOR, "", inline="S4/R4")
var r5 = array.new_float()
var s5 = array.new_float()
s5r5_show = input.bool(true, "S5/R5", inline="S5/R5")
s5r5_color = input.color(DEF_COLOR, "", inline="S5/R5")
// Pivot price variables
pivotX_open = float(na)
pivotX_open := nz(pivotX_open[1], open)
pivotX_high = float(na)
pivotX_high := nz(pivotX_high[1], high)
pivotX_low = float(na)
pivotX_low := nz(pivotX_low[1], low)
pivotX_prev_open = float(na)
pivotX_prev_open := nz(pivotX_prev_open[1])
pivotX_prev_high = float(na)
pivotX_prev_high := nz(pivotX_prev_high[1])
pivotX_prev_low = float(na)
pivotX_prev_low := nz(pivotX_prev_low[1])
pivotX_prev_close = float(na)
pivotX_prev_close := nz(pivotX_prev_close[1])
// Auto Pivot tracking
var pivot_highs = array.new_float()
var pivot_lows = array.new_float()
// Resolution function
get_pivot_resolution() =>
resolution = "M"
if pivot_time_frame == AUTO
if timeframe.isintraday
resolution := timeframe.multiplier <= 15 ? "D" : "W"
else if timeframe.isweekly or timeframe.ismonthly
resolution := "12M"
else if pivot_time_frame == DAILY
resolution := "D"
else if pivot_time_frame == WEEKLY
resolution := "W"
else if pivot_time_frame == MONTHLY
resolution := "M"
else if pivot_time_frame == QUARTERLY
resolution := "3M"
else if pivot_time_frame == YEARLY or pivot_time_frame == BIYEARLY or pivot_time_frame == TRIYEARLY or pivot_time_frame == QUINQUENNIALLY or pivot_time_frame == DECENNIALLY
resolution := "12M"
resolution
var lines = array.new_line()
var labels = array.new_label()
// Drawing functions
draw_line(i, pivot, col) =>
if array.size(arr_time) > 1
array.push(lines, line.new(array.get(arr_time, i), array.get(pivot, i), array.get(arr_time, i + 1), array.get(pivot, i), color=col, xloc=xloc.bar_time))
draw_label(i, y, txt, txt_color) =>
if show_labels
offset = ' '
labels_align_str = position_labels == "Left" ? txt + offset : offset + txt
x = position_labels == "Left" ? array.get(arr_time, i) : array.get(arr_time, i + 1)
array.push(labels, label.new(x=x, y=y, text=labels_align_str, textcolor=txt_color, style=label.style_label_center, color=#00000000, xloc=xloc.bar_time))
// Pivot calculations
traditional() =>
pivotX_Median = (pivotX_prev_high + pivotX_prev_low + pivotX_prev_close) / 3
array.push(p, pivotX_Median)
array.push(r1, pivotX_Median * 2 - pivotX_prev_low)
array.push(s1, pivotX_Median * 2 - pivotX_prev_high)
array.push(r2, pivotX_Median + (pivotX_prev_high - pivotX_prev_low))
array.push(s2, pivotX_Median - (pivotX_prev_high - pivotX_prev_low))
array.push(r3, pivotX_Median * 2 + (pivotX_prev_high - 2 * pivotX_prev_low))
array.push(s3, pivotX_Median * 2 - (2 * pivotX_prev_high - pivotX_prev_low))
array.push(r4, pivotX_Median * 3 + (pivotX_prev_high - 3 * pivotX_prev_low))
array.push(s4, pivotX_Median * 3 - (3 * pivotX_prev_high - pivotX_prev_low))
array.push(r5, pivotX_Median * 4 + (pivotX_prev_high - 4 * pivotX_prev_low))
array.push(s5, pivotX_Median * 4 - (4 * pivotX_prev_high - pivotX_prev_low))
array.push(P_R1, (pivotX_Median + array.get(r1, array.size(r1)-1)) / 2)
array.push(R1_R2, (array.get(r1, array.size(r1)-1) + array.get(r2, array.size(r2)-1)) / 2)
array.push(R2_R3, (array.get(r2, array.size(r2)-1) + array.get(r3, array.size(r3)-1)) / 2)
array.push(R3_R4, (array.get(r3, array.size(r3)-1) + array.get(r4, array.size(r4)-1)) / 2)
array.push(R4_R5, (array.get(r4, array.size(r4)-1) + array.get(r5, array.size(r5)-1)) / 2)
array.push(P_S1, (pivotX_Median + array.get(s1, array.size(s1)-1)) / 2)
array.push(S1_S2, (array.get(s1, array.size(s1)-1) + array.get(s2, array.size(s2)-1)) / 2)
array.push(S2_S3, (array.get(s2, array.size(s2)-1) + array.get(s3, array.size(s3)-1)) / 2)
array.push(S3_S4, (array.get(s3, array.size(s3)-1) + array.get(s4, array.size(s4)-1)) / 2)
array.push(S4_S5, (array.get(s4, array.size(s4)-1) + array.get(s5, array.size(s5)-1)) / 2)
fibonacci() =>
pivotX_Median = (pivotX_prev_high + pivotX_prev_low + pivotX_prev_close) / 3
pivot_range = pivotX_prev_high - pivotX_prev_low
array.push(p, pivotX_Median)
array.push(r1, pivotX_Median + 0.382 * pivot_range)
array.push(s1, pivotX_Median - 0.382 * pivot_range)
array.push(r2, pivotX_Median + 0.618 * pivot_range)
array.push(s2, pivotX_Median - 0.618 * pivot_range)
array.push(r3, pivotX_Median + 1 * pivot_range)
array.push(s3, pivotX_Median - 1 * pivot_range)
woodie() =>
pivotX_Woodie_Median = (pivotX_prev_high + pivotX_prev_low + pivotX_open * 2) / 4
pivot_range = pivotX_prev_high - pivotX_prev_low
array.push(p, pivotX_Woodie_Median)
array.push(r1, pivotX_Woodie_Median * 2 - pivotX_prev_low)
array.push(s1, pivotX_Woodie_Median * 2 - pivotX_prev_high)
array.push(r2, pivotX_Woodie_Median + pivot_range)
array.push(s2, pivotX_Woodie_Median - pivot_range)
array.push(r3, pivotX_prev_high + 2 * (pivotX_Woodie_Median - pivotX_prev_low))
array.push(s3, pivotX_prev_low - 2 * (pivotX_prev_high - pivotX_Woodie_Median))
array.push(r4, array.get(r3, array.size(r3)-1) + pivot_range)
array.push(s4, array.get(s3, array.size(s3)-1) - pivot_range)
classic() =>
pivotX_Median = (pivotX_prev_high + pivotX_prev_low + pivotX_prev_close) / 3
pivot_range = pivotX_prev_high - pivotX_prev_low
array.push(p, pivotX_Median)
array.push(r1, pivotX_Median * 2 - pivotX_prev_low)
array.push(s1, pivotX_Median * 2 - pivotX_prev_high)
array.push(r2, pivotX_Median + pivot_range)
array.push(s2, pivotX_Median - pivot_range)
array.push(r3, pivotX_Median + 2 * pivot_range)
array.push(s3, pivotX_Median - 2 * pivot_range)
array.push(r4, pivotX_Median + 3 * pivot_range)
array.push(s4, pivotX_Median - 3 * pivot_range)
demark() =>
pivotX_Demark_X = pivotX_prev_high + pivotX_prev_low * 2 + pivotX_prev_close
if pivotX_prev_close == pivotX_prev_open
pivotX_Demark_X := pivotX_prev_high + pivotX_prev_low + pivotX_prev_close * 2
if pivotX_prev_close > pivotX_prev_open
pivotX_Demark_X := pivotX_prev_high * 2 + pivotX_prev_low + pivotX_prev_close
array.push(p, pivotX_Demark_X / 4)
array.push(r1, pivotX_Demark_X / 2 - pivotX_prev_low)
array.push(s1, pivotX_Demark_X / 2 - pivotX_prev_high)
camarilla() =>
pivotX_Median = (pivotX_prev_high + pivotX_prev_low + pivotX_prev_close) / 3
pivot_range = pivotX_prev_high - pivotX_prev_low
array.push(p, pivotX_Median)
array.push(r1, pivotX_prev_close + pivot_range * 1.1 / 12.0)
array.push(s1, pivotX_prev_close - pivot_range * 1.1 / 12.0)
array.push(r2, pivotX_prev_close + pivot_range * 1.1 / 6.0)
array.push(s2, pivotX_prev_close - pivot_range * 1.1 / 6.0)
array.push(r3, pivotX_prev_close + pivot_range * 1.1 / 4.0)
array.push(s3, pivotX_prev_close - pivot_range * 1.1 / 4.0)
array.push(r4, pivotX_prev_close + pivot_range * 1.1 / 2.0)
array.push(s4, pivotX_prev_close - pivot_range * 1.1 / 2.0)
// Main logic
resolution = get_pivot_resolution()
[sec_open, sec_high, sec_low, sec_close] = request.security(syminfo.tickerid, resolution, [open, high, low, close], lookahead=barmerge.lookahead_on)
sec_open_gaps_on = request.security(syminfo.tickerid, resolution, open, gaps=barmerge.gaps_on, lookahead=barmerge.lookahead_on)
custom_years_divisor = switch pivot_time_frame
BIYEARLY => 2
TRIYEARLY => 3
QUINQUENNIALLY => 5
DECENNIALLY => 10
=> -1
is_change_years = false
if custom_years_divisor > 0 and ta.change(time(resolution))
is_change_years := year % custom_years_divisor == 0
var is_change = false
var uses_current_bar = timeframe.isintraday and kind == WOODIE
var change_time = int(na)
is_time_change = (ta.change(time(resolution)) and custom_years_divisor == -1) or is_change_years
if is_time_change
change_time := time
if (not uses_current_bar and is_time_change) or (uses_current_bar and not na(sec_open_gaps_on))
if is_daily_based and custom_years_divisor == -1
pivotX_prev_open := sec_open[1]
pivotX_prev_high := sec_high[1]
pivotX_prev_low := sec_low[1]
pivotX_prev_close := sec_close[1]
pivotX_open := sec_open
pivotX_high := sec_high
pivotX_low := sec_low
else
pivotX_prev_high := pivotX_high
pivotX_prev_low := pivotX_low
pivotX_prev_open := pivotX_open
pivotX_open := open
pivotX_high := high
pivotX_low := low
pivotX_prev_close := close[1]
if barstate.islast and not is_change and array.size(arr_time) > 0
array.set(arr_time, array.size(arr_time) - 1, change_time)
else
array.push(arr_time, change_time)
array.push(pivot_highs, pivotX_high)
array.push(pivot_lows, pivotX_low)
if kind == TRADITIONAL
traditional()
else if kind == FIBONACCI
fibonacci()
else if kind == WOODIE
woodie()
else if kind == CLASSIC
classic()
else if kind == DEMARK
demark()
else if kind == CAMARILLA
camarilla()
if array.size(arr_time) > look_back
array.shift(arr_time)
array.shift(pivot_highs)
array.shift(pivot_lows)
if p_show
array.shift(p)
if s1r1_show
array.shift(r1)
array.shift(s1)
if s2r2_show
array.shift(r2)
array.shift(s2)
if s3r3_show
array.shift(r3)
array.shift(s3)
if s4r4_show
array.shift(r4)
array.shift(s4)
if s5r5_show
array.shift(r5)
array.shift(s5)
if P_R1_show
array.shift(P_R1)
if R1_R2_show
array.shift(R1_R2)
if R2_R3_show
array.shift(R2_R3)
if R3_R4_show
array.shift(R3_R4)
if R4_R5_show
array.shift(R4_R5)
if P_S1_show
array.shift(P_S1)
if S1_S2_show
array.shift(S1_S2)
if S2_S3_show
array.shift(S2_S3)
if S3_S4_show
array.shift(S3_S4)
if S4_S5_show
array.shift(S4_S5)
is_change := true
else
if is_daily_based and custom_years_divisor == -1
pivotX_high := math.max(pivotX_high, sec_high)
pivotX_low := math.min(pivotX_low, sec_low)
else
pivotX_high := math.max(pivotX_high, high)
pivotX_low := math.min(pivotX_low, low)
if barstate.islast and array.size(arr_time) > 0 and is_change
is_change := false
if array.size(arr_time) > 2 and custom_years_divisor > 0
last_pivot_time = array.get(arr_time, array.size(arr_time) - 1)
prev_pivot_time = array.get(arr_time, array.size(arr_time) - 2)
estimate_pivot_time = last_pivot_time - prev_pivot_time
array.push(arr_time, last_pivot_time + estimate_pivot_time)
else
array.push(arr_time, time_close(resolution))
for i = 0 to array.size(lines) - 1
if array.size(lines) > 0
line.delete(array.shift(lines))
if array.size(labels) > 0
label.delete(array.shift(labels))
for i = 0 to array.size(arr_time) - 2
ph = array.get(pivot_highs, i)
pl = array.get(pivot_lows, i)
if p_show
draw_line(i, p, p_color)
draw_label(i, array.get(p, i), "P", p_color)
if s1r1_show
if not auto_pivots or ph > array.get(p, i)
draw_line(i, r1, s1r1_color)
draw_label(i, array.get(r1, i), "R1", s1r1_color)
if not auto_pivots or pl < array.get(p, i)
draw_line(i, s1, s1r1_color)
draw_label(i, array.get(s1, i), "S1", s1r1_color)
if s2r2_show
if not auto_pivots or ph > array.get(r1, i)
draw_line(i, r2, s2r2_color)
draw_label(i, array.get(r2, i), "R2", s2r2_color)
if not auto_pivots or pl < array.get(s1, i)
draw_line(i, s2, s2r2_color)
draw_label(i, array.get(s2, i), "S2", s2r2_color)
if s3r3_show
if not auto_pivots or ph > array.get(r2, i)
draw_line(i, r3, s3r3_color)
draw_label(i, array.get(r3, i), "R3", s3r3_color)
if not auto_pivots or pl < array.get(s2, i)
draw_line(i, s3, s3r3_color)
draw_label(i, array.get(s3, i), "S3", s3r3_color)
if s4r4_show
if not auto_pivots or ph > array.get(r3, i)
draw_line(i, r4, s4r4_color)
draw_label(i, array.get(r4, i), "R4", s4r4_color)
if not auto_pivots or pl < array.get(s3, i)
draw_line(i, s4, s4r4_color)
draw_label(i, array.get(s4, i), "S4", s4r4_color)
if s5r5_show
if not auto_pivots or ph > array.get(r4, i)
draw_line(i, r5, s5r5_color)
draw_label(i, array.get(r5, i), "R5", s5r5_color)
if not auto_pivots or pl < array.get(s4, i)
draw_line(i, s5, s5r5_color)
draw_label(i, array.get(s5, i), "S5", s5r5_color)
if P_R1_show and (not auto_pivots or ph > array.get(p, i))
draw_line(i, P_R1, P_R1_color)
draw_label(i, array.get(P_R1, i), "PR1_50%", P_R1_color)
if R1_R2_show and (not auto_pivots or ph > array.get(r1, i))
draw_line(i, R1_R2, R1_R2_color)
draw_label(i, array.get(R1_R2, i), "R1_R2_50%", R1_R2_color)
if R2_R3_show and (not auto_pivots or ph > array.get(r2, i))
draw_line(i, R2_R3, R2_R3_color)
draw_label(i, array.get(R2_R3, i), "R2_R3_50%", R2_R3_color)
if R3_R4_show and (not auto_pivots or ph > array.get(r3, i))
draw_line(i, R3_R4, R3_R4_color)
draw_label(i, array.get(R3_R4, i), "R3_R4_50%", R3_R4_color)
if R4_R5_show and (not auto_pivots or ph > array.get(r4, i))
draw_line(i, R4_R5, R4_R5_color)
draw_label(i, array.get(R4_R5, i), "R4_R5_50%", R4_R5_color)
if P_S1_show and (not auto_pivots or pl < array.get(p, i))
draw_line(i, P_S1, P_S1_color)
draw_label(i, array.get(P_S1, i), "PS1_50%", P_S1_color)
if S1_S2_show and (not auto_pivots or pl < array.get(s1, i))
draw_line(i, S1_S2, S1_S2_color)
draw_label(i, array.get(S1_S2, i), "S1_S2_50%", S1_S2_color)
if S2_S3_show and (not auto_pivots or pl < array.get(s2, i))
draw_line(i, S2_S3, S2_S3_color)
draw_label(i, array.get(S2_S3, i), "S2_S3_50%", S2_S3_color)
if S3_S4_show and (not auto_pivots or pl < array.get(s3, i))
draw_line(i, S3_S4, S3_S4_color)
draw_label(i, array.get(S3_S4, i), "S3_S4_50%", S3_S4_color)
if S4_S5_show and (not auto_pivots or pl < array.get(s4, i))
draw_line(i, S4_S5, S4_S5_color)
draw_label(i, array.get(S4_S5, i), "S4_S5_50%", S4_S5_color)
// Function to get the last value of an array
plotLast(_array) =>
var float _lastVal = na
if array.size(_array) > 0
_lastVal := array.get(_array, array.size(_array) - 1)
_lastVal
// Plot pivots on price scale (transparent)
plot(p_show ? plotLast(p) : na, title="P", color=color.new(p_color, 100))
plot(s1r1_show ? plotLast(r1) : na, title="R1", color=color.new(s1r1_color, 100))
plot(s1r1_show ? plotLast(s1) : na, title="S1", color=color.new(s1r1_color, 100))
plot(s2r2_show ? plotLast(r2) : na, title="R2", color=color.new(s2r2_color, 100))
plot(s2r2_show ? plotLast(s2) : na, title="S2", color=color.new(s2r2_color, 100))
plot(s3r3_show ? plotLast(r3) : na, title="R3", color=color.new(s3r3_color, 100))
plot(s3r3_show ? plotLast(s3) : na, title="S3", color=color.new(s3r3_color, 100))
plot(s4r4_show ? plotLast(r4) : na, title="R4", color=color.new(s4r4_color, 100))
plot(s4r4_show ? plotLast(s4) : na, title="S4", color=color.new(s4r4_color, 100))
plot(s5r5_show ? plotLast(r5) : na, title="R5", color=color.new(s5r5_color, 100))
plot(s5r5_show ? plotLast(s5) : na, title="S5", color=color.new(s5r5_color, 100))
plot(P_R1_show ? plotLast(P_R1) : na, title="P_R1", color=color.new(P_R1_color, 100))
plot(R1_R2_show ? plotLast(R1_R2) : na, title="R1_R2", color=color.new(R1_R2_color, 100))
plot(R2_R3_show ? plotLast(R2_R3) : na, title="R2_R3", color=color.new(R2_R3_color, 100))
plot(R3_R4_show ? plotLast(R3_R4) : na, title="R3_R4", color=color.new(R3_R4_color, 100))
plot(R4_R5_show ? plotLast(R4_R5) : na, title="R4_R5", color=color.new(R4_R5_color, 100))
plot(P_S1_show ? plotLast(P_S1) : na, title="P_S1", color=color.new(P_S1_color, 100))
plot(S1_S2_show ? plotLast(S1_S2) : na, title="S1_S2", color=color.new(S1_S2_color, 100))
plot(S2_S3_show ? plotLast(S2_S3) : na, title="S2_S3", color=color.new(S2_S3_color, 100))
plot(S3_S4_show ? plotLast(S3_S4) : na, title="S3_S4", color=color.new(S3_S4_color, 100))
plot(S4_S5_show ? plotLast(S4_S5) : na, title="S4_S5", color=color.new(S4_S5_color, 100))