Skip to content
ChartDeck ChartScript docs Account Open the terminal

Trade prints

The large trades (prints) of each bar from the trade tape with flow.prints, their price, size, side and time, the Auto threshold and history.

A print is one trade on the exchange: a price, a size and a side (did a buyer or a seller take the order book?). ChartDeck keeps the market's recent large prints and streams the live tape to the chart, and the built-in Large prints study draws them as bubbles. A script reads the same prints with flow.prints.

#The prints of a bar

flow.prints(min_notional) returns the bar's prints worth at least min_notional (price × size, in the quote currency), oldest first, as an array of flow.print:

FieldTypeMeaning
timeintthe trade time, in milliseconds
pricefloatthe trade price
sizefloatthe size, in the base coin
sideint+1 a buyer took the offer, -1 a seller hit the bid
notionalfloatprice × size
ChartScriptOpen in editor
//@chartscript 1
indicator("Big buys and sells", { overlay: true, max_labels_count: 300 })
const minValue = input.float(250000, "Minimum value")
for (const p of flow.prints(minValue)) {
    label.new(p.time, p.price, "", xloc.bar_time, yloc.price, p.side > 0 ? color.new(color.up, 60) : color.new(color.down, 60), label.style_circle, na, size.tiny)
}

A second argument keeps one side only: flow.prints(minValue, "buy") or "sell". Prints of one millisecond and one side arrive merged, as the exchanges send them.

#A threshold that fits the market

A fixed minimum suits one market and not the next. flow.print_threshold(percentile) gives the value that percentile percent of the market's recent prints stay under: 99, 99.5 and 99.9 from the server's last hour of prints, 95 and 98 (or when the server has seen too few) from the live tape's newest 3,000 prints. It is na until enough prints were seen. This is the built-in study's Auto threshold:

ChartScriptOpen in editor
//@chartscript 1
indicator("Prints above the 99.9th percentile", { overlay: true })
const thr = nz(flow.print_threshold(99.9), 1000000)
let buys = 0.0
let sells = 0.0
for (const p of flow.prints(thr)) {
    if (p.side > 0) {
        buys += p.notional
    } else {
        sells += p.notional
    }
}
plot(buys - sells, "Big-print delta", color.accent, 2, { display: display.data_window })

The official Large prints script (View source in that study's settings) rounds the threshold up to a readable figure ($250K) and sizes each bubble by its value, exactly as the built-in study does.

#Binance prints on any chart

The last argument, venue, picks whose prints you read. "" (the default) is the chart's market; "binance" is the coin's Binance perpetual (USDT-margined), whatever exchange the chart shows. A MEXC or BloFin chart can mark the big Binance trades, where most of the volume trades. It works on every plan, inside the plan's prints window.

ChartScriptOpen in editor
//@chartscript 1
indicator("Binance whales on this chart", { overlay: true, max_labels_count: 300 })
const thr = nz(flow.print_threshold(99.9, "binance"), 1000000)
for (const p of flow.prints(thr, "both", "binance")) {
    label.new(p.time, close, "", xloc.bar_time, yloc.price, p.side > 0 ? color.new(color.up, 50) : color.new(color.down, 50), label.style_diamond, na, size.tiny)
}

flow.print_threshold(percentile, venue) and flow.prints_since(venue) take the same argument. When Binance lists the coin as a contract of 1,000 coins (1000PEPEUSDT), that market's prints are read; when it lists no perpetual of the coin, the array is empty. The prices are Binance's, so draw them at the bar's own price (as above) when the two markets quote differently.

#How far back the prints go

Prints are live data, not candles. A script sees:

  • the prints ChartDeck recorded for the market recently: the plan's order-flow window (15 minutes on Beginner, 1 hour on Plus, 4 hours on Pro, 24 hours on Elite), when the market was being recorded (someone had its tape or workspace open);
  • then every print of the live tape while the chart is open (the newest 5,000, or 30 minutes).

Older bars therefore have no prints: flow.prints gives them an empty array. The Binance prints (venue = "binance") follow the same rules for the Binance market. flow.prints_since() says where the prints begin. On a live bar the prints of the bar grow tick by tick, like its high and low. Inside a request prints are the chart's, not the requested market's, so flow.prints there gives empty arrays (warning CS3124).

A script that runs on ChartDeck's servers (a protected Community script, a script alert) reads the server's recorded prints, refreshed every minute; it has no live tape.

#Big trades on the chart

The Big trades bubbles on your chart are piles of prints: one bar, one side, prices within a narrow band of each other (0.015 % up to 1-hour bars, wider on longer bars), at the size your chart uses (Chart settings: a fixed size, else Auto) and from its exchanges (This exchange, or All exchanges on Pro and Elite). A script reads exactly those piles:

NameGives
flow.big_buy_usd, flow.big_sell_usdthe value of the bar's Big trades on taker buys / sells (USD)
flow.big_counthow many bubbles the bar has
flow.big_trades(back)the bar's bubbles: time, price (value-weighted), notional, side (+1 buy, -1 sell), prints, venues
flow.big_threshold(), flow.big_since()the size in use, and the time from which the Big trades are held
ChartScriptOpen in editor
//@chartscript 1
indicator("Big buys against big sells")
plot(flow.big_buy_usd - flow.big_sell_usd, "Big trades delta", { style: plot.style_columns })

Before flow.big_since() every value is na, never 0; a bar inside the history with no Big trades reads 0. The history is your plan's Big trades reach (Beginner 15 minutes, Plus 24 hours, Pro 30 days, Elite 90 days), at most a month back from the newest bar. Big trades are on every plan for signed-in members; signed out, every value is na and the legend says "Big trades: sign in to load".

flow.big_trades(back) lists the bubbles of a bar, by time, with prints (how many prints the pile sums) and venues (their exchanges). It holds every pile, also those a zoomed-out chart leaves out. Mark the big ones, for example:

ChartScriptOpen in editor
//@chartscript 1
indicator("Biggest Big trades", { overlay: true, max_labels_count: 200 })
const minUsd = input.float(2000000, "Mark piles from (USD)")
for (const b of flow.big_trades()) {
    if (b.notional >= minUsd && barstate.isconfirmed) {
        label.new(b.time, b.price, str.tostring(b.notional / 1000000, "#.#") + "M", xloc.bar_time, yloc.price, b.side > 0 ? color.up : color.down, label.style_label_left, color.white, size.tiny)
    }
}
if (barstate.islast) {
    legend.info("Big trades from " + str.tostring(flow.big_threshold(), format.volume) + " USD")
}

The per-bar values follow the live tape on every tick; the stored prints behind them, and so the lists, are asked again every minute. In Bar replay a script sees only the prints at or before the replay time, at the Auto size of that time. A script on ChartDeck's servers (a protected script, a script alert) has no chart settings and no live tape: it reads This exchange at the Auto size from the recorded prints, refreshed every minute, so with a fixed size or All exchanges on your chart its values can differ from the chart's. The per-bar values also work inside a request; the lists read the chart's own bars only.

The ChartScript documentation is in English for now; translations will follow.