Live formulas: the reference
What is a live formula?
A measure you write yourself from order book and trade data, computed on our side in real time across the major venues and streamed to you every second or at the interval you choose. You can be notified when it crosses a value you set. Live formulas are part of the Ultra plan. The easiest way to write one is to ask the agent; over the API, send it to POST /v1/formulas and stream it from wss://realtime.blackforge.so/v1/stream.
Writing a formula
- Pairs are written
venue:SYMBOL, with the symbol exactly as the venue spells it:binance:BTCUSDT,okx:BTC-USDT,gate:ETH_USDT,kraken:XBTUSD. A formula can read pairs from different venues. - Windows are written in seconds or minutes, from
1sto60s(1m). - Operators:
+ - * / ^, comparisons< <= > >= == !=(true is 1, false is 0), andand,or,not. - Empty values: when there is no number (no mid on a one-sided book, no print in a window, an order the book cannot fill) the value is empty, never zero, and its flags say why.
Examples
mid(binance:BTCUSDT) - mid(okx:BTC-USDT): The price gap between two venues, live.(mid(binance:BTCUSDT) / mid(coinbase:BTC-USD) - 1) * 10000: The same gap in basis points.imbalance(binance:ETHUSDT, 50): How evenly the book is balanced within 0.5% of the mid.buyVol(binance:SOLUSDT, 60s) / max(sellVol(binance:SOLUSDT, 60s), 1): Taker buying against selling over the last minute.buyCost(binance:BTCUSDT, 50000) - buyCost(okx:BTC-USDT, 50000): Which venue fills a $50k market buy cheaper.avgOver(spreadBps(kraken:XBTUSD), 1m): The average spread over the last minute.
Functions
Order book, read at the value time
From the live book of one pair. Prices in the quote asset, sizes in the base asset.
| Function | What it returns | Unit |
|---|---|---|
bid(pair) | Best bid price held. | quote |
ask(pair) | Best ask price held. | quote |
bidQty(pair) | Size at the best bid. | base |
askQty(pair) | Size at the best ask. | base |
mid(pair) | Midpoint of best bid and best ask. | quote |
spread(pair) | Best ask minus best bid. | quote |
spreadBps(pair) | Spread as basis points of the mid. | bps |
bidLevels(pair) | Number of bid levels held. | count |
askLevels(pair) | Number of ask levels held. | count |
quoteUsd(pair) | The quote asset to USD rate held for the pair. | USD per quote |
last(pair) | Price of the latest trade ever seen. | quote |
lastAge(pair) | Seconds since the latest trade. | s |
Depth and market-order cost
Bands are measured from the mid, inclusive, in whole basis points from 1 to 200. Fills walk the resting orders from the touch, for a USD size from 100 to 1,000,000, and are empty when the book cannot fill the whole size. The number argument must be written in the formula.
| Function | What it returns | Unit |
|---|---|---|
bidDepth(pair, bps) | USD value of bids within bps of the mid (bps a whole number 1 to 200). | USD |
askDepth(pair, bps) | USD value of asks within bps of the mid (bps a whole number 1 to 200). | USD |
imbalance(pair, bps) | (bidDepth - askDepth) / (bidDepth + askDepth) at the same band, from -1 to 1. | ratio |
buyCost(pair, usd) | Cost in bps over the mid of buying usd (100 to 1,000,000) at market on the held book. | bps |
sellCost(pair, usd) | Cost in bps under the mid of selling usd (100 to 1,000,000) at market on the held book. | bps |
Trades over a window
Taker prints in the window, bucketed by the venue’s own event time. The window ends one second before the value’s timestamp, so late prints are counted.
| Function | What it returns | Unit |
|---|---|---|
buyVol(pair, window) | Taker buy volume in quote. | quote |
sellVol(pair, window) | Taker sell volume in quote. | quote |
vol(pair, window) | Total traded volume in quote. | quote |
buyUsd(pair, window) | Taker buy volume in USD. | USD |
sellUsd(pair, window) | Taker sell volume in USD. | USD |
volUsd(pair, window) | Total traded volume in USD. | USD |
buyCount(pair, window) | Number of taker buy trades. | count |
sellCount(pair, window) | Number of taker sell trades. | count |
tradeCount(pair, window) | Number of trades. | count |
netFlow(pair, window) | Taker buy volume minus taker sell volume, in quote. | quote |
buyShare(pair, window) | Taker buy volume as a share of total volume. | ratio |
vwap(pair, window) | Volume weighted average trade price. | quote |
high(pair, window) | Highest trade price. | quote |
low(pair, window) | Lowest trade price. | quote |
open(pair, window) | Price of the earliest trade. | quote |
close(pair, window) | Price of the latest trade. | quote |
maxBuy(pair, window) | Largest single taker buy, in quote. | quote |
maxSell(pair, window) | Largest single taker sell, in quote. | quote |
buyUsdAbove(pair, window, usd) | USD value of taker buys of at least usd each (usd one of 100, 1000, 10000, 100000). | USD |
sellUsdAbove(pair, window, usd) | USD value of taker sells of at least usd each (usd one of 100, 1000, 10000, 100000). | USD |
buyCountAbove(pair, window, usd) | Number of taker buys of at least usd each (usd one of 100, 1000, 10000, 100000). | count |
sellCountAbove(pair, window, usd) | Number of taker sells of at least usd each (usd one of 100, 1000, 10000, 100000). | count |
Book changes over a window
Size placed into and removed from the book, in the quote asset. "Near" means within 1% of the mid when the change happened.
| Function | What it returns | Unit |
|---|---|---|
bidAdded(pair, window) | Quote value added to bid levels (gross). | quote |
askAdded(pair, window) | Quote value added to ask levels (gross). | quote |
bidRemoved(pair, window) | Quote value removed from bid levels (gross). | quote |
askRemoved(pair, window) | Quote value removed from ask levels (gross). | quote |
bidAddedNear(pair, window) | Quote value added to bids within 1% of the mid. | quote |
askAddedNear(pair, window) | Quote value added to asks within 1% of the mid. | quote |
bidRemovedNear(pair, window) | Quote value removed from bids within 1% of the mid. | quote |
askRemovedNear(pair, window) | Quote value removed from asks within 1% of the mid. | quote |
bookChanges(pair, window) | Number of level changes where the size moved, both sides. | count |
Arithmetic
Applied to numbers. Any empty input makes the result empty, except coalesce and if.
| Function | What it returns | Unit |
|---|---|---|
abs(x) | Absolute value. | same as x |
sign(x) | -1, 0 or 1. | same as x |
sqrt(x) | Square root (null below 0). | same as x |
ln(x) | Natural logarithm (null at or below 0). | same as x |
log10(x) | Base 10 logarithm (null at or below 0). | same as x |
exp(x) | e to the power x. | same as x |
floor(x) | Round down. | same as x |
ceil(x) | Round up. | same as x |
pow(x, y) | x to the power y. | same as x |
min(a, b, ...) with 2 to 8 arguments | Smallest argument. | same as arguments |
max(a, b, ...) with 2 to 8 arguments | Largest argument. | same as arguments |
clamp(x, lo, hi) | x limited to the range lo..hi. | same as x |
round(x) or round(x, digits) with digits a whole number 0 to 12 | Round half away from zero, optionally to digits decimals. | same as x |
if(condition, then, else) | then when condition is non-zero, else otherwise (null when condition is null). | same as branches |
coalesce(a, b, ...) with 2 to 8 arguments | First argument that is not null. | same as arguments |
Over time
Sampled at the formula’s own update interval. The total look-back of a formula, windows included, is at most one minute.
| Function | What it returns | Unit |
|---|---|---|
avgOver(x, window) | Mean of the samples of x over the window. | same as x |
minOver(x, window) | Smallest sample of x over the window. | same as x |
maxOver(x, window) | Largest sample of x over the window. | same as x |
stdOver(x, window) | Population standard deviation of the samples of x over the window. | same as x |
change(x, window) | x now minus x one window ago. | same as x |
pctChange(x, window) | Percent change of x over the window. | percent |
Error codes
A formula that cannot be accepted returns one error with a stable code, the position in the formula, and suggestions where there are any.
syntax- The formula could not be read. The error lists what would have been valid at that point.
unknown_function- No function has that name. The error suggests the closest names.
wrong_arity- The function was given the wrong number of arguments. The error states its signature.
wrong_arg_type- An argument has the wrong kind: a pair (venue:SYMBOL), a window (30s, 1m) or a number. Size and band arguments must be numbers written in the formula.
unknown_venue- Pairs start with one of the supported venues, in lowercase.
unknown_symbol- The venue does not list that pair. Symbols are written exactly as the venue spells them; the error suggests close matches.
window_out_of_range- Windows run from 1s to 60s (1m).
window_too_short_for_interval- A window over time must hold at least two samples at the formula’s update interval.
horizon_too_long- The total look-back of the formula, nested windows included, is above one minute.
param_out_of_range- A band, size or rounding argument is outside its range.
too_many_pairs- The formula reads more pairs than your plan allows in one formula.
too_many_params- Too many distinct bands or sizes on one pair.
too_complex- The formula is too large: too many functions, nodes or levels of nesting.
too_long- The formula text is longer than 2,000 characters.
interval_out_of_range- The update interval runs from 1 to 60 seconds.
chained_comparison- Comparisons cannot be chained (a < b < c). Use and: a < b and b < c.
not_numeric- A formula must produce a number.