Joins
Use inner, left, right, outer, semi, anti, cross, and as-of joins. Join on a shared key or map different key names with on { left_key = right_key }.
Language guide
Detailed usage notes for the operations listed in the language reference. For exact grammar and edge-case semantics, use the specification.
Pipelines
Attach a comma-separated clause list to a table. Each clause receives the result of the previous clause. select projects fields or computes aggregations; update adds or replaces fields; filter retains rows; by changes the aggregation context; and order sorts the result.
let totals = trades[
update { notional = price * size },
filter notional > 1000,
select { total = sum(notional), n = count() },
by symbol,
order { total desc }
];
Use rename, distinct, head, and tail for common schema and row-shape operations. A conditional where predicate update { ... } replaces values only on matching rows.
Combining tables
Use inner, left, right, outer, semi, anti, cross, and as-of joins. Join on a shared key or map different key names with on { left_key = right_key }.
Append compatible tables with row binding, or combine columns with column binding when row alignment is intentional.
Use melt to convert wide data to long form and dcast to pivot long data back to a wide table.
let enriched = (trades left join symbols on symbol)[
select { symbol, sector, price, size }
];
Analytics
Aggregate expressions include count, sum, mean, min, max, first, last, median, quantiles, standard deviation, and correlation. With by, they run per group; without it, they reduce the whole table. Grouped update broadcasts a group result back to each row.
For ordered data, use lag, lead, rank functions, cumulative sums and products. Promote an ordered table with as_timeframe, then use window duration for rolling aggregates or resample duration for fixed time buckets.
let tf = as_timeframe(ticks, "ts");
tf[window 5m, update {
vwap = sum(price * size) / sum(size),
volume_5m = rolling_sum(size)
}, by symbol];
Values and expressions
Ibex has static scalar, Series, Table, and TimeFrame types. Use explicit constructors such as Int64(x) and Float64(x) where conversion is required.
Predicates use three-valued logic. Use is_null, fill_null, fill_forward, and fill_backward to inspect and repair missing values.
Declare typed fn functions for reusable expressions. case chooses the first matching branch; map expands repeated fields at compile time inside select and update.
More detail
Built-in signatures and examples.
CSV, Parquet, databases, and streams.
A first end-to-end pipeline.