Bump org.questdb:questdb from 9.2.2 to 9.3.3 in /modules/questdb by dependabot[bot] · Pull Request #11537 · testcontainers/testcontainers-java
9.3.3
QuestDB 9.3.3
QuestDB 9.3.3 is a feature-rich release introducing HORIZON JOIN for markout analysis, a new twap() aggregate, SQL-standard WINDOW definitions, JIT compilation on ARM64, and file-based secrets for Kubernetes deployments. It also brings significant performance improvements across Parquet I/O, parallel GROUP BY, UNION queries, and ORDER BY on computed expressions.
For any questions or feedback, please join us on Slack or on Discourse.
See also our prettier release notes page.
Highlights
HORIZON JOIN for markout analysis
HORIZON JOIN is a new join type designed for markout analysis — a common financial analytics pattern where you measure how prices or metrics evolve at specific time offsets relative to events like trades or orders.
For each row in the left-hand table and each offset in the horizon, the join computes left_timestamp + offset and performs an ASOF match against the right-hand table. Results are implicitly grouped by the horizon offset and any specified keys, with aggregate functions applied across all matched rows.
Here's an example measuring post-trade price impact at 1-second intervals up to 60 seconds:
SELECT h.offset / 1_000_000 AS horizon_sec, t.sym, avg(m.mid) AS avg_mid FROM trades AS t HORIZON JOIN mid_prices AS m ON (t.sym = m.sym) RANGE FROM 1s TO 60s STEP 1s AS h ORDER BY t.sym, horizon_sec
You can also use LIST for non-uniform horizons and negative offsets to look at pre-event behavior:
SELECT h.offset / 1_000_000 AS horizon_sec, t.sym, avg(m.mid - t.price) AS avg_markout FROM trades AS t HORIZON JOIN mid_prices AS m ON (t.sym = m.sym) LIST (-5s, -1s, 0, 1s, 5s, 30s, 1m) AS h ORDER BY t.sym, horizon_sec
The horizon pseudo-table exposes h.offset (raw microsecond value) and h.timestamp (the computed left_timestamp + offset), which can be used in expressions and grouping.
twap() time-weighted average price
The new twap(price, timestamp) aggregate computes the time-weighted average price using step-function integration: each price is held constant until the next observation, and the TWAP is the area under the step function divided by the total time span. It supports parallel GROUP BY and SAMPLE BY with FILL modes.
SELECT symbol, twap(price, timestamp) AS twap_price FROM trades WHERE timestamp IN today() SAMPLE BY 1h;
... (truncated)