Charts
Concepts

Surfaces

Pick where a script draws: on the price pane, in its own pane, or as the chart type.

surface picks where a script draws:

SurfaceWhereFramePrice scale
{ kind: "ChartOverlay", layer? }the price pane, over or under the candlesChartFramethe price pane's
{ kind: "ChartPane", weight? }its own pane below the price paneChartFrameits own, autoscaled from g.keepVisible and g.priceValue
{ kind: "Canvas", weight? }its own pane below the price paneCanvasFramenone
{ kind: "ChartSeries" }the price pane, as the chart typeChartFramethe price pane's, autoscaled from g.priceValue
  • ChartOverlay, ChartPane and Canvas are indicators: added from the indicator list. See Create an indicator.
  • ChartSeries is a chart type: picked in the chart type menu, the chart draws no candles. See Create a chart type.
  • weight is the pane's initial height relative to the price pane's 1, 0.3 when omitted. The user can resize it by dragging the separator, the new size is saved.
  • layer ("bottom", "normal", "top") is the overlay's paint layer. See Layers.

Chart surfaces

ChartOverlay, ChartPane and ChartSeries share the chart's time axis and crosshair. Their frame converts time and price to pane px (timeToX, priceToY), pointer events carry time and price, and they can add price and time axis labels.

Price scale

A price scale fits only what scripts report to it, from the next frame:

  • ChartPane and ChartSeries: call g.priceValue(time, value) in draw for every visible point, not just the last one, or the line runs out of the pane. g.keepVisible(0, 0) keeps a zero line in view.
  • ChartOverlay: the candles set the scale. A level far from price stays off-screen unless the script calls g.keepVisible(low, high) for it.

Canvas

A free pixel surface for things without a time axis: histograms, tables, gauges. No timeToX or priceToY, pointer events carry x and y only, g.layer just draws, and no axis labels or autoscale. The script draws its own axes. See Trade size distribution.

Canvas gets every click, chart surfaces only clicks on a hit, so an empty chart still pans.

Writing for one surface

TypeScript narrows the frame by the surface: with surface: { kind: "Canvas" }, draw gets a CanvasFrame and frame.priceToY is a type error. A helper that takes a frame can accept ChartFrame and check frame.kind.

On this page