FlowscopeDocs

Inputs and visuals

Expose clear settings, organise them, and choose the right plot for each output.

Inputs are the settings traders see when they click the gear on a script’s legend row. Give them clear labels and sensible ranges; defaults should produce a useful chart without any configuration.

Flowscope Script
script "MA spread"

input (
  fastLength = input.int(12, title: "Fast length", min: 1, max: 200)
  slowLength = input.int(26, title: "Slow length", min: 2, max: 400)
  bullishColor = input.color(color.green, title: "Bullish")
  bearishColor = input.color(color.red, title: "Bearish", sameLine: true)
)

data chart = subscribe(data.ohlcv)

plot spread = plot.histogram(title: "MA spread")

on chart.close {
  let fast = ta.ema(chart.close, fastLength)
  let slow = ta.ema(chart.close, slowLength)
  let value: float? = fast == null || slow == null ? null : (fast ?? 0.0) - (slow ?? 0.0)
  spread.plot(value, color: (value ?? 0.0) >= 0.0 ? bullishColor : bearishColor)
}

A vertical histogram without on: gets its own pane automatically, named after the script. Other plots go on the price pane unless you declare a pane and pass on:.

Input kinds

ConstructorValueNotes
input.int(default, min:, max:)intA number field.
input.float(default, min:, max:)floatA number field.
input.bool(default)boolA switch.
input.color(default)colorA colour picker.
input.select(default, options: [...])stringA dropdown of text options.
input.timeframe(default)timeframeA timeframe.
input.exchange(default), input.exchanges(default)string, string[]Exchange pickers.

Every input takes title:, description: (a tooltip), key: (keeps saved settings when you rename the binding), sameLine: and when: (show the input only when a condition on other inputs holds). Changing an input re-runs the script over the loaded history.

On a chart, the settings dialog edits number, switch, colour and dropdown inputs; timeframe and exchange inputs keep their defaults there.

Organise long settings

Layout rows are written without a binding:

Flowscope Script
script "Organised settings"

input (
  input.section(title: "Trend")
  trendLength = input.int(50, title: "Length", min: 2)
  showTrend = input.bool(true, title: "Show", sameLine: true)
  input.section(title: "Signals")
  signalStyle = input.select("Markers", title: "Style", options: ["Markers", "Background"])
)

data chart = subscribe(data.ohlcv)

plot (
  trend = plot.line(title: "Trend", color: color.blue)
  marks = plot.marker(title: "Above trend", shape: shape.circle, color: color.teal, size: 6.0)
  bg = plot.bg(title: "Above trend", color: #26A69A18)
)

on chart.close {
  let avg = ta.sma(chart.close, trendLength)
  trend.plot(showTrend ? avg : null)
  let above = (chart.close ?? 0.0) > (avg ?? 0.0)
  if above && signalStyle == "Markers" {
    marks.plot(chart.high)
  }
  if above && signalStyle == "Background" {
    bg.plot()
  }
}

For a visibility switch, keep the plot declared and feed it null when hidden, as trend does above, so the script’s outputs stay the same.

Choose the plot

PlotUse it for
plot.lineAverages, bands, oscillators. style: linestyle.dotted, dashed or step; area: true shades below.
plot.histogramSigned quantities such as delta, from zero, coloured per bar.
plot.candle, plot.barOHLC of another series, such as a higher timeframe or a synthetic index.
plot.pointSparse values as dots.
plot.markerEvents at a price, with a shape:.
plot.arrowUp or down events; the value’s sign is the direction.
plot.labelShort text at a price.
plot.bgTint the bars where a condition holds.
plot.cellsRows of cells inside each bar: footprints, per-bar profiles, ladders.
fill.betweenShade between two lines.

Free-form drawings (lines, boxes, labels anchored to the pane) are entity pools; see repainting for the pattern of drawing at the live edge.

Cells inside a bar

plot.cells draws rows of cells inside each bar: a price band, a width, colours and a number. It keeps them for far more bars than box entities can. This is a bid x ask footprint on rows of 25, with the chart’s candles as a thin strip beside it:

Flowscope Script
script "Footprint cells"

data (
  chart = subscribe(data.ohlcv)
  vol = subscribe(data.volume)
)

plot footprint = plot.cells(
  title: "Bid x Ask",
  columns: 2,
  candles: cellcandles.side,
  format: cellformat.fixed,
  decimals: 2,
)

on chart.update {
  let rows = vol.bucketsByStep(25.0)
  if rows != null {
    footprint.clear(time: rows.time)
    for row in rows {
      footprint.cell(row.from, row.to, weight: row.sell, value: row.sell, color: #e0443a80, column: 0,
        align: align.right, time: rows.time)
      footprint.cell(row.from, row.to, weight: row.buy, value: row.buy, color: #2fa66a80, column: 1,
        time: rows.time)
    }
  }
}
  • Columns. A bar has 1 to 4 columns side by side; column: picks one, align: the edge a cell’s width grows from.
  • Width. weight: is compared as the plot’s scale: says: with the largest weight on its own bar (cellscale.bar, the default), with the largest on the visible bars (cellscale.view), or taken as the width itself from 0 to 1 (cellscale.unit). Without a weight the cell fills its column.
  • Numbers. value: is written in the cell when it fits. format:, decimals:, sign: and grouping: choose 3.21K, 3214.56, +3,215 or 15.3%; a bar too narrow for that is written with fewer digits.
  • Candles. candles: leaves the chart’s candles as they are (cellcandles.overlay), draws them as a thin strip at the left of each bar (cellcandles.side) or hides them (cellcandles.hidden).
  • Steps. The first cell or clear for a bar in a handler call discards what the bar held before, so a script redraws a bar by writing it again. Call clear where a bar may end up with no cells.

bucketsByStep puts the rows on whole multiples of the step, so the same price is the same row on every bar. A bar holds up to 1024 cells per plot.