Tables#
The table object can display grid-based information at a fixed position on the chart, making it ideal for dashboards, showing current values of multiple indicators, or displaying strategy statistics. Unlike label, a table is anchored to a corner of the screen and does not move with the bars.
Creating a Table#
table.new(position, columns, rows, bgcolor, border_color, border_width, frame_color, frame_width)| Parameter | Description |
|---|---|
position | Position of the table on screen |
columns | Number of columns |
rows | Number of rows |
bgcolor | Table background color |
border_color | Cell border color |
border_width | Border width (px) |
Position Constants#
| Constant | Position |
|---|---|
position.top_left | Top-left corner |
position.top_center | Top center |
position.top_right | Top-right corner |
position.middle_left | Middle left |
position.middle_center | Center |
position.middle_right | Middle right |
position.bottom_left | Bottom-left corner |
position.bottom_center | Bottom center |
position.bottom_right | Bottom-right corner |
Filling Cells#
After creating the table, use table.cell() to fill each cell’s content:
table.cell(table_id, column, row, text, text_color, text_size, bgcolor, text_halign)Cell indices start at the top-left corner (0, 0), with columns increasing to the right and rows increasing downward.
Basic Example#
//@version=6
indicator("Simple Table", overlay=true)
// Only create the table on the last bar (avoid rebuilding every bar)
if barstate.islast
t = table.new(position.top_right, 2, 3,
bgcolor=color.new(color.navy, 10),
border_color=color.new(color.white, 50),
border_width=1)
// Header row
table.cell(t, 0, 0, "Indicator", text_color=color.white, text_size=size.small)
table.cell(t, 1, 0, "Value", text_color=color.white, text_size=size.small)
// RSI
rsiVal = ta.rsi(close, 14)
table.cell(t, 0, 1, "RSI(14)", text_color=color.white, text_size=size.small)
table.cell(t, 1, 1, str.tostring(math.round(rsiVal, 2)),
text_color=rsiVal > 70 ? color.red : rsiVal < 30 ? color.green : color.white,
text_size=size.small)
// Volume vs Average Volume
volMA = ta.sma(volume, 20)
volRatio = volume / volMA
table.cell(t, 0, 2, "Vol Ratio", text_color=color.white, text_size=size.small)
table.cell(t, 1, 2, str.tostring(math.round(volRatio, 2)) + "x",
text_color=volRatio > 1.5 ? color.yellow : color.white,
text_size=size.small)Persisting Tables with var#
Declaring the table with var avoids recreating it on every bar — you only need to update the cell content:
//@version=6
indicator("Persistent Table", overlay=true)
// Create the table only once
var t = table.new(position.top_right, 2, 4,
bgcolor=color.new(color.black, 20),
border_color=color.gray, border_width=1)
// Update values on every bar (only update the value column, no rebuild)
if barstate.islast or barstate.isrealtime
ma20 = ta.sma(close, 20)
rsi = ta.rsi(close, 14)
atr = ta.atr(14)
// Header row (safe to write every time)
table.cell(t, 0, 0, "Indicator", bgcolor=color.new(color.blue, 50), text_color=color.white)
table.cell(t, 1, 0, "Value", bgcolor=color.new(color.blue, 50), text_color=color.white)
table.cell(t, 0, 1, "MA20", text_color=color.white)
table.cell(t, 1, 1, str.tostring(math.round(ma20, 2)),
text_color=close > ma20 ? color.green : color.red)
table.cell(t, 0, 2, "RSI(14)", text_color=color.white)
table.cell(t, 1, 2, str.tostring(math.round(rsi, 1)),
text_color=rsi > 70 ? color.red : rsi < 30 ? color.lime : color.white)
table.cell(t, 0, 3, "ATR(14)", text_color=color.white)
table.cell(t, 1, 3, str.tostring(math.round(atr, 2)), text_color=color.white)Merging Cells#
table.merge_cells() merges adjacent cells, commonly used to create title rows:
//@version=6
indicator("Merged Cells", overlay=true)
if barstate.islast
t = table.new(position.top_left, 3, 3,
bgcolor=color.new(color.navy, 20),
border_color=color.white, border_width=1)
// Merge all three cells in the first row as the title
table.cell(t, 0, 0, "Multiple MA Dashboard",
text_color=color.white, text_size=size.normal)
table.merge_cells(t, 0, 0, 2, 0) // Merge from (0,0) to (2,0)
// Data rows
headers = array.from("Period", "MA Value", "Position")
periods = array.from(5, 20, 60)
for col = 0 to 2
table.cell(t, col, 1, array.get(headers, col),
text_color=color.gray, text_size=size.small)
for row = 0 to 2
period = array.get(periods, row)
maVal = ta.sma(close, period)
pos = close > maVal ? "Above ▲" : "Below ▼"
posColor = close > maVal ? color.green : color.red
table.cell(t, 0, row + 2, str.tostring(period) + "-bar",
text_color=color.white, text_size=size.small)
table.cell(t, 1, row + 2, str.tostring(math.round(maVal, 2)),
text_color=color.white, text_size=size.small)
table.cell(t, 2, row + 2, pos,
text_color=posColor, text_size=size.small)