---
title: "What you can read"
description: "A wrun indicator reads the market under the candles. Every level of the order book, buy and sell volume as the exchange tagged each trade, volume at each price…"
order: 9
section: "core-concepts"
---

<!-- source: docs/indicators/core-concepts/what-you-can-read.md; generated by packages/cli/scripts/gen-indicator-docs.ts, do not edit -->

# What you can read

A wrun indicator reads the market under the candles. Every level of the
order book, buy and sell volume as the exchange tagged each trade, volume
at each price and in each trade size, open interest, funding and
liquidations, the live options chain with its greeks, ETF flows and
economic series: each reaches your code as numbers, lined up bar for bar
with the chart. One `input` line asks for a feed and `onBar()` reads it,
with no fetch call and no network.

**What you can build from these feeds:**

- **Absorption.** The bars where heavy buying or selling failed to move
  price, from the exchange's own trade tags
  ([Absorption](../cookbook/absorption.md)).
- **A value area.** Volume at every price, folded into a point of control
  and a value area on the price axis
  ([Volume profile and value area](../cookbook/volume-profile-value-area.md)).
- **Positioning regimes.** Open interest against price, split into new
  longs, new shorts, short covering and long closing
  ([Positioning regimes](../cookbook/positioning-regimes.md)).
- **Liquidation bursts.** Forced buying and selling in USD, tagged on
  price when one side jumps past its norm
  ([Liquidation bursts](../cookbook/liquidation-bursts.md)).
- **A live gamma map.** Gamma at every strike, the flip and the call and
  put walls from the options chain, and whether dealers are long or short
  gamma where spot trades ([Gamma map](../cookbook/gamma-map.md)).
- **Book walls.** The heavier side of the order book near the price, the
  dollars resting by distance from the mid and the biggest bid and ask
  walls, kept current on the live bar
  ([Order book HUD](../cookbook/order-book-hud.md)).
- **ETF flows.** Each day's net spot-ETF flow under the chart, with the
  running total ([ETF flows](../cookbook/etf-flows.md)).

| Group | What you get | Charts |
| --- | --- | --- |
| [Order flow](#order-flow) | Buy and sell volume, as the exchange tagged each trade | Crypto, prediction markets |
| | The footprint: buy and sell at each price | Crypto, prediction markets |
| | Volume by trade size | Crypto |
| | The order book, up to 500 levels a side | Crypto, prediction markets |
| | Long and short liquidations | Crypto perpetuals |
| [Positioning](#positioning) | Open interest | Crypto perpetuals, prediction markets |
| | Funding and the long/short ratio | Crypto perpetuals |
| [Options and volatility](#options-and-volatility) | Implied volatility, skew and DVOL | BTC, ETH |
| | Options open interest and volume | BTC, ETH |
| | The options chain, with greeks | Any coin an options venue lists |
| [Beyond the venue](#beyond-the-venue) | Spot-ETF flows, holdings and premium | BTC, ETH, SOL |
| | Ethena collateral | BTC, ETH |
| | Bitfinex margin funding | Coins Bitfinex lends |
| | Token supply, economic series, Binance's treasury | Every chart |
| | Polymarket odds | Crypto, prediction markets |
| [Price and time](#price-and-time) | Candles, and each bar's time, trade date and session | Every chart |
| [Other markets and timeframes](#other-markets-and-timeframes) | Another market's candles: crypto, stocks, forex, gold and silver | Every chart |
| | A coarser timeframe, or its closed candles as a stream | Every chart |
| | The finer bars inside each bar | Charts of 2 minutes and up |

## One line per feed

**Name a feed once at the top of the file. Read this bar's value in
`onBar()`.**

![Every feed on the chart's rows: the candles set one row per bar; buy and sell volume and open interest give each row its numbers; a daily ETF flow lands on the first bar of its day and the bars after it carry it; onBar() runs once per row and reads every feed on that row, the column circled in orange](/wrun/images/diagrams/read-lanes.svg)

1. **Candles**: the chart's own bars set the rows, one per bar.
2. **Buy and sell volume**: two numbers on every row, buyers up and
   sellers down.
3. **Open interest**: one number on every row.
4. **ETF flow**: one number a day. It lands on the day's first bar, and
   the bars after it carry it.
5. **`onBar()`** runs once per row and reads every feed on that row.

```typescript
// at the top of the file: the feed, under a name you pick
input("oi", oi.close);
// inside onBar(): this bar's value
const oi = in_oi();
```

Knobs appear only when a feed has a choice to make: a side, a tenor, a
fund, a venue.

## Order flow

**Who bought, who sold, at which price and in what size, and what still
rests in the book.**

```typescript
// buy and sell volume, in coins
input("buy", trades.volume, { side: "BUY" });
input("sell", trades.volume, { side: "SELL" });
// the footprint: [low, high, buy, sell] at each price
input("profile", volume_profile.cells, { max_cells: 8192 });
// [bucket, buy_usd, sell_usd, buy_count, sell_count] per size
input("sizes", trade_volume_by_size.cells, { max_cells: 7 });
// the book: [price, size, side] per level
input("book", book.cells, { max_cells: 1000, block_size: 10 });
// liquidations in USD, both sides unless side picks one
input("liq", liquidations.liquidations, { missing: "zero" });
```

Buy minus sell, summed bar after bar, is CVD. Size buckets run from 1,
trades under 1K USD, to 7, trades of 10M and up, each fill at its own
size; a long is liquidated by a forced sell, so `side: "SELL"` reads
longs.

## Positioning

**Who holds the market, what holding it costs, and which way they lean.**

```typescript
// open interest, in USD
input("oi", oi.close, { missing: "nan" });
// the funding rate, in percent per hour
input("funding", funding.rate_close, { missing: "zero" });
// longs over shorts, every account
input("ls", long_short_ratio.total_account, { missing: "nan" });
```

Funding is normalized to one hour, so venues with different funding
intervals compare. The long/short ratio counts every account, or the
venue's top traders with `top_trader_account` or `top_trader_position`,
on charts of 5 minutes or coarser.

## Options and volatility

**What the options market prices in, by tenor and by strike.**

```typescript
// implied volatility and skew on Deribit, one tenor each
input("iv", implied_volatility.implied_volatility,
  { tenor: "ONE_M" });
input("skew", skew.skew, { tenor: "ONE_M", delta: 25 });
// the volatility index, DVOL, in index points
input("dvol", volatility_index.close);
// put open interest on Deribit, call volume on Binance
input("put_oi", options_oi.puts);
input("call_vol", options_volume.calls, { venue: "binance" });
// every listed contract, on the live bar
input("chain", options_chain.cells, { max_cells: 2000 });
```

Tenors are `ONE_W`, `ONE_M`, `TWO_M`, `THREE_M` and `SIX_M`, and skew's
`delta` is 5, 15, 25 or 35. The chain fills the live bar only, one
`[strike, expiry_ms, side, oi, gamma, delta, mark_iv, underlying,
multiplier, vega]` row per contract.

## Beyond the venue

**What moves the coin from outside the exchange: ETF money, supply,
rates and the odds.**

```typescript
// spot-ETF flow (USD, daily), holdings (coins), premium (%)
input("flow", etf_flow.flow_usd, { fund: "all", missing: "nan" });
input("held", etf_holdings.holdings, { fund: "all" });
input("premium", etf_premium.premium_rate, { fund: "IBIT" });
// Ethena collateral in USD; Bitfinex funding provided
input("ethena", ethena_positions.collateral);
input("provided", bitfinex_funding.funding_size);
// market cap, daily; the US 10-year yield; Binance's own BTC
input("mcap", token_supply.marketcap, { token: "Bitcoin" });
input("us10y", economic.value,
  { publisher: "FRED", series: "DGS10" });
input("treasury", treasury_balance.balance, { asset: "BTC" });
// a Polymarket market's odds, 0 to 1, by condition id
input("yes", odds.close, { symbol: "0x...", outcome: "YES" });
```

A token is named the way its series spells it (`Bitcoin`, never `BTC`),
and a Polymarket market by its condition id. A day's ETF flow is known
only after the US session, so on an intraday chart it shows the day, not
a signal you had at the open.

## Price and time

**The chart's candles and clock; the candle needs no input line.**

```typescript
// this bar's candle
bar.open(); bar.high(); bar.low(); bar.close(); bar.volume();
// its open, in epoch seconds UTC
bar.time();
// the exchange's trade date
input("day", time.trade_date);
// 1 regular, 2 pre-market, 3 after-hours, 0 closed
input("phase", time.session);
```

On US stocks the session follows New York's pre-market, regular and
after-hours sessions; a market without sessions reads `1` on every bar.

## Other markets and timeframes

**Another market beside yours, a higher timeframe, or the bars inside
each bar.**

```typescript
// another market's candles
input("btc", ohlcv.close,
  { symbol: "BTCUSDT", exchange: "BINANCE_FUTURES" });
// a coarser timeframe, and its closed candles as a stream
input("daily", ohlcv.close, { interval: "1d" });
input("d", candles.cells, { interval: "1d", bars: 400 });
// the finer bars inside each bar
input("m1", intrabar.cells, { interval: "1m", max_cells: 60 });
```

Only candle feeds take a market pin, `symbol` and `exchange` together: a
crypto market, a US stock or ETF (`POLYGON`), a forex pair, gold or silver
(`FX_OTC`, `XAU/USD`, `XAG/USD`), never a CME market. A coarser candle counts only once it
closes, so history shows what you would have seen live.

## What each chart has

**Perpetuals carry the most. Stocks and forex carry candles and a few
series.**

| Feeds | Crypto perpetual | Crypto spot | Prediction market | US stocks and forex | CME futures |
| --- | --- | --- | --- | --- | --- |
| Order flow | ● | ◐ no liquidations | ◐ trades, footprint, book | ○ | ○ |
| Positioning | ● | ○ | ◐ open interest | ○ | ○ |
| Options | ◐ by coin | ◐ by coin | ○ | ○ | ○ |
| Beyond the venue | ◐ by coin | ◐ by coin | ◐ odds, supply, economic, treasury | ◐ supply, economic, treasury | ○ |
| Price and time | ● | ● | ● | ● | ○ |
| Other markets | ● | ● | ● | ● | ○ |

On CME futures only OpenMarket's official indicators run; your drafts and
other authors' indicators do not. A stock traded on a crypto venue is a
crypto chart: the venue decides what a chart has, not the ticker.

## Blocks, not numbers

**A `.cells` feed hands you the whole bar: every level of the book, every
price of the footprint.**

![One number per bar beside a block per bar: open interest gives each bar one value, read with in_oi(); the book gives the circled bar a block, read with in_book_view() as a flat run of numbers where every three, price, size and side, make one level, so the loop steps i by three](/wrun/images/diagrams/read-blocks.svg)

1. **One number per bar**: open interest gives every bar a single value,
   read with `in_oi()`.
2. **A block per bar**: the book gives the circled bar a run of numbers,
   read with `in_book_view()`.
3. **Rows of three**: every three numbers are one level,
   `[price, size, side]`, with `+1` a bid and `-1` an ask.
4. **`i += 3`**: the loop steps one row at a time, up to the count
   `in_book_cells()` returns.

```typescript
function onBar(): void {
  const n = in_book_cells(); // this bar's count: 0 empty, -1 none
  if (n <= 0) return;
  const cells = in_book_view(); // the block itself, no copy
  for (let i = 0; i + 2 < n; i += 3) {
    const price = cells[i];
    const size = cells[i + 1];
    const side = cells[i + 2]; // +1 a bid, -1 an ask
  }
}
```

Every block reads the same way, stepping by its row's width: 4 for the
footprint, 5 for size buckets, 6 for candles, 10 for the chain. Only the
first `n` numbers are this bar's, so bound every loop by the count.

A block larger than `max_cells` stops the run instead of being cut. The
first input sets the rows and cannot be a block, so a file that reads
blocks starts with `input("close", ohlcv.close);`.

## When a bar has no reading

**`missing` decides what an empty bar reads: the last value, `NaN` or
zero.**

```typescript
// "carry", the default: the last value
input("funding", funding.rate_close);
// "nan": a bar without a reading reads NaN, never a guess
input("oi", oi.close, { missing: "nan" });
// "zero": a quiet bar reads 0
input("liq", liquidations.liquidations, { missing: "zero" });
```

Blocks never carry: a bar without one gets an empty block. A feed the
chart cannot serve on this market stops the run and names the feed, on
the indicator's legend and in the editor's Console.

## Four feeds, one file

**Taker delta, the change in open interest and liquidations, in USD per
bar.**

```typescript sample=gs-what-you-can-read
input("close", ohlcv.close); // first: it sets the rows
input("buy", trades.volume, { side: "BUY" }); // in coins
input("sell", trades.volume, { side: "SELL" });
input("oi", oi.close, { missing: "nan" }); // in USD
input("liq", liquidations.liquidations, { missing: "zero" });
output("delta", histogram, lower,
  { color: "#94a3b8", label: "Delta, USD", format: "si" });
output("oi_change", line, lower,
  { color: "#c2410c", label: "OI change, USD", format: "si" });
output("liquidated", line, lower,
  { color: "#64748b", label: "Liquidated, USD", format: "si" });

let lastOi = NaN; // open interest on the last bar that had one

function onBar(): void {
  const close = bar.close();
  if (isNaN(close)) return;
  out_delta((in_buy() - in_sell()) * close); // coins to USD
  const oi = in_oi();
  out_oi_change(oi - lastOi); // NaN until two readings
  if (!isNaN(oi)) lastOi = oi;
  out_liquidated(in_liq());
}
```

Paste it under the `//@lang=wrun-ts` marker and press **Run** on a crypto
perpetual chart. On spot, open interest reads `NaN` and liquidations zero,
as their `missing` knobs say.

The `close` line stays first: it sets the rows the other feeds line up
with, and `bar.close()` reads through it. Every knob, unit and edge case
is on [Data sources](data-sources.md); pins are on
[Multi-source](multi-source.md) and
[Multi-timeframe](multi-timeframe.md).
