FlowscopeDocs

Data and update events

Subscribe to market data, react to open, update, close and trade events, and read earlier values.

A subscription names a market-data series the script reads. For a chart indicator, start with the chart’s candles:

Flowscope Script
script "Chart data"

data chart = subscribe(data.ohlcv)

chart is a name you choose, not a built-in global. It exposes candle fields such as open, high, low, close and volume. These can be missing, so their types are nullable (float?).

Sources

SourceRecordWhat it holds
data.ohlcvOhlcvSubCandles: open high low close volume buyVolume sellVolume buyCount sellCount trades.
data.vdVdSubVolume delta per bar as open high low close.
data.cvdCvdSubCumulative volume delta as open high low close.
data.oiOiSubOpen interest as open high low close.
data.statStatSubMarket statistics: sellLiq buyLiq markPrice fundingRate.
data.tradesTradesSubIndividual trades, delivered to an on t.trade(tr) handler.
data.bookBookSubOrder-book snapshots, read from another subscription’s handler.
data.volumeVolumeSubVolume-profile snapshots, read from another subscription’s handler.

What a chart provides

On a chart, subscriptions serve the chart’s own market:

  • Candles, delta, CVD and open interest at the chart’s interval or a whole multiple of it (a 15m chart serves timeframe: 1h, not 5m).
  • Statistics from the market’s liquidations and funding: sellLiq and buyLiq are the value of liquidation orders in the bar (a sell liquidates a long), fundingRate the last settled rate (the current rate on the newest bar). markPrice is not available. Spot markets have no statistics.
  • Trades from the trades the chart holds in memory.
  • Order books from the book the chart has recorded (what its liquidity heatmap shows): a snapshot is the book resting at the end of a period. Before the recording starts, reads return null.
  • Volume profiles from the footprints of the chart’s bars: a snapshot sums the volume traded in a period by footprint row. While a script reads a profile, the chart loads footprints for the bars on screen; bars without one read null.

Volume delta needs a volume split: the data hub’s candles carry one, being built from recorded trades, and so does the live tape.

Other exchanges and symbols

Candles, delta and CVD can come from other markets than the chart’s. exchange: takes one exchange id or several joined with markets.agg(...); their bought and sold volume are added up, and the prices are those of the first exchange that traded in the bar. Without symbol: each exchange’s market of the chart’s coin is read (BTCUSDT on Binance, BTC-USDT-SWAP on OKX, BTC on Hyperliquid), so one script works on any chart:

Flowscope Script
script "Spot CVD"

setup spot = markets.agg("binance", "bybit", "okx", "coinbase", "kraken")

data (
  chart = subscribe(data.ohlcv)
  spotCvd = subscribe(data.cvd, exchange: spot)
)

pane cvdPane = pane(title: "Spot CVD", height: 0.25)
plot line = plot.line(title: "Spot CVD", on: cvdPane)

on chart.update {
  line.plot(spotCvd.close)
}

The bars are the chart’s bars: a bar no exchange of the subscription traded in reads null. The other markets load after the script starts, so the first values appear a moment later. Open interest, statistics, trades, order books and volume profiles of other markets are not available: they read null. markets.exchangeNames("spot") and markets.exchangeNames("futures") list the exchange ids.

Respond to updates

Put calculations in a handler of the subscription that drives them:

Flowscope Script
script "Candle range"

data chart = subscribe(data.ohlcv)

plot range = plot.histogram(title: "Candle range")

on chart.update {
  let candleRange = (chart.high ?? 0.0) - (chart.low ?? 0.0)
  range.plot(candleRange)
}

Several handlers

Each subscription reacts to its own events, so different rates stay in separate, focused blocks. This script saves levels when an hourly candle closes and plots them as the chart advances:

Flowscope Script
script "Previous hour high and low"

data (
  chart = subscribe(data.ohlcv)
  h1 = subscribe(data.ohlcv, timeframe: 1h)
)

state (
  prevHigh: float? = null
  prevLow: float? = null
)

plot (
  highPlot = plot.line(title: "Previous hour high", color: color.red, style: linestyle.step)
  lowPlot = plot.line(title: "Previous hour low", color: color.green, style: linestyle.step)
)

on h1.close {
  prevHigh = h1.high
  prevLow = h1.low
}

on chart.update {
  highPlot.plot(prevHigh)
  lowPlot.plot(prevLow)
}
  • on h1.close runs when an hourly candle is confirmed and saves values that do not change afterwards.
  • on chart.update runs as the chart advances and draws the saved levels.

state connects the handlers: what one writes, later calls of the other read.

Period subscriptions support open, update and close handlers. A trades subscription uses a trade handler for each print. There is at most one handler per subscription and event.

Statistics: liquidations and funding

Flowscope Script
script "Liquidations"

data (
  chart = subscribe(data.ohlcv)
  stats = subscribe(data.stat)
)

pane liqPane = pane(title: "Liquidations (USD)", height: 0.25)

plot (
  longs = plot.histogram(title: "Longs liquidated", color: color.red, on: liqPane)
  shorts = plot.histogram(title: "Shorts liquidated", color: color.green, on: liqPane)
)

on stats.close {
  longs.plot(stats.sellLiq)
  shorts.plot(stats.buyLiq == null ? null : 0.0 - (stats.buyLiq ?? 0.0))
}

Funding as a line in basis points:

Flowscope Script
script "Funding (bps)"

data stats = subscribe(data.stat)

pane fundingPane = pane(title: "Funding", height: 0.2)

plot funding = plot.line(title: "Funding (bps)", color: color.amber, on: fundingPane)

on stats.close {
  let rate = stats.fundingRate
  funding.plot(rate == null ? null : (rate ?? 0.0) * 10000.0)
}

Trades

A trades subscription runs its trade handler once for each print, oldest first. minSize: keeps only prints of at least that size. Each tr is a Trade with time, price, size and isBuy.

Flowscope Script
script "Large buys"

input minSize = input.float(5.0, title: "Smallest trade (base units)", min: 0.0)

data (
  chart = subscribe(data.ohlcv)
  tape = subscribe(data.trades, minSize: minSize)
)

state bought = 0.0

pane buysPane = pane(title: "Large buy volume", height: 0.2)
plot buys = plot.histogram(title: "Large buys", color: color.green, on: buysPane)

on chart.open {
  bought = 0.0
}

on tape.trade(tr) {
  if tr.isBuy {
    bought += tr.size
  }
}

on chart.update {
  buys.plot(bought)
}

On a chart, trades reach back as far as the chart keeps them in memory, so older bars have no trades.

Order books and volume profiles

Book and profile subscriptions have no handlers of their own: read them from another subscription’s handler. Each read gets the snapshot of the last period completed at that moment, so in on chart.close it describes the bar that just closed; barsAgo: reaches further back.

Flowscope Script
script "Book imbalance and bar POC"

data (
  chart = subscribe(data.ohlcv)
  book = subscribe(data.book)
  profile = subscribe(data.volume)
)

pane imbalancePane = pane(title: "Book imbalance within 1%", height: 0.2)

plot (
  imbalance = plot.histogram(title: "Imbalance", on: imbalancePane)
  poc = plot.marker(title: "Bar POC", shape: shape.diamond, color: color.amber, size: 4.0)
)

on chart.close {
  // (bids - asks) / (bids + asks) by value, from -1 to 1.
  let ratio = book.imbalance(1.0)
  imbalance.plot(ratio, color: (ratio ?? 0.0) >= 0.0 ? color.green : color.red)
  let level = profile.poc()
  if level != null {
    poc.plot(level.price)
  }
}

profile.profile(n) merges the last n periods into one profile with the same queries (poc, valueArea, buckets, summary).

Read earlier values

Brackets read history on period fields:

Flowscope Script
script "Previous close"

data chart = subscribe(data.ohlcv)

plot previous = plot.line(title: "Previous close")

on chart.update {
  previous.plot(chart.close[1])
}

Earlier values can be null, especially near the start of the chart. Keep that absence where it matters instead of inventing a value.

For live candles and close-confirmed signals, continue with repainting and confirmed values.