Chart Rendering
After executing a Pine Script, call instance.chart() to obtain a Chart — the complete set of visual outputs produced by the script. This document describes the chart data model so you can render it in any frontend (Canvas, SVG, WebGL, native UI, etc.).
See Reading Outputs for the basic Rust API patterns for accessing charts and script info.
Overview
The Chart contains two categories of visuals:
| Category | Accessed via | Description |
|---|---|---|
| Series graphs | chart.series_graphs() | Per-bar data: one value per bar. Includes plot(), plotshape(), plotchar(), plotarrow(), plotcandle(), plotbar(), bgcolor(), fill(). |
| Non-series graphs | chart.graphs() | Point-in-time drawing objects created with *.new(). Includes label, line, box, table, polyline, hline, linefill. |
Series graphs are indexed by bar (index 0 = first bar). Non-series graphs are standalone objects with explicit coordinates.
Accessing the Chart
use openpine_vm::*;
// 1. Build an instance with bar data
let mut instance = Instance::builder(candlesticks, source, TimeFrame::days(1), "NASDAQ:AAPL")
.build().await?;
// 2. Run the script against all bars
instance.run_to_end("NASDAQ:AAPL", TimeFrame::days(1)).await?;
// 3. Access the chart (borrow)
let chart = instance.chart();
// Or take ownership (consumes the instance)
let chart = instance.into_chart();
// 4. Access script configuration
let info = instance.script_info();Key Chart Methods
| Method | Return Type | Description |
|---|---|---|
background_color() | Option<Color> | Chart-level background color |
series_graphs() | Iterator<(SeriesGraphId, &SeriesGraph)> | All per-bar visual series |
series_graph(id) | Option<&SeriesGraph> | Lookup a specific series graph by ID |
graphs() | Iterator<(GraphId, &Graph)> | All drawing objects |
graph(id) | Option<&Graph> | Lookup a specific drawing object by ID |
series_len() | usize | Total number of bars |
bar_colors() | &BarColors | Per-bar candlestick color overrides |
filled_orders_on_bar(i) | &[FilledOrder] | Filled orders on bar i (signal name, price, qty) |
Chart Structure
Chart
|-- background_color: Option<Color>
|-- bar_colors: BarColors
|-- filled_orders: { bar_index -> [FilledOrder] }
|
|-- series_graphs: { SeriesGraphId -> SeriesGraph }
| |-- Plot
| |-- PlotShape
| |-- PlotChar
| |-- PlotArrow
| |-- PlotBar
| |-- PlotCandle
| |-- BackgroundColors
| |-- Fill
|
|-- graphs: { GraphId -> Graph }
| |-- Hline
| |-- Label
| |-- Line
| |-- LineFill
| |-- Box
| |-- Polyline
| |-- TableScript Configuration (ScriptInfo)
Access via instance.script_info(). This tells you how the script declared itself — it controls pane layout, z-order, and value formatting. Both indicator() and strategy() share the same rendering-relevant fields.
let info = instance.script_info();
// Access rendering fields via script_type
let is_overlay = match &info.script_type {
ScriptType::Indicator(ind) => ind.overlay,
ScriptType::Strategy(strat) => strat.overlay,
ScriptType::Library(lib) => lib.overlay,
};| Field | Type | Default | Description |
|---|---|---|---|
title | String | — | Display name shown in chart legend and data window |
short_title | Option<String> | None | Abbreviated name for compact display (status line, price scale) |
overlay | bool | false | true = draw on the main price chart pane; false = draw in a separate sub-pane |
format | Format | Inherit | Number formatting for values displayed on the price scale, tooltips, data window |
precision | Option<u8> | None | Decimal places for values. None = use the symbol's default |
scale | ScaleType | None | Price scale placement: None (auto), Left, Right |
explicit_plot_zorder | bool | false | true = plots render in declaration order (first = bottom). false = default z-order |
behind_chart | bool | false | true = draw behind candlesticks instead of on top |
overlay is the most important rendering decision:
true-> Draw all visuals on the main price chart pane, sharing the price Y-axis.false-> Create a separate sub-pane below the chart with its own Y-axis.
overlay also sets the default value of force_overlay for every visual the script creates. When overlay = true, all visuals default to force_overlay = true (main pane). When overlay = false, they default to force_overlay = false (sub-pane). Pine users can override this per-visual by passing force_overlay explicitly.
format controls how numeric values are formatted on the sub-pane Y-axis and in crosshair/tooltip displays. Apply it to all sub-pane value labels:
Inherit/Price— format as a price (e.g.150.25,0.0042)Percent— append a percent sign (e.g.3.14%)Volume— abbreviate large numbers (e.g.1.5M,200K)MinTick— format using the symbol's minimum tick size (treat asPriceif tick size is unavailable)
explicit_plot_zorder controls layering:
false(default) — the renderer decides the draw ordertrue— plots are drawn in the order they appear inseries_graphs()(first = bottom layer)
Common Types
Color
A packed 32-bit RGBA value stored as u32 in 0xRRGGBBAA format.
| Method | Description |
|---|---|
red() -> u8 | Red channel (0-255) |
green() -> u8 | Green channel (0-255) |
blue() -> u8 | Blue channel (0-255) |
alpha() -> u8 | Alpha channel (0 = transparent, 255 = opaque) |
transparency() -> u8 | Inverse of alpha (0 = opaque, 100 = transparent) |
as_u32() -> u32 | Raw packed value |
To convert to CSS: rgba(color.red(), color.green(), color.blue(), color.alpha() as f64 / 255.0).
When serialized to JSON, Color appears as a plain integer (e.g., 4294901760 for red 0xFF0000FF).
Option<Color> with value None means "use the default color" or "invisible" depending on context.
Series<T>
A Series<T> is a sequential array of per-bar values, backed by a VecDeque<T>. Index 0 is the first bar, index len() - 1 is the last bar.
| Method | Description |
|---|---|
get(index) -> Option<&T> | Get value at bar index |
len() -> usize | Number of bars |
is_empty() -> bool | Whether the series is empty |
last() -> Option<&T> | Value at the last bar |
Most series are typed as Series<Option<f64>> or Series<Option<Color>>. A None entry means na (not available / no value on that bar). When rendering, skip None entries — do not draw anything for that bar.
When serialized to JSON, a Series appears as a plain array: [null, 150.0, 153.2, null, ...].
PlotDisplay (Bitflags)
Controls where a visual element is shown. This is a bitmask — multiple flags can be combined.
| Flag | Value | Description |
|---|---|---|
ALL | 0xFFFF | Show everywhere (default) |
NONE | 0x0 | Hidden — do not render anywhere |
PANE | 0x2 | Show in the chart pane (the visual plot itself) |
DATA_WINDOW | 0x1 | Show in the data window panel |
PRICE_SCALE | 0x8 | Show value on the price scale axis |
STATUS_LINE | 0x10 | Show value on the status/legend line |
Rendering rule: Only render the visual on the chart pane if display contains the PANE flag (display & 0x2 != 0). If display is NONE (0x0), skip rendering entirely.
Series Graphs (Per-Bar Data)
Iterate with chart.series_graphs(). Each entry is a (SeriesGraphId, &SeriesGraph) pair. Use pattern matching to identify the type:
for (id, sg) in chart.series_graphs() {
match sg {
SeriesGraph::Plot(plot) => { /* render plot */ }
SeriesGraph::PlotShape(shape) => { /* render shapes */ }
SeriesGraph::PlotChar(pchar) => { /* render characters */ }
SeriesGraph::PlotArrow(arrow) => { /* render arrows */ }
SeriesGraph::PlotCandle(candle) => { /* render candles */ }
SeriesGraph::PlotBar(bar) => { /* render OHLC bars */ }
SeriesGraph::BackgroundColors(bg) => { /* render bg colors */ }
SeriesGraph::Fill(fill) => { /* render fill area */ }
}
}Or use accessor methods: sg.as_plot(), sg.as_plot_shape(), etc.
Plot
The most common series graph. Produced by the Pine plot() function.
Pine example:
plot(close, "Close", color.blue, linewidth=2, style=plot.style_line)Fields:
| Field | Type | Description |
|---|---|---|
title | Option<String> | Title of the plot. Displayed in the chart legend, data window, and used as the default tooltip label. None = no title. |
series | Series<Option<f64>> | Per-bar numeric values to plot. Each entry corresponds to one bar. None = na (no point on that bar — the plot gaps or breaks depending on style and join). |
colors | Series<Option<Color>> | Per-bar color of the plot. Can change dynamically per bar (e.g., green when rising, red when falling). None = use the default color. |
line_width | i32 | Width of the line or outline in pixels. Default: 1. Applies to all styles. |
style | PlotStyle | Determines how the series data is visually rendered: as a continuous line, step line, area fill, histogram bars, columns, or point markers (circles, crosses, diamonds). See the PlotStyle enum for all options. |
line_style | PlotLineStyle | Stroke pattern for line-based styles: Solid, Dashed, or Dotted. Only applies to Line, LineBr, StepLine, StepLineBr styles. |
track_price | bool | If true, a horizontal dashed line extends from the last plotted value to the right edge of the chart, and the value is shown on the price scale. Useful for highlighting the current indicator value. |
histbase | f64 | The reference/baseline value for Histogram, Area, AreaBr, and Columns styles. These styles fill the area between the series value and histbase. Default: 0.0. For example, with histbase = 50.0, a histogram bar at value 80 draws upward from 50 to 80, and a bar at value 30 draws downward from 50 to 30. |
offset | i32 | Shifts the entire plot left or right by the given number of bars. Positive values shift right (into the future), negative values shift left (into the past). Default: 0. The renderer should draw the value at bar_index + offset instead of bar_index. |
join | bool | Controls gap handling for Line, StepLine, and Area styles. If true, consecutive non-na points are connected even if there are na values between them (the gap is bridged). If false, the line breaks at na values. The *Br styles (LineBr, StepLineBr, AreaBr) always break at na regardless of this setting. |
show_last | Option<usize> | If set, only the last N bars of the plot are rendered. All earlier bars are hidden. Useful for limiting visual clutter. None = show all bars. |
display | PlotDisplay | Bitflag controlling where the plot is visible: on the chart pane, data window, price scale, status line, or all/none. Only render on the chart if the PANE flag is set. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting (see ScriptInfo). Can be overridden per plot() call via the force_overlay parameter. |
Rendering logic:
for bar_index in 0..chart.series_len():
value = plot.series[bar_index] // Option<f64>
color = plot.colors[bar_index] // Option<Color>
if value is None:
if style is Line/StepLine/Area and join is true:
// skip but connect to next valid point
else:
// break the line / skip the bar
continue
actual_bar = bar_index + plot.offset
y = value_to_pixel(value)
x = bar_to_pixel(actual_bar)
match plot.style:
Line/LineBr -> draw line segment to (x, y)
StepLine/... -> draw horizontal then vertical to (x, y)
Area/AreaBr -> fill between y and histbase
Histogram -> draw thin vertical bar from histbase to y
Columns -> draw wide vertical bar from histbase to y
Circles -> draw circle at (x, y)
Cross -> draw + at (x, y)
Diamond -> draw diamond at (x, y)PlotShape
Renders shape glyphs on the chart. Produced by the Pine plotshape() function.
Pine example:
plotshape(close > open, style=shape.triangleup, location=location.belowbar, color=color.green)Fields:
| Field | Type | Description |
|---|---|---|
title | String | Title of the plot, displayed in the chart legend and data window. |
series | (private) | Per-bar values determining whether a shape is drawn. Access via bool_value(i) (returns Some(true) if the shape should appear on bar i) or float_value(i) (the raw numeric value). When location is Absolute, the float value is used as the Y coordinate. |
style | Shape | The type of shape glyph to draw (e.g., triangle, arrow, circle, cross, diamond, flag, label, square, x-cross). |
location | Location | Controls the vertical placement of the shape. AboveBar / BelowBar place the shape at a fixed offset above/below the bar's high/low. Top / Bottom anchor the shape to the top/bottom of the pane. Absolute uses the series float value as the exact Y price coordinate. |
colors | Series<Option<Color>> | Per-bar color of the shape. Can be a constant or change dynamically per bar (e.g., green for bullish signals, red for bearish). |
offset | i32 | Shifts shapes left (negative) or right (positive) by the given number of bars. Default: 0. |
text | Option<String> | Optional text displayed alongside the shape. Supports multiline text via \n. Rendered near the shape position. |
text_colors | Series<Option<Color>> | Per-bar color of the text. Independent of the shape color. |
size | Size | Controls the visual size of the shape on the chart: Auto, Tiny, Small, Normal, Large, Huge. |
show_last | Option<usize> | If set, only draw shapes on the last N bars (counting backwards from the most recent bar). |
display | PlotDisplay | Bitflag controlling visibility. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Access methods:
bool_value(bar_index) -> Option<bool>— returnstrueif the value is non-zero (shape should be drawn),falseif zero,Noneif na.float_value(bar_index) -> Option<f64>— returns the raw float value.
Rendering logic:
for bar_index in 0..chart.series_len():
show = plotshape.bool_value(bar_index) // Option<bool>
if show is None or show == false:
continue
x = bar_to_pixel(bar_index + offset)
y = match location:
AboveBar -> bar_high_pixel - margin
BelowBar -> bar_low_pixel + margin
Absolute -> value_to_pixel(plotshape.float_value(bar_index))
Top -> pane_top
Bottom -> pane_bottom
draw_shape(style, x, y, size, colors[bar_index])
if text is not None:
draw_text(text, x, y, text_colors[bar_index])PlotChar
Similar to PlotShape but renders a single character. Produced by the Pine plotchar() function.
Pine example:
plotchar(crossover, char='*', location=location.abovebar, color=color.yellow)Fields:
| Field | Type | Description |
|---|---|---|
title | String | Title of the plot, displayed in the chart legend and data window. |
series | (private) | Per-bar values. Access via bool_value(i) / float_value(i). Same behavior as PlotShape: when location is Absolute, the float value determines Y position; otherwise, boolean determines whether the character appears. |
char | char | Any single Unicode character to use as the visual marker (e.g., '*', '✓', '❄'). |
location | Location | Vertical positioning. Same as PlotShape: AboveBar, BelowBar, Top, Bottom, or Absolute. |
colors | Series<Option<Color>> | Per-bar color of the character. |
offset | i32 | Shifts characters left or right by the given number of bars. Default: 0. |
text | Option<String> | Optional additional text displayed near the character. Supports \n for multiline. |
text_colors | Series<Option<Color>> | Per-bar color of the additional text. |
size | Size | Size of the character on the chart: Auto, Tiny, Small, Normal, Large, Huge. |
show_last | Option<usize> | If set, only draw on the last N bars. |
display | PlotDisplay | Bitflag controlling visibility. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Rendering is identical to PlotShape, except you draw the char character instead of a shape glyph.
PlotArrow
Renders directional arrows. Produced by the Pine plotarrow() function. The arrow direction is determined by the sign of the value.
Pine example:
plotarrow(close - open, colorup=color.green, colordown=color.red)Fields:
| Field | Type | Description |
|---|---|---|
title | String | Title of the plot, displayed in the chart legend and data window. |
series | Series<Option<f64>> | Per-bar numeric values that determine arrow direction and relative height. Positive values draw an up arrow above the bar; negative values draw a down arrow below the bar. None (na) = no arrow is drawn on that bar. The absolute value determines the arrow's height relative to other arrows in the series — larger absolute values produce taller arrows. |
up_colors | Series<Option<Color>> | Per-bar color for upward arrows (drawn when the series value is positive). Can change dynamically per bar. None = use the default color. |
down_colors | Series<Option<Color>> | Per-bar color for downward arrows (drawn when the series value is negative). Can change dynamically per bar. None = use the default color. |
offset | i32 | Shifts arrows left (negative) or right (positive) by the given number of bars. Default: 0. The renderer should draw the arrow at bar_index + offset instead of bar_index. |
min_height | usize | Minimum possible arrow height in pixels. The smallest absolute value in the series maps to this height. Default: 5. |
max_height | usize | Maximum possible arrow height in pixels. The largest absolute value in the series maps to this height. Default: 100. Arrow heights are linearly interpolated between min_height and max_height based on the ratio of the bar's absolute value to the maximum absolute value across the entire series. |
show_last | Option<usize> | If set, only draw arrows on the last N bars (counting backwards from the most recent bar). All earlier bars are hidden. None = show all bars. |
display | PlotDisplay | Bitflag controlling where the arrow data is visible: on the chart pane, data window, price scale, status line, or all/none. Only render on the chart if the PANE flag is set. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Rendering logic:
for bar_index in 0..chart.series_len():
value = series[bar_index]
if value is None:
continue
x = bar_to_pixel(bar_index + offset)
if value > 0:
// Up arrow: draw above the bar
color = up_colors[bar_index]
height = scale(abs(value), min_height, max_height)
draw_up_arrow(x, bar_high - margin, height, color)
else:
// Down arrow: draw below the bar
color = down_colors[bar_index]
height = scale(abs(value), min_height, max_height)
draw_down_arrow(x, bar_low + margin, height, color)The arrow height scales proportionally between min_height and max_height based on the absolute value relative to the maximum absolute value in the series.
PlotCandle
Renders OHLC candles. Produced by the Pine plotcandle() function. Used to draw custom candlestick overlays (e.g., Heikin Ashi).
Pine example:
plotcandle(haOpen, haHigh, haLow, haClose, title="Heikin Ashi", color=haClose >= haOpen ? color.green : color.red)Fields:
| Field | Type | Description |
|---|---|---|
title | String | Title of the plot, displayed in the chart legend and data window. |
series | Series<Option<Bar>> | Per-bar OHLC data (open, high, low, close). Each entry is a Bar struct. None = no candle is drawn on that bar. If any of the four OHLC values is NaN, the bar should not be drawn. The maximum of the four values is used as the high, and the minimum as the low, regardless of which field they come from. |
colors | Series<Option<Color>> | Per-bar color for the candle body (the rectangle between open and close). Can change dynamically per bar — typically green/bullish when close >= open, red/bearish otherwise. None = use the default color. |
wick_colors | Series<Option<Color>> | Per-bar color for the candle wicks (the thin vertical lines extending from the body to the high and low). None = use the default wick color (often the same as the body or border color). |
border_colors | Series<Option<Color>> | Per-bar color for the candle body outline/border. Drawn as a stroke around the body rectangle. None = use the default border color. |
show_last | Option<usize> | If set, only draw candles on the last N bars (counting backwards from the most recent bar). All earlier bars are hidden. None = show all bars. |
display | PlotDisplay | Bitflag controlling where the candle data is visible: on the chart pane, data window, price scale, status line, or all/none. Only render on the chart if the PANE flag is set. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Bar struct (OHLC data):
| Field | Type | Description |
|---|---|---|
open | f64 | Open price |
high | f64 | High price |
low | f64 | Low price |
close | f64 | Close price |
Rendering:
For each bar with a non-None OHLC value:
- Draw the wick (vertical line from
lowtohigh) usingwick_colors. - Draw the body (rectangle from
opentoclose) filled withcolors. - Draw the body border using
border_colors. - If
close >= openthe candle is bullish; otherwise bearish. Colors are already set per-bar by the script.
PlotBar
Renders OHLC bars (thin lines, not candles). Produced by the Pine plotbar() function.
Fields:
| Field | Type | Description |
|---|---|---|
title | String | Title of the plot, displayed in the chart legend and data window. |
series | Series<Option<Bar>> | Per-bar OHLC data (open, high, low, close). Each entry is a Bar struct. None = no OHLC bar is drawn on that bar. If any of the four values is NaN, the bar should not be drawn. The maximum of the four values is used as the high, and the minimum as the low. |
colors | Series<Option<Color>> | Per-bar color applied to the entire OHLC bar (the vertical line, open tick, and close tick are all drawn in this color). Can change dynamically per bar. None = use the default color. |
show_last | Option<usize> | If set, only draw OHLC bars on the last N bars (counting backwards from the most recent bar). All earlier bars are hidden. None = show all bars. |
display | PlotDisplay | Bitflag controlling where the bar data is visible: on the chart pane, data window, price scale, status line, or all/none. Only render on the chart if the PANE flag is set. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Rendering:
For each bar: draw a vertical line from low to high, a left tick at open, and a right tick at close. All use the same color from colors[bar_index].
BackgroundColor (bgcolor)
Fills the chart background with per-bar colors. Produced by the Pine bgcolor() function.
Pine example:
bgcolor(close > open ? color.new(color.green, 90) : color.new(color.red, 90))Fields:
| Field | Type | Description |
|---|---|---|
colors | Series<Option<Color>> | Per-bar background color. Each entry fills the entire vertical strip for that bar (from the top of the pane to the bottom) with the specified color. Typically uses semi-transparent colors (high alpha/transparency) to tint the background without obscuring the chart data. None = transparent / no fill on that bar. |
offset | i32 | Shifts the background color series left (negative) or right (positive) by the given number of bars. Default: 0. The renderer should apply the color at bar_index + offset instead of bar_index. |
title | Option<String> | Title displayed in the chart legend and data window. None = no title. |
show_last | Option<usize> | If set, only apply background color to the last N bars (counting backwards from the most recent bar). All earlier bars are left unfilled. None = apply to all bars. |
display | PlotDisplay | Bitflag controlling where the bgcolor data is visible: on the chart pane, data window, price scale, status line, or all/none. Only render on the chart if the PANE flag is set. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Rendering:
For each bar: if colors[bar_index] is not None, fill the vertical strip for that bar (from pane top to pane bottom) with the specified color. These are typically semi-transparent.
Fill
Fills the area between two anchors (two plots or two hlines). Produced by the Pine fill() function.
Pine example:
p1 = plot(sma(close, 10))
p2 = plot(sma(close, 20))
fill(p1, p2, color=color.new(color.blue, 80))Fields:
| Field | Type | Description |
|---|---|---|
from | FillAnchor | First boundary of the filled area. References either a Plot series graph (by SeriesGraphId) or an Hline graph (by GraphId). Both anchors must be the same type — you cannot mix a Plot and an Hline. |
to | FillAnchor | Second boundary of the filled area. Same anchor type as from. The fill is drawn between the Y values of from and to on each bar. |
colors | Series<Option<FillColor>> | Per-bar fill color or gradient. Each entry can be Solid(Color) for a uniform fill, or Gradient(Gradient) for a vertical gradient that interpolates between two colors based on Y position. None = no fill on that bar. Can change dynamically per bar. |
title | Option<String> | Title displayed in the chart legend and data window. None = no title. |
show_last | Option<usize> | If set, only fill the last N bars (counting backwards from the most recent bar). All earlier bars are left unfilled. None = fill all bars. |
fillgaps | bool | Controls behavior when one of the anchors has an na (missing) value on a bar. If true, the last known value of the missing anchor is used, so the fill continues across the gap. If false, the fill is interrupted on bars where either anchor is na. |
display | PlotDisplay | Bitflag controlling where the fill data is visible: on the chart pane, data window, price scale, status line, or all/none. Only render on the chart if the PANE flag is set. See PlotDisplay. |
Gradient struct (used by FillColor::Gradient):
| Field | Type | Description |
|---|---|---|
top_value | f64 | The Y-axis price value at which color1 applies at full intensity. Points at or above this value are rendered entirely in color1. |
bottom_value | f64 | The Y-axis price value at which color2 applies at full intensity. Points at or below this value are rendered entirely in color2. |
color1 | Color | Color applied at top_value. The gradient linearly interpolates from color1 to color2 between the two values. |
color2 | Color | Color applied at bottom_value. |
Rendering logic:
// Resolve anchor Y values
for bar_index in 0..chart.series_len():
y1 = resolve_anchor(fill.from, bar_index) // f64 or None
y2 = resolve_anchor(fill.to, bar_index) // f64 or None
if y1 is None or y2 is None:
if fillgaps: use last known values
else: skip this bar
fill_color = fill.colors[bar_index]
if fill_color is None:
continue
match fill_color:
Solid(color) -> fill_rect(x, min(y1,y2), bar_width, abs(y1-y2), color)
Gradient(g) -> fill_gradient(x, y1, y2, g.color1, g.color2, g.top_value, g.bottom_value)To resolve an anchor:
FillAnchor::Plot(id)->chart.series_graph(id)?.as_plot()?.series[bar_index]FillAnchor::Hline(id)->chart.graph(id)?.as_hline()?.value(constant for all bars)
Non-Series Graphs (Drawing Objects)
Iterate with chart.graphs(). Each entry is a (GraphId, &Graph) pair. These are point-in-time objects — they are not indexed by bar. They have explicit coordinates.
for (id, graph) in chart.graphs() {
match graph {
Graph::Hline(h) => { /* render horizontal line */ }
Graph::Label(l) => { /* render label */ }
Graph::Line(l) => { /* render line */ }
Graph::LineFill(lf) => { /* render line fill */ }
Graph::Box(b) => { /* render box */ }
Graph::Polyline(p) => { /* render polyline */ }
Graph::Table(t) => { /* render table */ }
}
}Or use accessor methods: graph.as_hline(), graph.as_label(), etc.
Hline
A horizontal line at a fixed price level. Produced by the Pine hline() function.
Pine example:
hline(70, "Overbought", color=color.red, linestyle=hline.style_dashed)Fields:
| Field | Type | Description |
|---|---|---|
value | f64 | The fixed Y-axis value at which the horizontal line is drawn. The line extends across the entire pane width at this value. Must be a constant (not per-bar). |
color | Option<Color> | Color of the horizontal line. Must be a constant. None = use the default color. |
title | Option<String> | Title displayed in the chart legend and data window. None = no title. |
line_style | HlineStyle | Stroke pattern for the horizontal line: Solid, Dashed, or Dotted. See HlineStyle. |
line_width | i32 | Width of the horizontal line in pixels. Default: 1. |
display | PlotDisplay | Bitflag controlling where the hline is visible. Note: hlines use a simplified display that only supports display.none and display.all. See PlotDisplay. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting — hline has no Pine-level force_overlay parameter. |
Rendering: Determine the target pane and its value range from force_overlay (same logic as other visuals). Draw a horizontal line across the full width of that pane at the pixel Y corresponding to value.
Label
A positioned text annotation with an optional background shape. Produced by label.new() in Pine Script.
Pine example:
label.new(bar_index, high, "Buy Signal", style=label.style_label_down, color=color.green)Fields:
| Field | Type | Description |
|---|---|---|
x | i64 | X coordinate of the label's anchor point. Interpretation depends on xloc: when XLocation::Index, this is a 0-based bar index; when XLocation::Time, this is a Unix timestamp in milliseconds. |
y | f64 | Y coordinate of the label's anchor point (price value). When yloc is AboveBar or BelowBar, this value is ignored and the label is positioned relative to the bar's high/low at the given X. |
text | String | Text content displayed inside the label. Supports multiline text via \n. |
xloc | XLocation | X-axis coordinate system. Index = bar index (default), Time = Unix timestamp in milliseconds. Determines how x is interpreted. |
yloc | YLocation | Y-axis positioning mode. Price (default) = use y as the exact price coordinate. AboveBar = position above the bar's high at the given X. BelowBar = position below the bar's low at the given X. |
color | Option<Color> | Background fill color of the label shape. The visual shape is determined by style. None = transparent background. |
style | LabelStyle | Controls the visual shape of the label background: directional bubbles (up, down, left, right), arrows, geometric shapes (circle, diamond, square, triangle), or text-only (None). See LabelStyle. |
text_color | Option<Color> | Color of the text inside the label. None = use the default text color. |
size | u32 | Font size of the text in points. |
text_align | HorizontalAlign | Horizontal alignment of the text within the label area: Left, Center, or Right. Only meaningful for multiline text or labels wider than their text. |
tooltip | Option<String> | Text shown in a tooltip popup when the user hovers over the label. None = no tooltip. Supports multiline text via \n. |
text_font_family | FontFamily | Font family for the label text: Default (proportional) or Monospace. |
text_formatting | TextFormatting | Text style: None (regular), Bold, or Italic. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Line
A line segment between two points. Produced by line.new() in Pine Script.
Pine example:
line.new(bar_index[10], high[10], bar_index, high, color=color.blue, width=2)Fields:
| Field | Type | Description |
|---|---|---|
x1 | i64 | X coordinate of the line's start point. Interpretation depends on xloc: bar index or Unix timestamp in milliseconds. |
y1 | f64 | Y coordinate (price) of the line's start point. |
x2 | i64 | X coordinate of the line's end point. Same coordinate system as x1. |
y2 | f64 | Y coordinate (price) of the line's end point. |
xloc | XLocation | X-axis coordinate system. Index = bar index (default), Time = Unix timestamp in milliseconds. Applies to both x1 and x2. |
extend | Extend | Controls whether the line extends beyond its defined endpoints. None (default) = draw only between (x1,y1) and (x2,y2). Left = extend infinitely to the left past (x1,y1). Right = extend infinitely to the right past (x2,y2). Both = extend in both directions. The extension follows the slope of the line. |
color | Option<Color> | Stroke color of the line. None = use the default color. |
style | LineStyle | Stroke pattern: Solid, Dashed, Dotted, or arrow styles (ArrowLeft, ArrowRight, ArrowBoth) that add arrowheads at the endpoints. See LineStyle. |
width | i32 | Width of the line stroke in pixels. Default: 1. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
LineFill
Fills the area between two Line objects. Produced by linefill.new() in Pine Script.
Fields:
| Field | Type | Description |
|---|---|---|
line1 | GraphId | ID of the first Line drawing object. Resolve via chart.graph(line1) to get the line's endpoints. Both lines must exist and be valid for the fill to render. |
line2 | GraphId | ID of the second Line drawing object. Resolve via chart.graph(line2). The fill is drawn in the region between the two lines. |
color | Option<Color> | Fill color for the region between the two lines. Typically semi-transparent. None = transparent (no fill rendered). |
Rendering: Resolve both lines by their GraphId, then fill the polygon/region formed between them. The filled area is bounded by the two line segments (or their extensions if extend is set on either line). If either line is deleted or missing, the fill should not render.
Box
An axis-aligned rectangle with optional text. Produced by box.new() in Pine Script.
Pine example:
box.new(bar_index - 10, high, bar_index, low, bgcolor=color.new(color.blue, 80))Fields:
| Field | Type | Description |
|---|---|---|
left | i64 | X coordinate of the left edge. Interpretation depends on xloc: bar index or Unix timestamp in milliseconds. |
top | f64 | Y coordinate of the top edge (higher price value). |
right | i64 | X coordinate of the right edge. Same coordinate system as left. |
bottom | f64 | Y coordinate of the bottom edge (lower price value). |
border_color | Option<Color> | Stroke color of the box border. None = no border drawn. |
border_width | i32 | Width of the box border in pixels. Default: 1. Set to 0 for no border. |
border_style | LineStyle | Stroke pattern for the box border: Solid, Dashed, or Dotted. Arrow styles are not typically used for boxes. See LineStyle. |
extend | Extend | Controls whether the box extends beyond its left/right edges. None (default) = draw only between left and right. Left = extend the left edge to the beginning of the chart. Right = extend the right edge to the end of the chart. Both = extend in both directions. The top and bottom Y values are preserved. |
xloc | XLocation | X-axis coordinate system for left and right. Index = bar index (default), Time = Unix timestamp in milliseconds. |
background_color | Option<Color> | Interior fill color of the box. Typically semi-transparent. None = transparent (no fill). |
text | String | Text displayed inside the box, positioned according to text_halign and text_valign. Empty string = no text. Supports multiline text via \n. |
text_size | u32 | Font size of the text in points. |
text_color | Option<Color> | Color of the text inside the box. None = use the default text color. |
text_halign | HorizontalAlign | Horizontal alignment of the text within the box: Left, Center (default), or Right. |
text_valign | VerticalAlign | Vertical alignment of the text within the box: Top, Middle (default), or Bottom. |
text_wrap | TextWrap | Text wrapping behavior: Auto = wrap text to fit within the box width, None = no wrapping (text may overflow). |
text_font_family | FontFamily | Font family for the text: Default (proportional) or Monospace. |
text_formatting | TextFormatting | Text style: None (regular), Bold, or Italic. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Polyline
A connected series of line segments (optionally closed and/or curved). Produced by polyline.new() in Pine Script.
Fields:
| Field | Type | Description |
|---|---|---|
points | Vec<(i64, f64)> | Ordered list of (x, y) vertices that define the polyline path. X values are bar indices, Y values are price levels. Points are connected in order. An empty list means nothing is drawn. |
curved | bool | Controls the interpolation between points. true = render as a smooth curve through the points (using cubic spline or Bezier interpolation). false = connect points with straight line segments. |
closed | bool | Controls whether the path forms a closed shape. true = connect the last point back to the first point, forming a polygon. false = leave the path open (first and last points are not connected). |
line_color | Option<Color> | Stroke color of the polyline path. None = no stroke drawn. |
fill_color | Option<Color> | Interior fill color. Only meaningful when closed is true — fills the interior of the closed polygon. When closed is false, this is ignored. None = no fill. Typically semi-transparent. |
line_style | LineStyle | Stroke pattern for the polyline: Solid, Dashed, or Dotted. See LineStyle. |
line_width | i32 | Width of the polyline stroke in pixels. Default: 1. |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Rendering:
- Convert all
(x, y)points to pixel coordinates. - If
curved: use cubic spline or Bezier interpolation. - If
closed: connect the last point to the first. - Stroke the path with
line_color,line_style,line_width. - If
fill_coloris set andclosed: fill the interior.
Table
A cell grid anchored to a fixed position on the chart. Produced by table.new() in Pine Script.
Pine example:
var t = table.new(position.top_right, 2, 3)
table.cell(t, 0, 0, "Header", text_color=color.white, bgcolor=color.blue)Fields:
| Field | Type | Description |
|---|---|---|
position | Position | Anchor position on the chart where the table is placed. The table is rendered as a floating overlay at one of 9 positions (e.g., TopRight, BottomCenter, MiddleLeft). The table does not scroll with the chart — it stays fixed at the specified position. See Position. |
background_color | Option<Color> | Background color of the entire table. Applied behind all cells. None = transparent. |
frame_color | Option<Color> | Color of the outer frame (border around the entire table). None = no outer frame. |
frame_width | i32 | Width of the outer frame in pixels. Default: 0 (no frame). |
border_color | Option<Color> | Default border color for the grid lines between cells. None = no cell borders. |
border_width | i32 | Default width of the cell borders in pixels. Default: 0 (no cell borders). |
force_overlay | bool | If true, draw on the main price pane. If false, draw in the sub-pane. Defaults to the script's overlay setting. |
Methods:
| Method | Return Type | Description |
|---|---|---|
num_columns() | usize | Number of columns |
num_rows() | usize | Number of rows |
cell(row, col) | &TableCell | Access a cell (panics if out of bounds) |
cell_opt(row, col) | Option<&TableCell> | Access a cell (returns None if out of bounds) |
TableCell fields:
| Field | Type | Description |
|---|---|---|
text | String | Text content displayed inside the cell. Supports multiline text via \n. Empty string = no text. |
width | f32 | Cell width as a percentage of the chart's available width. 0.0 = auto-size based on content. Values are percentages (e.g., 25.0 = 25% of the chart width). |
height | f32 | Cell height as a percentage of the chart's available height. 0.0 = auto-size based on content. |
text_color | Option<Color> | Color of the text inside the cell. None = use the default text color. |
text_halign | HorizontalAlign | Horizontal alignment of the text within the cell: Left, Center (default), or Right. |
text_valign | VerticalAlign | Vertical alignment of the text within the cell: Top, Middle (default), or Bottom. |
text_size | u32 | Font size of the text in points. |
background_color | Option<Color> | Background color of this individual cell. Overrides the table-level background_color. None = inherit from the table. |
tooltip | Option<String> | Text shown in a tooltip popup when the user hovers over the cell. None = no tooltip. |
text_font_family | FontFamily | Font family for the cell text: Default (proportional) or Monospace. |
text_formatting | TextFormatting | Text style: None (regular), Bold, or Italic. |
colspan | usize | Number of columns this cell spans. Default: 1. A value greater than 1 merges this cell with adjacent cells to the right. |
rowspan | usize | Number of rows this cell spans. Default: 1. A value greater than 1 merges this cell with adjacent cells below. |
Bar Colors
Access via chart.bar_colors(). This controls per-bar color overrides for the main candlestick/bar chart. Produced by the Pine barcolor() function.
Pine example:
barcolor(close > open ? color.green : color.red)Fields:
| Field | Type | Description |
|---|---|---|
colors | Series<Option<Color>> | Per-bar color override for the main candlestick/bar chart. When set, the entire candle or bar (body, wick, border) is drawn in this color, overriding the default bullish/bearish coloring. None = no override on that bar (use the chart's default coloring). |
offset | i32 | Shifts the color series left (negative) or right (positive) by the given number of bars. Default: 0. The renderer should apply the color override at bar_index + offset instead of bar_index. |
show_last | Option<usize> | If set, only apply the color override to the last N bars (counting backwards from the most recent bar). All earlier bars use the default coloring. None = apply to all bars. |
title | Option<String> | Title displayed in the chart legend and data window. None = no title. |
display | PlotDisplay | Bitflag controlling where the barcolor data is visible: on the chart pane, data window, price scale, status line, or all/none. Only apply the color override if the PANE flag is set. See PlotDisplay. |
Rendering: When drawing the main OHLC candles/bars, check bar_colors.colors[bar_index]. If it is Some(color), use that color instead of the default bullish/bearish coloring.
Filled Orders (Strategy)
For strategy scripts, chart.filled_orders_on_bar(bar_index) returns the list of filled orders on a given bar. Each entry is a FilledOrder (signal/order id, price, signed quantity).
FilledOrder fields:
| Field | Type | Description |
|---|---|---|
order_id | String | Signal name (entry/exit id) from strategy.entry(), strategy.exit(), or strategy.order(). Shown next to the fill on the chart (TradingView-style). |
price | f64 | The price at which the order was filled. Used as the Y coordinate when rendering the fill marker on the chart. |
quantity | f64 | The quantity (number of contracts/shares) filled in this execution. Positive = buy, negative = sell. Use the sign to determine the marker direction (e.g., up arrow for buys, down arrow for sells). |
Renderers should draw each fill with its signal name (order_id) and signed quantity: buys above the bar, sells below; multiple fills on the same bar stacked. Sum quantity from the list if a total per bar is needed.
Enum Reference
ScriptInfo Enums
Format — number formatting for sub-pane Y-axis labels and crosshair/tooltip values:
| Variant | Description | Example output |
|---|---|---|
Inherit | Use the chart's default formatting (default) | 150.25 |
Price | Format as a price | 150.25 |
Volume | Format with volume abbreviations | 1.5M, 200K |
Percent | Format as a percentage | 3.14% |
MinTick | Format using the symbol's minimum tick size | (treat as Price if tick unavailable) |
Apply format to all sub-pane axis labels and tooltip values. The main price axis (candlestick pane) always uses price formatting regardless of this field.
ScaleType — price scale placement:
| Variant | Description |
|---|---|
None | Auto / no dedicated scale (default) |
Left | Show on the left scale |
Right | Show on the right scale |
Plot Enums
PlotStyle — rendering style for Plot:
| Variant | Description |
|---|---|
Line | Connect points with straight line segments (default) |
LineBr | Like Line, but breaks at na values |
StepLine | Step/staircase line (horizontal then vertical) |
StepLineBr | Like StepLine, but breaks at na values |
Area | Filled area between the line and histbase |
AreaBr | Like Area, but breaks at na values |
Histogram | Thin vertical bars from histbase to value |
Columns | Wide vertical bars from histbase to value |
Circles | Circle marker at each point |
Cross | Cross (+) marker at each point |
Diamond | Diamond marker at each point |
PlotLineStyle — stroke pattern for line-based plots:
| Variant | Description |
|---|---|
Solid | Solid stroke (default) |
Dashed | Dashed stroke |
Dotted | Dotted stroke |
HlineStyle — stroke pattern for horizontal lines:
| Variant | Description |
|---|---|
Solid | Solid stroke |
Dashed | Dashed stroke |
Dotted | Dotted stroke |
Shape / Marker Enums
Shape — glyph type for PlotShape:
| Variant | Visual |
|---|---|
XCross | X mark (default) |
Cross | + mark |
Circle | Circle |
Square | Square |
Diamond | Diamond |
TriangleUp | Upward triangle |
TriangleDown | Downward triangle |
ArrowUp | Upward arrow |
ArrowDown | Downward arrow |
Flag | Flag |
LabelUp | Label pointing up |
LabelDown | Label pointing down |
Location — vertical positioning for PlotShape / PlotChar:
| Variant | Description |
|---|---|
AboveBar | Fixed offset above the bar's high (default) |
BelowBar | Fixed offset below the bar's low |
Absolute | Use the series value as the Y coordinate |
Top | At the top of the pane |
Bottom | At the bottom of the pane |
Size — size for shapes and characters:
| Variant | Description |
|---|---|
Auto | Automatic sizing (default) |
Tiny | Extra small |
Small | Small |
Normal | Standard size |
Large | Large |
Huge | Extra large |
Drawing Enums
LineStyle — stroke style for Line, Box border, Polyline:
| Variant | Description |
|---|---|
Solid | Solid stroke (default) |
Dashed | Dashed stroke |
Dotted | Dotted stroke |
ArrowLeft | Line with a left-pointing arrowhead |
ArrowRight | Line with a right-pointing arrowhead |
ArrowBoth | Line with arrowheads on both ends |
Extend — line/box extension mode:
| Variant | Description |
|---|---|
None | No extension (default) |
Left | Extend infinitely to the left |
Right | Extend infinitely to the right |
Both | Extend infinitely in both directions |
LabelStyle — shape style for Label:
| Variant | Description |
|---|---|
None | Text only, no background shape |
LabelDown | Downward-pointing label bubble (default) |
LabelUp | Upward-pointing label bubble |
LabelLeft | Left-pointing label bubble |
LabelRight | Right-pointing label bubble |
LabelCenter | Centered label bubble |
LabelLowerLeft | Lower-left label bubble |
LabelLowerRight | Lower-right label bubble |
LabelUpperLeft | Upper-left label bubble |
LabelUpperRight | Upper-right label bubble |
ArrowDown | Downward arrow |
ArrowUp | Upward arrow |
Circle | Circle shape |
Cross | Cross (+) shape |
Diamond | Diamond shape |
Square | Square shape |
Flag | Flag shape |
TriangleDown | Downward triangle |
TriangleUp | Upward triangle |
XCross | X-cross shape |
TextOutline | Text with outline, no fill |
Coordinate Enums
XLocation — X-axis coordinate system:
| Variant | Description |
|---|---|
Index | X values are bar indices (0-based integers) |
Time | X values are Unix timestamps in milliseconds |
YLocation — Y-axis positioning (labels only):
| Variant | Description |
|---|---|
Price | Y is a price value on the Y-axis (default) |
AboveBar | Position above the bar at the given X |
BelowBar | Position below the bar at the given X |
Position Enum
Table anchor position on the chart:
| Variant | Description |
|---|---|
TopLeft | Top-left corner |
TopCenter | Top center |
TopRight | Top-right corner |
MiddleLeft | Middle left |
MiddleCenter | Center of the chart |
MiddleRight | Middle right |
BottomLeft | Bottom-left corner |
BottomCenter | Bottom center |
BottomRight | Bottom-right corner |
Text Enums
| Enum | Variants | Description |
|---|---|---|
HorizontalAlign | Left, Center, Right | Horizontal text alignment |
VerticalAlign | Top, Middle, Bottom | Vertical text alignment |
FontFamily | Default, Monospace | Font selection |
TextFormatting | None, Bold, Italic | Text style |
TextWrap | Auto, None | Text wrapping behavior |
Fill Enums
FillAnchor — boundary reference for Fill:
| Variant | Description |
|---|---|
Plot(SeriesGraphId) | References a Plot series graph |
Hline(GraphId) | References an Hline graph |
FillColor — fill color type:
| Variant | Description |
|---|---|
Solid(Color) | Uniform fill color |
Gradient(Gradient) | Vertical gradient between two values |
Rendering Order
The recommended draw order (back to front):
- Chart background — clear with the theme background color.
- Grid lines — price and time axis gridlines.
- Background colors — iterate
series_graphs, drawBackgroundColorstrips. - Fills — iterate
series_graphs, drawFillareas between anchors. - Main candlesticks / bars — the input OHLC data (apply
bar_colorsoverrides). Ifbehind_chartisfalse, draw the script visuals on top; otherwise draw them behind. - Hlines — iterate
graphs, draw horizontal lines. - Plot series — iterate
series_graphs, drawPlot(lines, areas, histograms, markers). - Extended series — iterate
series_graphs, drawPlotCandle,PlotBar,PlotArrow,PlotChar,PlotShape. - Drawing objects — iterate
graphs, drawLine,Box,Polyline,LineFill. - Labels — iterate
graphs, drawLabel(text + shape). - Tables — iterate
graphs, drawTableat their anchored positions. - Axes — price scale, time scale, volume scale.
- Order fills — for strategies, draw fill markers from
filled_orders. - Crosshair / interaction overlay — mouse tracking, tooltips.
If explicit_plot_zorder is true, draw series graphs strictly in their iteration order (which is the declaration order in the script). Earlier = bottom layer.
If force_overlay is true on any visual, render it on the main price pane regardless of whether the script is an overlay.
When show_last is set, only render the last N entries. When offset is set, shift the visual by that many bars.
Next Steps
- Error Handling — handling compile and runtime errors
- C/C++ API — use from C++