MMTMMT Docs
Built-in catalog

surfaces reference

Render surfaces for windows, panes, chart panels, heatmaps, and tables.

Render surfaces for windows, panes, chart panels, heatmaps, and tables.

Accepted values

These named values are the complete choices accepted by parameters of each type.

Align

PreviewValueMeaning
align.leftAligns text to the left. This is the default for columns and cells.
align.centerCenters text.
align.rightAligns text to the right.

Axis

ValueMeaning
axis.timeUses time values as keys, for example for custom candles or session bars.
axis.indexUses integer positions as keys, for example for distributions.
axis.categoryUses string labels as keys, for example for bars grouped by exchange or symbol.

window

window(title: string = "") -> Window

Creates a window containing charts, heatmaps, or tables.

title names the window. A script attached to a chart starts with its window closed; open it from the badge beside the script's name. A script opened without a chart shows its window immediately.

Declare each panel as a named field inside the window block, then refer to it as win.main. Each field needs a different name within its window and must contain one chart, heatmap, or table panel. A panel cannot be shared between fields. Different windows can reuse field names.

Use on: win.main to add a pane to a window's chart panel. Keep the window and panel names stable to preserve saved settings; title only changes the label. A script can create up to 4 windows.

Example

script "Window Surface"
data px = subscribe(data.ohlcv)
window win = window(title: "Volume screener") {
  main: chart.panel(px),
}
plot vol = plot.histogram(title: "Volume", on: win.main)

on px.update {
  vol.plot(px.volume)
}

pane

pane(title: string = "", height: float = 0.3, on: ChartPanel? = null) -> Pane

Adds a separate pane to a chart.

  • title names the pane.
  • height sets its size relative to the main price pane: 0.5 means half as tall. Use a value from 0.05 to 1.0, inclusive. Other values are rejected before the script runs.
  • on chooses a window chart panel, such as dash.daily. Omit it to use the main chart.

Use on: paneName when declaring a plot to draw in this pane. Plots without on: use their default pane. Panes appear in declaration order, with up to 4 per chart.

Give the pane a name and keep it stable to preserve saved appearance settings. Moving an unnamed pane to another declaration can reset those settings. Names starting with $ are reserved for panes created automatically by the app.

Contracts

  • height: Accepted range: 0.05 to 1.0. Must be a finite number. Invalid values are rejected.

Example

script "Pane Surface"
data chart = subscribe(data.ohlcv)
pane wt = pane(title: "WaveTrend", height: 0.3)
plot wave = plot.line(title: "WT", on: wt)

on chart.update {
  wave.plot(ta.rsi(chart.close, 14))
}

chart.panel

chart.panel(sub: Subscription? = null, axis: Axis? = null, title: string = "") -> ChartPanel

Adds a chart panel to a window.

Declare it as a named field inside a window block, then refer to it as win.main.

Choose one data layout:

  • sub: Use a bar subscription to set the chart's horizontal axis.
  • axis: Choose an axis and add plot values with set(key, ...). Each key must match the axis's type.

Provide either sub or axis, but not both. Leaving both null is also an error. Use title to name the panel.

Set on: win.main to draw in its price pane. To draw in a separate pane, create one with pane(..., on: win.main) and target that pane instead.

Example

script "Chart Panel"
data h4 = subscribe(data.ohlcv, timeframe: tf("4h"))
window dash = window(title: "Daily") {
  main: chart.panel(h4, title: "4h Price"),
}
plot px = plot.line(title: "4h Close", on: dash.main)

on h4.close {
  px.plot(h4.close)
}

Accepted values

heatmap.new

heatmap.new(title: string = "", x: Axis, y: Axis, capacity: int, min: float? = null, max: float? = null, palette: color[] = []) -> HeatmapPanel

Creates a heatmap panel.

  • title names the panel.
  • x and y choose the two axes and the types of keys used for each.
  • capacity limits the number of cells, from 1 to 65536. Other values are rejected before the script runs.
  • min and max set a fixed color scale when both are supplied. Leave them null for automatic scaling.
  • palette supplies the gradient colors. An empty list uses the default palette.

Add or update cells with hm.set(x, y, value).

Contracts

  • capacity: Accepted range: 1 to 65536. Invalid values are rejected.

Example

script "Heatmap Panel"
data chart = subscribe(data.ohlcv)
window win = window(title: "Volume") {
  hm: heatmap.new(title: "Volume", x: axis.category, y: axis.index,
    capacity: 128, min: 0.0, max: 1000000.0),
}

on chart.update {
  win.hm.set("BTC", 0, chart.volume ?? 0.0)
}

Accepted values

table.new

table.new(columns: TableColumn[], title: string = "", key: Axis? = null, capacity: int = 100) -> TablePanel

Creates a table panel with fixed columns.

  • title names the panel.
  • columns defines up to 16 columns using table.col.
  • key chooses the row-key type. Leave it null to use string category keys.
  • capacity limits the number of rows. Values outside the allowed range are rejected before the script runs. Adding a new row when full stops the script with an error.

Rows stay in the table until you update or delete them. Use the table methods to add rows, change cells, or clear data. The app handles sorting, filtering, and resizing columns.

Contracts

  • capacity: Accepted range: 1 to 1000. Invalid values are rejected.

Example

script "Table Panel"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([
    table.col(title: "Symbol"),
    table.col(title: "Close", align: align.right),
  ], title: "Positions"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", "BTCUSDT", chart.close ?? 0.0)
}

Accepted values

table.col

table.col(title: string = "", align: Align? = null, width: float = 1) -> TableColumn

Defines a column for a table.

Use this inside the columns list of table.new.

  • title names the column.
  • align sets text alignment. Null uses left alignment.
  • width sets the column's relative width. A value of 0.6 gives it 60% of the space given to a column with width 1.0. Use 0.1 to 10.0, inclusive; other values are rejected before the script runs.

Contracts

  • width: Accepted range: 0.1 to 10.0. Must be a finite number. Invalid values are rejected.

Example

script "Table Column"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([
    table.col(title: "Symbol"),
    table.col(title: "Close", align: align.right, width: 0.8),
  ], title: "Quotes"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", "BTCUSDT", chart.close ?? 0.0)
}

Accepted values

table.cell

table.cell(value: scalar, fg: color? = null, bg: color? = null, align: Align? = null) -> TableCell

Adds text color, background color, or alignment to a table value.

value can be a float, int, bool, string, or time. Null displays an empty cell.

  • fg sets the text color.
  • bg sets the background color.
  • align sets text alignment.

Leave a style option null to use the table or column setting. For unstyled cells, pass values directly to row or set; no table.cell wrapper is needed.

Example

script "Table Cell"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([table.col(title: "Close")], title: "Quotes"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", table.cell(chart.close, fg: color.green))
}

Accepted values

surfaces.pane.setTitle

surfaces.pane.setTitle(text: string) -> void

Sets the title the chart shows for this pane's legend row.

Call this on a pane you declared, such as wt.setTitle(text), or another name referring to that pane. You can call it on every update. The chart refreshes the title after the handler finishes when the text has changed. Pass an empty string to restore the pane's original title:.

Titles are limited to 256 UTF-8 bytes; longer text is shortened. Saved appearance settings keep using the pane's declared name. Use script.setTitle to change the title on the main price pane.

Example

script "WaveTrend"
data chart = subscribe(data.ohlcv)
pane wt = pane(title: "WaveTrend", height: 0.3)
plot wave = plot.line(title: "WT", on: wt)

on chart.update {
  let v = ta.rsi(chart.close, 14)
  wave.plot(v)
  wt.setTitle(str.format("WT  {0:.1}", v ?? 0.0))
}

surfaces.heatmap.set

surfaces.heatmap.set(x: Key, y: Key, value: float?) -> void

Adds or updates a heatmap cell.

x and y locate the cell. value sets its value; null deletes the cell. The panel's color scale determines the cell color.

Adding a new cell when capacity is reached stops the script with an error.

Example

script "Heatmap Set"
data chart = subscribe(data.ohlcv)
window win = window(title: "Volume") {
  hm: heatmap.new(title: "Volume", x: axis.category, y: axis.index,
    capacity: 128),
}

on chart.update {
  win.hm.set("BTC", 0, chart.volume ?? 0.0)
}

surfaces.table.row

surfaces.table.row(key: Key, cells: TableCell...) -> void

Adds or replaces a whole table row.

key identifies the row. Supply one value in cells for each column, in column order. The number of cells must match the column count. A mismatch is rejected before the script runs when it can be checked then; otherwise it stops the script with an error.

Pass plain values for unstyled cells or use table.cell to style individual cells. Use rowBg to set the row's background. Updating a row replaces all of its cells together.

Example

script "Table Row"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([
    table.col(title: "Symbol"),
    table.col(title: "Close", align: align.right),
  ], title: "Quotes"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", "BTCUSDT", chart.close ?? 0.0)
}

surfaces.table.set

surfaces.table.set(key: Key, column: int, value: TableCell) -> void

Changes one cell in an existing row.

key identifies the row. column selects the column, counting from 0. value can be a plain value or a styled table.cell.

A missing row, a negative column, or a column at or beyond the column count stops the script with an error. Use row to create a row first.

Contracts

  • column: Accepted range: 0 up to but not including MAX_TABLE_COLS. Invalid values are rejected.

Example

script "Table Set"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([
    table.col(title: "Symbol"),
    table.col(title: "Close", align: align.right),
  ], title: "Quotes"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", "BTCUSDT", 0.0)
  dash.tbl.set("BTCUSDT", 1, table.cell(chart.close, fg: color.green))
}

surfaces.table.rowBg

surfaces.table.rowBg(key: Key, bg: color?) -> void

Changes the background color of an existing row.

key identifies the row. bg sets its background color; null restores the theme default. A missing row stops the script with an error.

Use this after row to style the whole row.

Example

script "Table Row Background"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([table.col(title: "Symbol")], title: "Quotes"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", "BTCUSDT")
  dash.tbl.rowBg("BTCUSDT", color.rgb(200, 0, 0, 40))
}

surfaces.table.clear

surfaces.table.clear(key: Key? = null) -> void

Deletes one row or clears the table.

Pass key to delete that row. An unknown key does nothing. Omit key, or pass null, to delete every row.

Example

script "Table Clear"
data chart = subscribe(data.ohlcv)
window dash = window(title: "Screener") {
  tbl: table.new([table.col(title: "Symbol")], title: "Quotes"),
}

on chart.update {
  dash.tbl.row("BTCUSDT", "BTCUSDT")
  if (chart.close ?? 0.0) < (chart.open ?? 0.0) { dash.tbl.clear("BTCUSDT") }
}

axis.time

axis.time: Axis = 0

Uses time values as keys, for example for custom candles or session bars.

axis.index

axis.index: Axis = 1

Uses integer positions as keys, for example for distributions.

axis.category

axis.category: Axis = 2

Uses string labels as keys, for example for bars grouped by exchange or symbol.

align.left

align.left: Align = 0

Aligns text to the left. This is the default for columns and cells.

align.center

align.center: Align = 1

Centers text.

align.right

align.right: Align = 2

Aligns text to the right.

On this page