Builtins: levels, stats, flows and candles from the rest of the catalog
Every other chart indicator that draws something a script can use is readable by name, grouped here by the shape of what it draws. Each family needs its indicator visible on the chart, reads that indicator's own settings, and answers exactly what the chart shows. Every family has available() and count(); -1 or an index past count() minus 1 is none, answering nan, an empty string or UNDEFINED; and when the indicator is missing the settings under the editor say its name followed by Required, for example Important Levels Required or Net GEX Required.
Level lines: Important Levels, GEX Levels, GEX Classic, GEX State
| Signature | Returns |
|---|---|
| important_levels.available() -> bool | Whether a visible Important Levels indicator is on this chart |
| important_levels.count() -> int | How many lines this bar carries |
| important_levels.find(name: string) -> int | Index of the line with exactly that label, or -1 |
| important_levels.name(index: int) -> string | The line's label as the chart prints it |
| important_levels.price(index: int) -> float | The line's price |
| important_levels.at(price: float) -> int | Index of a line exactly at that price, or -1 |
| important_levels.above(price: float) -> int | Index of the nearest line above the price, or -1 |
| important_levels.below(price: float) -> int | Index of the nearest line below the price, or -1 |
| gex_levels.available() -> bool | Whether a visible GEX Levels indicator is on this chart |
| gex_levels.count() -> int | How many lines this bar carries |
| gex_levels.find(name: string) -> int | Index of the line with exactly that label, or -1 |
| gex_levels.name(index: int) -> string | The line's label as the chart prints it |
| gex_levels.price(index: int) -> float | The line's price |
| gex_levels.at(price: float) -> int | Index of a line exactly at that price, or -1 |
| gex_levels.above(price: float) -> int | Index of the nearest line above the price, or -1 |
| gex_levels.below(price: float) -> int | Index of the nearest line below the price, or -1 |
| gex_classic.available() -> bool | Whether a visible GEX Classic indicator is on this chart |
| gex_classic.count() -> int | How many lines this bar carries |
| gex_classic.find(name: string) -> int | Index of the line with exactly that label, or -1 |
| gex_classic.name(index: int) -> string | The line's label as the chart prints it |
| gex_classic.price(index: int) -> float | The line's price |
| gex_classic.at(price: float) -> int | Index of a line exactly at that price, or -1 |
| gex_classic.above(price: float) -> int | Index of the nearest line above the price, or -1 |
| gex_classic.below(price: float) -> int | Index of the nearest line below the price, or -1 |
| gex_state.available() -> bool | Whether a visible GEX State indicator is on this chart |
| gex_state.count() -> int | How many lines this bar carries |
| gex_state.find(name: string) -> int | Index of the line with exactly that label, or -1 |
| gex_state.name(index: int) -> string | The line's label as the chart prints it |
| gex_state.price(index: int) -> float | The line's price |
| gex_state.at(price: float) -> int | Index of a line exactly at that price, or -1 |
| gex_state.above(price: float) -> int | Index of the nearest line above the price, or -1 |
| gex_state.below(price: float) -> int | Index of the nearest line below the price, or -1 |
- important_levels: one record per line, named as the chart prints it: a period and a level, such as pD H, pD L, pW POC, cD L or cM VWAP, or a custom window's name and level, such as Asia H. The periods are pD and cD for the previous and current day, pW and cW for the week, pM and cM for the month; the levels are H, L, O, C, POC, VAH, VAL and VWAP.
- important_levels never looks ahead: each bar reads the lines the chart would draw at that bar's start from the bars up to it, so a previous day's high appears only once that day has ended and a running day's high is its high so far. The newest bar reads exactly the lines on the chart.
- The GEX level families read the lines drawn from the snapshot the chart shows now, live or at the replay playhead, and carry them on the newest bar only. For a gamma history bar by bar, use gex.*.
- Their names are the chart's labels, such as ZG, GEX+, GEX- and MaxΔ on GEX Levels; ZG, P-Vol, N-Vol, P-OI, N-OI and the minute lines on GEX Classic; MLG, MSG, LG, SG, P-DEL and N-DEL on GEX State. List the rest with name(i).
- The GEX families need your GEXBot key connected.
let pdh: int = important_levels.find("pD H")
let pdl: int = important_levels.find("pD L")
let broke_pdh: bool = pdh >= 0 && close > important_levels.price(pdh) && open <= important_levels.price(pdh)
plot.marker(broke_pdh, high, "#22C55E", "triangle", "above", 10, 3)
let zg: int = gex_levels.find("ZG")
plot.label(str.concat("PREV DAY LOW ", format.fixed(important_levels.price(pdl), 2), " ZERO GAMMA ", format.fixed(gex_levels.price(zg), 2)), "#E5E7EB")Named values: Orderflow Stats, Chart Stats, On Candle Stats, Dealers Flow, COT, Net GEX
| Signature | Returns |
|---|---|
| orderflow_stats.available() -> bool | Whether a visible Orderflow Stats indicator is on this chart |
| orderflow_stats.count() -> int | How many named values this bar carries |
| orderflow_stats.find(name: string) -> int | Index of the value with exactly that name, or -1 |
| orderflow_stats.name(index: int) -> string | Its name |
| orderflow_stats.value(index: int) -> float | Its number |
| chart_stats.available() -> bool | Whether a visible Chart Stats indicator is on this chart |
| chart_stats.count() -> int | How many named values this bar carries |
| chart_stats.find(name: string) -> int | Index of the value with exactly that name, or -1 |
| chart_stats.name(index: int) -> string | Its name |
| chart_stats.value(index: int) -> float | Its number |
| candle_stats.available() -> bool | Whether a visible On Candle Stats indicator is on this chart |
| candle_stats.count() -> int | How many named values this bar carries |
| candle_stats.find(name: string) -> int | Index of the value with exactly that name, or -1 |
| candle_stats.name(index: int) -> string | Its name |
| candle_stats.value(index: int) -> float | Its number |
| dealers_flow.available() -> bool | Whether a visible Dealers Flow indicator is on this chart |
| dealers_flow.count() -> int | How many named values this bar carries |
| dealers_flow.find(name: string) -> int | Index of the value with exactly that name, or -1 |
| dealers_flow.name(index: int) -> string | Its name |
| dealers_flow.value(index: int) -> float | Its number |
| dealers_flow.spot(index: int) -> float | The price the line is drawn at |
| cot.available() -> bool | Whether a visible COT indicator is on this chart |
| cot.count() -> int | How many named values this bar carries |
| cot.find(name: string) -> int | Index of the value with exactly that name, or -1 |
| cot.name(index: int) -> string | Its name |
| cot.value(index: int) -> float | Its number |
| cot.change(index: int) -> float | Its change from the previous week |
| cot.released() -> int | How many reports became active on this bar |
| net_gex.available() -> bool | Whether a visible Net GEX indicator is on this chart |
| net_gex.count() -> int | 1 when this bar has a value, else 0 |
| net_gex.value(index: int) -> float | The Net GEX value, index 0 |
- orderflow_stats: one value per number the Orderflow Stats card prints, named row then column. The rows are GR, Vanna, Charm, DEX Aggregate, DEX Aggregate Call, DEX Aggregate Put, DEX Net, DEX Net Call, DEX Net Put and CVR with the columns 0DTE and 1DTE, and DEX flow, GEX flow and CVR flow with the columns Today and 1DTE, for example "DEX Net 0DTE" or "GEX flow Today". A hidden section or a number printed as a dash has no value. The card keeps no history: a snapshot sits from the bar its time falls in through the newest bar, earlier bars read none, and in replay it is empty.
- chart_stats reads Chart Stats and candle_stats reads On Candle Stats: one value per row the indicator shows, on each bar, named Volume, Delta, Delta %, Cumulative Delta, Bid Volume, Ask Volume, Max Delta, Min Delta, Trades, Delta Trades, Volume per Second or Candle Time. Only the rows switched on in the indicator exist. The values are the same at every zoom.
- dealers_flow: one value per line the chart draws on the bar, named Convexity, GEX or DEX, with spot the price the line is drawn at. Each bar carries only its own data. Not in replay, and it needs your GEXBot key.
- cot: one value per visible COT indicator, named by that indicator's label, such as COT Commercial or COT Index (Retail), with change its change from the week before. A report is readable only from its release, never from its report date, and released() is 1 on the bar a new report becomes active.
- net_gex: the Net GEX line as a step: each bar reads the newest point from before the next bar starts, the forming bar the newest so far. A bar before the first point reads none. It needs your GEXBot key.
let delta_row: int = chart_stats.find("Delta %")
let strong_bar: bool = delta_row >= 0 && math.abs(chart_stats.value(delta_row)) >= 30
plot.candle_color(strong_bar, "#F59E0B", 0.6)
let net: int = orderflow_stats.find("DEX Net 0DTE")
plot.label(str.concat("DEX NET 0DTE ", format.compact(orderflow_stats.value(net)), " NET GEX ", format.compact(net_gex.value(0))), "#E5E7EB")Candles: Overlay Chart and HFT candles
| Signature | Returns |
|---|---|
| overlay_chart.available() -> bool | Whether a visible Overlay Chart indicator is on this chart |
| overlay_chart.count() -> int | How many candles this bar can read |
| overlay_chart.open(index: int) -> float | Open of that candle, index 0 the newest |
| overlay_chart.high(index: int) -> float | Its high |
| overlay_chart.low(index: int) -> float | Its low |
| overlay_chart.close(index: int) -> float | Its close |
| overlay_chart.side(index: int) -> side | BUY for a candle that closed at or above its open, else SELL |
| hft_candles.available() -> bool | Whether a visible HFT candles indicator is on this chart |
| hft_candles.count() -> int | How many candles this bar can read |
| hft_candles.open(index: int) -> float | Open of that candle, index 0 the newest |
| hft_candles.high(index: int) -> float | Its high |
| hft_candles.low(index: int) -> float | Its low |
| hft_candles.close(index: int) -> float | Its close |
| hft_candles.side(index: int) -> side | BUY for a candle that closed at or above its open, else SELL |
- Both list their candles newest first.
- overlay_chart: the second instrument's candles, up to five. Index 0 is the most recent overlay candle whose span has ended at or before this bar, 1 the one before it; a candle appears only once its span ended. On the newest bar the candle in progress is read as the chart draws it. The first visible Overlay Chart is read.
- hft_candles: index 0 is the higher timeframe candle this bar belongs to, built from its bars up to and including this one; then the finished candles before it, as many as the indicator shows. A finished candle's final values are never on a bar inside it but its last.
let htf_up: bool = hft_candles.available() && hft_candles.side(0) == "BUY"
let prev_high: float = hft_candles.high(1)
plot.hline(prev_high, "#6B7280", 1, "dashed", "Prior HTF high")
plot.candle_color(htf_up, "#22C55E", 0.25)
plot.marker(overlay_chart.count() > 1 && overlay_chart.close(0) > overlay_chart.high(1), high, "#3B82F6", "diamond", "above", 8, 4)Orderflow marks: Big Trades MBO, Iceberg MBO, Speed of Tape
| Signature | Returns |
|---|---|
| bigtrades_mbo.available() -> bool | Whether a visible Big Trades MBO indicator is on this chart |
| bigtrades_mbo.count() -> int | How many squares sit on this bar |
| bigtrades_mbo.price(index: int) -> float | The price it is drawn at |
| bigtrades_mbo.size(index: int) -> float | Its size in contracts |
| bigtrades_mbo.side(index: int) -> side | BUY or SELL |
| bigtrades_mbo.time(index: int) -> float | Its time, epoch milliseconds |
| iceberg_mbo.available() -> bool | Whether a visible Iceberg MBO indicator is on this chart |
| iceberg_mbo.count() -> int | How many points sit on this bar |
| iceberg_mbo.price(index: int) -> float | The price it is drawn at |
| iceberg_mbo.size(index: int) -> float | Its size in contracts |
| iceberg_mbo.side(index: int) -> side | BUY or SELL |
| iceberg_mbo.time(index: int) -> float | Its time, epoch milliseconds |
| speed_of_tape.available() -> bool | Whether a visible Speed of Tape indicator is on this chart |
| speed_of_tape.count() -> int | 1 when the panel draws a candle on this bar, else 0 |
| speed_of_tape.value(index: int) -> float | The candle's body, index 0 |
| speed_of_tape.peak(index: int) -> float | Its wick |
| speed_of_tape.side(index: int) -> side | The side the candle is coloured as |
| speed_of_tape.buy_share(index: int) -> float | The buyers' share the colour shows, from 0 to 1 |
- bigtrades_mbo: one record per square Big Trades MBO draws, over all loaded bars, on the bar of the order's last print, where its size is final: price where the square is drawn, size the contracts the order took, side the aggressor side, time the instant the square is drawn at. In replay an order not finished at the playhead is not there yet.
- iceberg_mbo: one record per point Iceberg MBO marks, a bar and a price: price, size the contracts filled there, side the order's side, time its first fill there. A point appears only from the bar by which its order had become an iceberg, even though the chart then draws its arrows back on earlier bars.
- speed_of_tape: one record on each bar where the Speed of Tape panel draws a candle; a bar its filter hides has none. Each bar reads only its own tape; the forming bar develops.
- For the raw data behind them, read mbo.* and tape.* directly.
let big: bool = bigtrades_mbo.count() > 0 && bigtrades_mbo.size(0) >= 100
plot.dot(big && bigtrades_mbo.side(0) == "BUY", bigtrades_mbo.price(0), "#22C55E", 8)
plot.dot(big && bigtrades_mbo.side(0) == "SELL", bigtrades_mbo.price(0), "#EF4444", 8)
plot.marker(iceberg_mbo.count() > 0, iceberg_mbo.price(0), "#F59E0B", "square", "below", 7, 2)
plot.histogram(speed_of_tape.value(0), "#22C55E", "#EF4444")