Documentation Index
Fetch the complete documentation index at: https://mintlify.com/questdb/questdb/llms.txt
Use this file to discover all available pages before exploring further.
QuestDB provides specialized finance functions for analyzing orderbook data, market microstructure, and trading metrics.
Price Functions
mid
Calculates mid price from bid and ask.
Signature: mid(DD)
Parameters:
- First
D - Bid price
- Second
D - Ask price
Returns: DOUBLE
Formula: (bid + ask) / 2
Example:
SELECT mid(bid_price, ask_price) as mid_price
FROM orderbook;
-- Result: 150.125
SELECT
timestamp,
symbol,
mid(bid, ask) as mid_price
FROM level1_quotes
SAMPLE BY 1s;
weighted_mid
Calculates weighted mid price using bid and ask sizes.
Signature: weighted_mid(DDDD)
Parameters:
- First
D - Bid price
- Second
D - Ask price
- Third
D - Bid size
- Fourth
D - Ask size
Returns: DOUBLE
Formula: (bid * ask_size + ask * bid_size) / (bid_size + ask_size)
Example:
SELECT weighted_mid(
bid_price,
ask_price,
bid_size,
ask_size
) as weighted_mid_price
FROM orderbook;
SELECT
symbol,
weighted_mid(bid, ask, bid_qty, ask_qty) as wmid
FROM quotes
WHERE timestamp > now() - INTERVAL '1' HOUR;
Spread Functions
spread
Calculates bid-ask spread.
Signature: spread(DD)
Parameters:
- First
D - Bid price
- Second
D - Ask price
Returns: DOUBLE
Formula: ask - bid
Example:
SELECT spread(bid_price, ask_price) as spread
FROM orderbook;
-- Result: 0.25
SELECT
symbol,
avg(spread(bid, ask)) as avg_spread
FROM quotes
GROUP BY symbol;
spread_bps
Calculates bid-ask spread in basis points.
Signature: spread_bps(DD)
Parameters:
- First
D - Bid price
- Second
D - Ask price
Returns: DOUBLE
Formula: 10000 * (ask - bid) / mid(bid, ask)
Example:
SELECT spread_bps(bid_price, ask_price) as spread_bps
FROM orderbook;
-- Result: 16.66 (basis points)
SELECT
symbol,
avg(spread_bps(bid, ask)) as avg_spread_bps,
min(spread_bps(bid, ask)) as min_spread_bps,
max(spread_bps(bid, ask)) as max_spread_bps
FROM quotes
WHERE timestamp > '2024-03-15T00:00:00Z'
GROUP BY symbol
ORDER BY avg_spread_bps;
Volume-Weighted Metrics
vwap
Calculates Volume-Weighted Average Price.
Signature: vwap(DD) - aggregation function
Parameters:
- First
D - Price
- Second
D - Volume/quantity
Returns: DOUBLE
Formula: sum(price * volume) / sum(volume)
Example:
SELECT vwap(price, quantity) as vwap
FROM trades
WHERE symbol = 'AAPL'
AND timestamp > '2024-03-15T00:00:00Z';
-- Result: 150.234
-- VWAP by hour
SELECT
timestamp,
symbol,
vwap(price, quantity) as hourly_vwap
FROM trades
SAMPLE BY 1h ALIGN TO CALENDAR;
-- VWAP vs price deviation
SELECT
symbol,
price,
vwap(price, quantity) OVER (PARTITION BY symbol) as daily_vwap,
(price - vwap(price, quantity) OVER (PARTITION BY symbol)) /
vwap(price, quantity) OVER (PARTITION BY symbol) * 100 as deviation_pct
FROM trades;
twap
Calculates Time-Weighted Average Price.
Signature: twap(DN) - aggregation function
Parameters:
Returns: DOUBLE
Formula: Time-weighted average accounting for duration at each price
Example:
SELECT twap(price, timestamp) as twap
FROM quotes
WHERE symbol = 'AAPL'
AND timestamp > '2024-03-15T00:00:00Z';
-- Result: 150.187
-- TWAP by minute
SELECT
timestamp,
symbol,
twap(mid(bid, ask), timestamp) as minute_twap
FROM quotes
SAMPLE BY 1m;
-- Compare VWAP vs TWAP
SELECT
symbol,
vwap(price, quantity) as vwap,
twap(price, timestamp) as twap,
vwap(price, quantity) - twap(price, timestamp) as vwap_twap_diff
FROM trades
GROUP BY symbol;
Orderbook Level Functions
level_price
Extracts price at specific orderbook level.
Signature: level_price(AI)
Parameters:
A - Array of price levels (DOUBLE[])
I - Level index (0-based)
Returns: DOUBLE
Example:
-- Assuming orderbook has bid_prices and ask_prices as arrays
SELECT
symbol,
level_price(bid_prices, 0) as best_bid,
level_price(ask_prices, 0) as best_ask,
level_price(bid_prices, 1) as bid_level_2,
level_price(ask_prices, 1) as ask_level_2
FROM orderbook_snapshot;
level_size
Extracts size at specific orderbook level.
Signature: level_size(AI)
Parameters:
A - Array of size levels (DOUBLE[])
I - Level index (0-based)
Returns: DOUBLE
Example:
SELECT
symbol,
level_size(bid_sizes, 0) as best_bid_size,
level_size(ask_sizes, 0) as best_ask_size
FROM orderbook_snapshot;
Usage Examples
Market Quality Analysis
SELECT
symbol,
count() as quote_count,
avg(spread(bid, ask)) as avg_spread,
avg(spread_bps(bid, ask)) as avg_spread_bps,
stddev(spread_bps(bid, ask)) as spread_volatility,
avg(mid(bid, ask)) as avg_mid_price
FROM quotes
WHERE timestamp BETWEEN '2024-03-15T09:30:00Z' AND '2024-03-15T16:00:00Z'
GROUP BY symbol
ORDER BY avg_spread_bps;
Intraday VWAP Comparison
SELECT
timestamp,
symbol,
price,
vwap(price, quantity) as current_vwap,
price - vwap(price, quantity) as price_vs_vwap,
(price - vwap(price, quantity)) / vwap(price, quantity) * 100 as deviation_pct
FROM trades
WHERE symbol = 'AAPL'
AND timestamp > '2024-03-15T09:30:00Z'
SAMPLE BY 5m;
Execution Quality Report
SELECT
trader_id,
symbol,
count() as trade_count,
sum(quantity) as total_quantity,
vwap(price, quantity) as execution_vwap,
avg(price) as avg_price,
min(price) as best_price,
max(price) as worst_price
FROM executions
WHERE timestamp > '2024-03-15T00:00:00Z'
GROUP BY trader_id, symbol;
Spread Analysis by Time of Day
SELECT
hour(timestamp) as hour,
symbol,
count() as quote_count,
avg(spread_bps(bid, ask)) as avg_spread_bps,
percentile(spread_bps(bid, ask), 50) as median_spread_bps,
percentile(spread_bps(bid, ask), 95) as p95_spread_bps
FROM quotes
WHERE timestamp > '2024-03-01T00:00:00Z'
GROUP BY hour(timestamp), symbol
ORDER BY symbol, hour;
Orderbook Imbalance
SELECT
timestamp,
symbol,
bid_size,
ask_size,
(bid_size - ask_size) / (bid_size + ask_size) as imbalance,
CASE
WHEN (bid_size - ask_size) / (bid_size + ask_size) > 0.2 THEN 'BUY_PRESSURE'
WHEN (bid_size - ask_size) / (bid_size + ask_size) < -0.2 THEN 'SELL_PRESSURE'
ELSE 'BALANCED'
END as market_pressure
FROM orderbook
WHERE symbol = 'AAPL'
AND timestamp > now() - INTERVAL '1' HOUR;
Multi-Level Orderbook Analysis
SELECT
symbol,
level_price(bid_prices, 0) as bid_1,
level_price(bid_prices, 1) as bid_2,
level_price(bid_prices, 2) as bid_3,
level_size(bid_sizes, 0) as bid_size_1,
level_size(bid_sizes, 1) as bid_size_2,
level_size(bid_sizes, 2) as bid_size_3,
level_price(ask_prices, 0) as ask_1,
level_price(ask_prices, 1) as ask_2,
level_price(ask_prices, 2) as ask_3,
level_size(ask_sizes, 0) as ask_size_1,
level_size(ask_sizes, 1) as ask_size_2,
level_size(ask_sizes, 2) as ask_size_3
FROM orderbook_snapshot
WHERE timestamp = latest(timestamp) BY symbol;
VWAP and TWAP
- Both functions are implemented as efficient aggregations
- Use with SAMPLE BY for time-bucketed calculations
- VWAP uses SIMD acceleration for large datasets
Orderbook Functions
- Array-based level functions have O(1) access time
- Suitable for real-time orderbook snapshots
- Consider using SAMPLE BY for historical analysis
Best Practices
- Use SAMPLE BY for time-series aggregations
- Filter by timestamp ranges for better performance
- Index symbol columns for faster GROUP BY operations
- Use designated timestamp for proper time-ordered operations
NULL Handling
- Functions return NULL if any price input is NULL
- VWAP and TWAP skip NULL values in aggregation
- Spread functions require both bid and ask to be non-NULL
See Also