pivot.pine
pivot.pine
// ===================
// User Control Settings
// ===================
enablePivotSettings = input.bool(true, title="Enable Pivot Settings")
enableStyleSettings = input.bool(true, title="Enable Style Settings")
enableLineDisplaySettings = input.bool(true, title="Enable Line Display Settings")
// ===================
// History Control Settings
// ===================
historyOptions = input.string(title="Pivot History Display", defval="90 Days",
options=["90 Days", "180 Days", "Unlimited"], tooltip="Select the amount of pivot
history to display")
// ===================
// Control the history display based on the user selection
// ===================
var int historyDays = 0
if historyOptions == "90 Days"
historyDays := 90
else if historyOptions == "180 Days"
historyDays := 180
else
historyDays := 1000000 // Large number to represent unlimited
// Get the timestamp for the current time minus the number of days selected
var int startTimestamp = timenow - historyDays * 86400 // 86400 seconds in a day
// ===================
// Pivot High/Low Settings (Conditional Display)
// ===================
var int leftLenH = 10
var int rightLenH = 10
var int leftLenL = 10
var int rightLenL = 10
if (enablePivotSettings)
group_pivots = "Pivot Settings"
leftLenH := input.int(title="Pivot High Length", defval=10, minval=1,
group=group_pivots)
rightLenH := input.int(title="Pivot Right Length High", defval=10, minval=1,
group=group_pivots)
leftLenL := input.int(title="Pivot Low Length", defval=10, minval=1,
group=group_pivots)
rightLenL := input.int(title="Pivot Right Length Low", defval=10, minval=1,
group=group_pivots)
// ===================
// Style Settings (Conditional Display)
// ===================
var color highLabelColor = color.rgb(14,200,88,80)
var color lowLabelColor = color.rgb(126,22,80,70)
var color highTextColor = color.white
var color lowTextColor = color.white
var textSize = size.normal
if (enableStyleSettings)
group_style = "Style Settings"
highLabelColor := input.color(title="High Label Color",
defval=color.rgb(14,200,88,80), group=group_style)
lowLabelColor := input.color(title="Low Label Color",
defval=color.rgb(126,22,80,70), group=group_style)
highTextColor := input.color(title="High Text Color", defval=color.white,
group=group_style)
lowTextColor := input.color(title="Low Text Color", defval=color.white,
group=group_style)
textSizeOption = input.string(title="Label Text Size", defval="Normal",
options=["Small", "Normal", "Large"], group=group_style)
textSize := textSizeOption == "Small" ? size.small : textSizeOption ==
"Large" ? size.large : size.normal
// ===================
// Line Display Settings (Conditional Display)
// ===================
var bool showContinuousLines = false
var bool showLastHighLowLines = false
if (enableLineDisplaySettings)
group_lines = "Line Display Settings"
showContinuousLines := input.bool(false, title="Show Continuous Lines",
group=group_lines)
showLastHighLowLines := input.bool(false, title="Show Last High/Low Lines",
group=group_lines)
// ===================
// Logic for pivot points and restricting display based on history
// ===================
if not na(pivotHigh)
line.set_xy2(pivotLineHigh, bar_index, high[pivotHigh])
if not na(pivotLow)
line.set_xy2(pivotLineLow, bar_index, low[pivotLow])
// ===================
// Fibonacci Settings
// ===================
group_fib = "Fibonacci Settings"
showFib = input.bool(false, title="Show Fibonacci Levels", group=group_fib)
// Update the series only when new pivot points are found
if not na(ph)
highLineSeries := ph // Set the high series value to the current pivot high
prevHigh := ph // Update the previous high value
else
highLineSeries := highLineSeries[1.8] // Carry the previous value forward to
maintain continuity
if not na(pl)
lowLineSeries := pl // Set the low series value to the current pivot low
prevLow := pl // Update the previous low value
else
lowLineSeries := lowLineSeries[1.8] // Carry the previous value forward to
maintain continuity
if not na(prevLow)
lastLowLine := line.new(x1=bar_index[rightLenL], y1=prevLow, x2=bar_index,
y2=lowLineSeries, color=color.green, width=2)
// Calculate the percentage rise from low to high and the percentage drop from high
to low
percentageRise = (not na(ph) and not na(lowLineSeries)) ?
calcPercentageRise(lowLineSeries, ph) : na
percentageDrop = (not na(pl) and not na(highLineSeries)) ?
calcPercentageDrop(highLineSeries, pl) : na
// Draw labels for high pivots with percentage rise (above the bar, right side)
if not na(ph) and not na(percentageRise)
labelTextHigh = str.format("High: {0}\nRise: {1}%", ph,
str.tostring(percentageRise, "#.00"))
label.new(bar_index[rightLenH], ph, text=labelTextHigh,
style=label.style_label_right, color=highLabelColor, textcolor=highTextColor,
size=textSize, yloc=yloc.abovebar)
// Draw labels for low pivots with percentage drop (below the bar, right side)
if not na(pl) and not na(percentageDrop)
labelTextLow = str.format("Low: {0}\nDrop: {1}%", pl,
str.tostring(percentageDrop, "#.00"))
label.new(bar_index[rightLenL], pl, text=labelTextLow,
style=label.style_label_right, color=lowLabelColor, textcolor=lowTextColor,
size=textSize, yloc=yloc.belowbar)
// fib tool
// Updated Fibonacci Levels and Colors to match the image
depthTooltip = "The minimum number of bars that will be taken into account when
calculating the indicator."
depth = input.int(title="Depth", defval=20, minval=5, inline = "Pivots",
tooltip=depthTooltip)
reverse = input(false, "Reverse", display = display.data_window)
var extendLeft = input(false, "Extend Left | Extend Right", inline = "Extend
Lines", display = display.data_window)
var extendRight = input(true, "", inline = "Extend Lines", display =
display.data_window)
var extending = extend.none
if extendLeft and extendRight
extending := extend.both
if extendLeft and not extendRight
extending := extend.left
if not extendLeft and extendRight
extending := extend.right
prices = input(false, "Show Prices", display = display.data_window)
levels = input(true, "Show Levels", inline = "Levels", display =
display.data_window)
levelsFormat = input.string("Percent", "", options = ["Values", "Percent"], inline
= "Levels", display = display.data_window)
labelsPosition = input.string("Right", "Labels Position", options = ["Left",
"Right"], display = display.data_window)
backgroundTransparency = input.int(95, "Background Transparency", minval = 0,
maxval = 100, display = display.data_window)
upperThreshold = 0.236
lowerThreshold = 1.0
import TradingView/ta/7
import TradingView/ZigZag/7 as zigzag
update()=>
var line lineLastHL = na
var line lineLastLH = na
var line lineLast = na
countPivotsH = array.size(pivotsH)
countPivotsL = array.size(pivotsL)
if not na(H)
array.push(pivotsH, H)
if not na(L)
array.push(pivotsL, L)
for i = array.size(pivots)-1 to 0
if i < 0
break
p = array.get(pivots, i)
if p.time < lastL.time
break
betterPrice = isHighLast ? p.price > lastH.price : p.price <
lastL.price
if p.price > lastH.price
lastH := array.pop(pivots)
else
array.remove(pivots, i)
if array.size(pivotsHCopy) == 0 or array.size(pivotsLCopy) == 0
break
if isHighLast
endPrice := lastL.price
diff = math.abs(startPrice - endPrice)
if lastH.price > endPrice + diff * lowerThreshold or lastH.price <
endPrice + diff * upperThreshold
array.push(pivotsLCopy, lastL)
continue
line.delete(lineLastHL)
line.delete(lineLastLH)
lineLastHL := line.new(prevPivot, lastL, color=color.red, width=1,
style=line.style_dashed, xloc = xloc.bar_time)
lineLastLH := line.new(lastL, lastH, color=color.green, width=1,
style=line.style_dashed, xloc = xloc.bar_time)
lineLast := lineLastLH
else
endPrice := lastH.price
diff = math.abs(startPrice - endPrice)
if lastL.price < endPrice - diff * lowerThreshold or lastL.price >
endPrice - diff * upperThreshold
array.push(pivotsHCopy, lastH)
continue
line.delete(lineLastHL)
line.delete(lineLastLH)
lineLastLH := line.new(prevPivot, lastH, color=color.red, width=1,
style=line.style_dashed, xloc = xloc.bar_time)
lineLastHL := line.new(lastH, lastL, color=color.green, width=1,
style=line.style_dashed, xloc = xloc.bar_time)
lineLast := lineLastHL
break
diff = (isHighLast ? -1 : 1) * math.abs(startPrice - endPrice)
offset = isHighLast ? line.get_y1(lineLastLH) - line.get_y2(lineLastLH) :
line.get_y1(lineLastHL) - line.get_y2(lineLastHL)
offset := (isHighLast ? -1 : 1) * math.abs(offset)
if barstate.islast and na(lineLast)
runtime.error("Not enough data to calculate Auto Fib Extension on the
current symbol. Change the chart's timeframe to a lower one or select a smaller
calculation depth using the indicator's `Depth` settings.")
_crossing_level(sr, r) =>
(r > sr and r < sr[1]) or (r < sr and r > sr[1])
//// ===================
// EMA Settings
// ===================
group_ema = "EMA and Smiley Settings"
// EMA Definitions
ema_def1 = input.int(20, title="EMA 1 Length", minval=1, group=group_ema)
ema_def2 = input.int(52, title="EMA 2 Length", minval=1, group=group_ema)
ema_def3 = input.int(90, title="EMA 3 Length", minval=1, group=group_ema)
ema_def4 = input.int(160, title="EMA 4 Length", minval=1, group=group_ema)
ema_def5 = input.int(210, title="EMA 5 Length", minval=1, group=group_ema)
ema_def6 = input.int(265, title="EMA 6 Length", minval=1, group=group_ema)
// EMA Calculations
ema_line1 = ta.ema(close, ema_def1)
ema_line2 = ta.ema(close, ema_def2)
ema_line3 = ta.ema(close, ema_def3)
ema_line4 = ta.ema(close, ema_def4)
ema_line5 = ta.ema(close, ema_def5)
ema_line6 = ta.ema(close, ema_def6)
// Initialize labels for each EMA length (at the last bar)
if (barstate.islast)
// Delete previous labels if they exist
var label ema_label1 = na
var label ema_label2 = na
var label ema_label3 = na
var label ema_label4 = na
var label ema_label5 = na
var label ema_label6 = na