🛡️ QuestDB 9.0 is here!Read the release blog

Live order book & FX data charts

Real-time order book depth, bid/ask spreads, and quantitative trading analytics

Powered by
QuestDB logoQuestDB
and
Grafana LogoGrafana

Market Depth - EURUSD

Visualizes the order book snapshot for the selected currency pair, showing the price and cumulative volume at each bid and ask level. The area under the green (bids) and red (asks) lines represents market liquidity on both sides, with the mid-price and top volume “walls” highlighted for quick identification of major support and resistance.

WITH snapshot AS (
SELECT timestamp, bids, asks
FROM market_data
WHERE dateadd('m', -10, now()) < timestamp and symbol = 'EURUSD'
ORDER BY timestamp DESC
LIMIT 1
),
bid_levels AS (
SELECT timestamp, 'bid' AS side, bids[1,1] AS price, bids[2,1] AS volume FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,2], bids[2,2] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,3], bids[2,3] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,4], bids[2,4] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,5], bids[2,5] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,6], bids[2,6] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,7], bids[2,7] FROM snapshot
),
ask_levels AS (
SELECT timestamp, 'ask' AS side, asks[1,1] AS price, asks[2,1] AS volume FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,2], asks[2,2] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,3], asks[2,3] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,4], asks[2,4] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,5], asks[2,5] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,6], asks[2,6] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,7], asks[2,7] FROM snapshot
),
bid_cum AS (
SELECT
timestamp,
side,
price,
volume,
SUM(volume) OVER (ORDER BY price DESC) AS cum_volume
FROM bid_levels
WHERE price IS NOT NULL
),
ask_cum AS (
SELECT
timestamp,
side,
price,
volume,
SUM(volume) OVER (ORDER BY price ASC) AS cum_volume
FROM ask_levels
WHERE price IS NOT NULL
)
SELECT * FROM bid_cum
UNION ALL
SELECT * FROM ask_cum
ORDER BY side, price;
Launch in live demo

Market Depth - GBPUSD

Visualizes the order book snapshot for the selected currency pair, showing the price and cumulative volume at each bid and ask level. The area under the green (bids) and red (asks) lines represents market liquidity on both sides, with the mid-price and top volume “walls” highlighted for quick identification of major support and resistance.

WITH snapshot AS (
SELECT timestamp, bids, asks
FROM market_data
WHERE dateadd('m', -10, now()) < timestamp and symbol = 'GBPUSD'
ORDER BY timestamp DESC
LIMIT 1
),
bid_levels AS (
SELECT timestamp, 'bid' AS side, bids[1,1] AS price, bids[2,1] AS volume FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,2], bids[2,2] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,3], bids[2,3] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,4], bids[2,4] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,5], bids[2,5] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,6], bids[2,6] FROM snapshot
UNION ALL SELECT timestamp, 'bid', bids[1,7], bids[2,7] FROM snapshot
),
ask_levels AS (
SELECT timestamp, 'ask' AS side, asks[1,1] AS price, asks[2,1] AS volume FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,2], asks[2,2] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,3], asks[2,3] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,4], asks[2,4] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,5], asks[2,5] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,6], asks[2,6] FROM snapshot
UNION ALL SELECT timestamp, 'ask', asks[1,7], asks[2,7] FROM snapshot
),
bid_cum AS (
SELECT
timestamp,
side,
price,
volume,
SUM(volume) OVER (ORDER BY price DESC) AS cum_volume
FROM bid_levels
WHERE price IS NOT NULL
),
ask_cum AS (
SELECT
timestamp,
side,
price,
volume,
SUM(volume) OVER (ORDER BY price ASC) AS cum_volume
FROM ask_levels
WHERE price IS NOT NULL
)
SELECT * FROM bid_cum
UNION ALL
SELECT * FROM ask_cum
ORDER BY side, price;
Launch in live demo

L2 Market Data · Market Depth Charts · Bid-Ask Spread Analytics

Analyze order book depth level-by-level, compute cumulative volume profiles, and monitor spread in real-time

Spread and Volume per second - EURUSD

Displays a rolling table of the most recent seconds for the selected currency pair, summarizing the current average spread (difference between best ask and best bid) along with the aggregated bid and ask volumes. Use this to monitor how liquidity and price tightness evolve in real time, and spot sudden widening or bursts in traded volume.

SELECT
timestamp AS Time,
avg(asks [ 1, 1 ] - bids [ 1, 1 ]) AS Spread,
sum(bids [ 1, 1 ] * bids [ 2, 1 ]) AS Bid_Volume,
sum(asks [ 1, 1 ] * asks [ 2, 1 ]) AS Ask_Volume
FROM market_data
WHERE dateadd('m', -1, now()) < timestamp AND symbol = 'EURUSD'
SAMPLE BY 1s
ORDER BY timestamp DESC
LIMIT 6;
Launch in live demo

Spread and Volume per second - GBPUSD

Displays a rolling table of the most recent seconds for the selected currency pair, summarizing the current average spread (difference between best ask and best bid) along with the aggregated bid and ask volumes. Use this to monitor how liquidity and price tightness evolve in real time, and spot sudden widening or bursts in traded volume.

SELECT
timestamp AS Time,
avg(asks [ 1, 1 ] - bids [ 1, 1 ]) AS Spread,
sum(bids [ 1, 1 ] * bids [ 2, 1 ]) AS Bid_Volume,
sum(asks [ 1, 1 ] * asks [ 2, 1 ]) AS Ask_Volume
FROM market_data
WHERE dateadd('m', -1, now()) < timestamp AND symbol = 'GBPUSD'
SAMPLE BY 1s
ORDER BY timestamp DESC
LIMIT 6;
Launch in live demo

Purpose-built for FX Order Book Data

Store market depth snapshots with ARRAY columns and query them using capital-markets SQL functions

Top-of-book Levels vs Core Price - EURUSD

Compares the best bid in the order book (from L2 market data) using an ASOF JOIN against the corresponding “core” quote price from upstream sources (e.g., ECNs). Then it finds at which level we could trade the core price bid volume. If no matching level is found, Level and Price will be empty. This table helps detect price alignment issues, latency, or anomalies between your live order book and reference prices provided by liquidity venues.

WITH p AS (
SELECT
timestamp,
bid_price,
bid_volume,
symbol,
ecn
FROM core_price
WHERE dateadd('m', -1, now()) < timestamp AND symbol = 'EURUSD'
LIMIT -6
), levels AS (
SELECT
market_data.timestamp AS md_timestamp,
insertion_point(bids [ 2 ], bid_volume) AS level,
bids [ 1 ] [ insertion_point(bids [ 2 ], bid_volume) ] AS price,
bids [ 2 ] [ insertion_point(bids [ 2 ], bid_volume) ] AS volume,
p.timestamp,
p.bid_price,
p.bid_volume AS bid_volume,
p.ecn
FROM p ASOF JOIN market_data ON symbol
)
SELECT
md_timestamp AS MarketData_Time,
CASE WHEN price IS null THEN null ELSE level end AS Level,
Price,
Volume,
timestamp AS CorePrice_Time,
bid_price AS Bid_Price,
bid_volume1 AS Bid_Volume,
ecn AS ECN
FROM levels;
Launch in live demo

Top-of-book Levels vs Core Price - GBPUSD

Compares the best bid in the order book (from L2 market data) using an ASOF JOIN against the corresponding “core” quote price from upstream sources (e.g., ECNs). Then it finds at which level we could trade the core price bid volume. If no matching level is found, Level and Price will be empty. This table helps detect price alignment issues, latency, or anomalies between your live order book and reference prices provided by liquidity venues.

WITH p AS (
SELECT
timestamp,
bid_price,
bid_volume,
symbol,
ecn
FROM core_price
WHERE dateadd('m', -1, now()) < timestamp AND symbol = 'GBPUSD'
LIMIT -6
), levels AS (
SELECT
market_data.timestamp AS md_timestamp,
insertion_point(bids [ 2 ], bid_volume) AS level,
bids [ 1 ] [ insertion_point(bids [ 2 ], bid_volume) ] AS price,
bids [ 2 ] [ insertion_point(bids [ 2 ], bid_volume) ] AS volume,
p.timestamp,
p.bid_price,
p.bid_volume AS bid_volume,
p.ecn
FROM p ASOF JOIN market_data ON symbol
)
SELECT
md_timestamp AS MarketData_Time,
CASE WHEN price IS null THEN null ELSE level end AS Level,
Price,
Volume,
timestamp AS CorePrice_Time,
bid_price AS Bid_Price,
bid_volume1 AS Bid_Volume,
ecn AS ECN
FROM levels;
Launch in live demo

Extreme Performance

Low-latency, Millions of rows per second, instant analytics at terabyte scale

OHLC - Bids - 5secs - (EURUSD)

Candlestick chart summarizing price action using the best bid from the order book, aggregated into 5-second intervals. Each candlestick shows the open, high, low, and close bid price, along with traded volume. Ideal for visualizing price trends, volatility, and market regime changes over time. Data is queried from a live table and aggregated on the fly.

select
timestamp,
first(bids[1,1]) open,
max(bids[1,1]) high,
min(bids[1,1]) low,
last(bids[1,1]) close,
sum(bids[2,1]) total_volume
from market_data
where dateadd('m', -5, now()) < timestamp and symbol = 'EURUSD'
sample by 5s;
Launch in live demo

OHLC - Bids - 5secs - (GBPUSD)

Candlestick chart summarizing price action using the best bid from the order book, aggregated into 5-second intervals. Each candlestick shows the open, high, low, and close bid price, along with traded volume. Ideal for visualizing price trends, volatility, and market regime changes over time. Data is queried from a live table and aggregated on the fly.

select
timestamp,
first(bids[1,1]) open,
max(bids[1,1]) high,
min(bids[1,1]) low,
last(bids[1,1]) close,
sum(bids[2,1]) total_volume
from market_data
where dateadd('m', -5, now()) < timestamp and symbol = 'GBPUSD'
sample by 5s;
Launch in live demo

Interactive SQL

Click SHOW QUERY to inspect the live QuestDB statements behind every panel

VWAP - RSI 12h - Bollinger Bands (20,2) (EURUSD)

Multi-layered chart, overlaid on OHLC candles, combining three technical indicators for the selected symbol: • VWAP: Shows the Volume-Weighted Average Price, a key benchmark for execution quality. • RSI (12h): The Relative Strength Index, computed over 12-hour rolling windows, highlights overbought/oversold conditions and price momentum. • Bollinger Bands (20,2): Plots a 20-period moving average with ±2 standard deviations, indicating price volatility and potential breakout/reversal zones. Each period is 15 minutes, so the simple moving average (SMA) covers a 6-hour window.

WITH sampled AS (
SELECT
timestamp, symbol,
total_volume,
((open+close)/2) * total_volume AS traded_value
FROM market_data_ohlc_1m
WHERE date_trunc('day', now()) < timestamp
AND
symbol IN 'EURUSD'
), cumulative AS (
SELECT timestamp, symbol,
SUM(traded_value)
OVER (ORDER BY timestamp) AS cumulative_value,
SUM(total_volume)
OVER (ORDER BY timestamp) AS cumulative_volume
FROM sampled
), vwap as (
SELECT timestamp, cumulative_value/cumulative_volume AS vwap FROM cumulative
)
SELECT * FROM vwap;
Launch in live demo

VWAP - RSI 12h - Bollinger Bands (20,2) (GBPUSD)

Multi-layered chart, overlaid on OHLC candles, combining three technical indicators for the selected symbol: • VWAP: Shows the Volume-Weighted Average Price, a key benchmark for execution quality. • RSI (12h): The Relative Strength Index, computed over 12-hour rolling windows, highlights overbought/oversold conditions and price momentum. • Bollinger Bands (20,2): Plots a 20-period moving average with ±2 standard deviations, indicating price volatility and potential breakout/reversal zones. Each period is 15 minutes, so the simple moving average (SMA) covers a 6-hour window.

WITH sampled AS (
SELECT
timestamp, symbol,
total_volume,
((open+close)/2) * total_volume AS traded_value
FROM market_data_ohlc_1m
WHERE date_trunc('day', now()) < timestamp
AND
symbol IN 'GBPUSD'
), cumulative AS (
SELECT timestamp, symbol,
SUM(traded_value)
OVER (ORDER BY timestamp) AS cumulative_value,
SUM(total_volume)
OVER (ORDER BY timestamp) AS cumulative_volume
FROM sampled
), vwap as (
SELECT timestamp, cumulative_value/cumulative_volume AS vwap FROM cumulative
)
SELECT * FROM vwap;
Launch in live demo

Try it yourself

Ready to store FX market data? Follow our tutorial series on building Grafana dashboards

Bid vs Ask Volume (30s) - BBO (1s) - (EURUSD)

Time series chart comparing the aggregated bid and ask volumes over 30-second intervals, alongside the best bid and offer (BBO) price at 1-second granularity. Useful for monitoring shifts in market pressure, liquidity imbalances, and rapid changes in top-of-book pricing.

SELECT
timestamp time,
symbol,
sum(bids [ 1, 1 ] * bids [ 2, 1 ]) AS bid,
-1 * sum(asks [ 1, 1 ] * asks [ 2, 1 ]) AS ask
FROM
market_data
WHERE dateadd('m', -30, now()) < timestamp AND symbol IN 'EURUSD'
SAMPLE BY 30s;
Launch in live demo

Bid vs Ask Volume (30s) - BBO (1s) - (GBPUSD)

Time series chart comparing the aggregated bid and ask volumes over 30-second intervals, alongside the best bid and offer (BBO) price at 1-second granularity. Useful for monitoring shifts in market pressure, liquidity imbalances, and rapid changes in top-of-book pricing.

SELECT
timestamp time,
symbol,
sum(bids [ 1, 1 ] * bids [ 2, 1 ]) AS bid,
-1 * sum(asks [ 1, 1 ] * asks [ 2, 1 ]) AS ask
FROM
market_data
WHERE dateadd('m', -30, now()) < timestamp AND symbol IN 'GBPUSD'
SAMPLE BY 30s;
Launch in live demo

Build your own on QuestDB

High performance ingest & slick visualizations.
Perfect for financial data and real-time analytics.