Drawing Objects#
In addition to plot functions, Pine Script provides drawing objects that can be precisely positioned: label (text labels), line (line segments), and box (rectangles). These objects can be drawn at any position and time on the chart, making them ideal for marking specific bars or drawing pattern structures.
label — Text Label#
label.new() creates a label with text at a specified position:
label.new(x, y, text, style, color, textcolor, size)| Parameter | Description |
|---|---|
x | Horizontal position (typically bar_index) |
y | Vertical position (price) |
text | Text to display |
style | Label shape |
color | Label background color |
textcolor | Text color |
size | Text size |
//@version=6
indicator("label Demo", overlay=true)
// Show a marker above every bullish bar
if close > open
label.new(bar_index, high,
text="▲",
style=label.style_label_down,
color=color.new(color.green, 20),
textcolor=color.white,
size=size.small)label Styles#
Commonly used style options:
| Constant | Description |
|---|---|
label.style_label_up | Upward label (arrow at bottom) |
label.style_label_down | Downward label (arrow at top) |
label.style_label_left | Left-pointing label |
label.style_label_right | Right-pointing label |
label.style_label_center | Box without arrow |
label.style_circle | Circle |
label.style_diamond | Diamond |
label.style_none | Text only, no background |
Object Count Limit#
Pine Script retains at most 500 objects of each type by default (label, line, and box are counted independently). When the limit is exceeded, the oldest object is automatically deleted.
If you only need to display the most recent few objects, manage them manually:
//@version=6
indicator("Limit Label Count", overlay=true)
var labelQueue = array.new<label>()
// Create a new label on every bar
lbl = label.new(bar_index, high, str.tostring(math.round(close, 2)),
style=label.style_label_down, size=size.tiny)
array.push(labelQueue, lbl)
// Keep only the most recent 10 labels
if array.size(labelQueue) > 10
label.delete(array.shift(labelQueue))line — Line Segment#
line.new() draws a line segment connecting two points:
line.new(x1, y1, x2, y2, color, width, style, extend)//@version=6
indicator("Trend Line Demo", overlay=true)
// Draw a line connecting recent pivot highs on the last bar
if barstate.islast
// Find the two most recent pivot highs
ph1 = ta.pivothigh(high, 5, 5)
ph2 = ta.pivothigh(high, 10, 10)
if not na(ph1) and not na(ph2)
line.new(bar_index - 5, ph1,
bar_index - 10, ph2,
color=color.red, width=2,
extend=extend.right) // Extend to the rightExtend Direction#
The extend parameter controls whether the line extends beyond its endpoints:
| Constant | Description |
|---|---|
extend.none | No extension (default) |
extend.right | Extend to the right edge of the chart |
extend.left | Extend to the left edge of the chart |
extend.both | Extend in both directions |
Line Styles#
| Constant | Description |
|---|---|
line.style_solid | Solid line |
line.style_dashed | Dashed line |
line.style_dotted | Dotted line |
line.style_arrow_right | With right arrow |
box — Rectangle#
box.new() draws a rectangle, commonly used to mark patterns or supply/demand zones:
box.new(left, top, right, bottom, border_color, border_width, bgcolor)//@version=6
indicator("Box Demo", overlay=true)
// Draw a box around the previous bar's candle body
prevOpen = open[1]
prevClose = close[1]
// Only draw for the most recent bars to avoid too many objects
if bar_index > last_bar_index - 20
box.new(left=bar_index - 1, top=math.max(prevOpen, prevClose),
right=bar_index, bottom=math.min(prevOpen, prevClose),
border_color=prevClose > prevOpen ? color.green : color.red,
bgcolor=color.new(prevClose > prevOpen ? color.green : color.red, 70))Practical Example: Marking Breakout Points#
Using close breaking above the N-bar high as an example, combining label and line:
//@version=6
indicator("Breakout Markers", overlay=true)
lookback = input.int(20, "Breakout Period")
highestHigh = ta.highest(high, lookback)[1] // Previous bar's lookback high
breakout = close > highestHigh
if breakout
// Mark the breakout bar
label.new(bar_index, low,
"Breakout " + str.tostring(lookback) + "-bar high\n" +
str.tostring(math.round(close, 2)),
style=label.style_label_up,
color=color.new(color.green, 10),
textcolor=color.white,
size=size.normal)
// Draw the horizontal line that was broken
line.new(bar_index - lookback, highestHigh,
bar_index, highestHigh,
color=color.new(color.red, 30),
style=line.style_dashed)Practical Example: Statistics Label on the Last Bar#
//@version=6
indicator("Bar Statistics Label", overlay=true)
var int bullCount = 0
var int bearCount = 0
if close > open
bullCount := bullCount + 1
else
bearCount := bearCount + 1
// Only display on the last bar
if barstate.islast
total = bullCount + bearCount
bullPct = total > 0 ? bullCount / total * 100 : 0.0
label.new(bar_index + 5, high,
"Bullish: " + str.tostring(bullCount) + " (" +
str.tostring(math.round(bullPct, 1)) + "%)\n" +
"Bearish: " + str.tostring(bearCount),
style=label.style_label_left,
color=color.new(color.navy, 10),
textcolor=color.white,
size=size.normal)