Live crypto price charts

Real-time prices across 11 crypto pairs including Bitcoin and Ethereum, streamed into QuestDB and queried live.

Stored in QuestDB·Rendered with Grafana·Market data from OKX
LiveHit Show query on any panel for the SQL behind it

Real-time crypto trades and candlestick (OHLC) charts

Trades arriving from OKX as they happen, with five-second OHLC bars off the same tick stream.

Latest trades

Real-time buy and sell orders from OKX, covering exchanges amongst assets.

SELECT
timestamp,
left(symbol, strpos(symbol, '-') - 1) asset,
right(symbol, length(symbol) - strpos(symbol, '-')) counter,
CASE
WHEN side = 'buy' THEN amount
ELSE -amount
END quantity,
CASE
WHEN side = 'buy' THEN -amount * price
ELSE amount * price
END consideration,
CASE
WHEN (now() - timestamp) / 1000000 < 0.3 THEN 'x'
ELSE ''
END new
FROM trades
WHERE dateadd('m', -1, now()) < timestamp
AND (
symbol LIKE '%-USDT'
OR symbol LIKE '%-ETH'
OR symbol LIKE '%-BTC'
)
ORDER BY timestamp DESC
LIMIT 50;
Run in live demo

Candlestick Chart (OHLC) BTC-USDT

An OHLC (Open, High, Low, Close) chart for BTC-USDT, sampled every five seconds over the past 5 minutes.

SELECT
timestamp AS time,
first(price) AS open,
last(price) AS close,
min(price) AS lo,
max(price) AS hi,
sum(amount) AS vol
FROM trades
WHERE symbol = 'BTC-USDT'
AND dateadd('m', -5, now()) < timestamp
SAMPLE BY 5s;
Run in live demo

Trades and moving averages

Individual trades by USD notional. Separately, 10-, 30- and 45-second moving averages of the price.

Real-time trades

Filled exchange orders between crypto assets, with USD notional along the y-axis. Positive values are buy orders, negative are sell orders.

SELECT
timestamp time,
symbol,
CASE
WHEN side = 'buy' THEN amount * price
ELSE -1 * amount * price
END trade
FROM trades
WHERE dateadd('m', -1, now()) < timestamp
AND (symbol LIKE '%-USDT');
Run in live demo

Moving averages BTC-USDT

Moving averages on the price of BTC-USDT in the past 5 minutes, over 10-, 30-, and 45-second windows.

SELECT
timestamp time,
symbol,
price AS priceBtc,
avg(price) OVER (
PARTITION BY symbol ORDER BY timestamp
RANGE BETWEEN 10 seconds PRECEDING AND CURRENT ROW
) movingAvg10Sec,
avg(price) OVER (
PARTITION BY symbol ORDER BY timestamp
RANGE BETWEEN 30 seconds PRECEDING AND CURRENT ROW
) movingAvg30Sec,
avg(price) OVER (
PARTITION BY symbol ORDER BY timestamp
RANGE BETWEEN 45 seconds PRECEDING AND CURRENT ROW
) movingAvg45Sec
FROM trades
WHERE dateadd('m', -5, now()) < timestamp
AND symbol = 'BTC-USDT';
Run in live demo

Crypto trading volume by asset

Traded value per asset, bucketed across the last five minutes.

Volume heatmap

Trade volume (USD notional) distribution per asset for the past 5 minutes.

SELECT
timestamp time,
left(symbol, strpos(symbol, '-') - 1) asset,
sum(abs(amount))
FROM trades
WHERE dateadd('m', -5, now()) < timestamp
AND symbol LIKE '%-USDT'
SAMPLE BY 5s
ORDER BY asset, time;
Run in live demo

VWAP and crypto correlation

Volume-weighted average price today against yesterday, and rolling correlation with ETH.

Rolling BTC-USDT vs ETH-USDT correlation coefficient

Calculation of the Pearson correlation coefficient (ρ) between the prices of BTC-USDT and ETH. Data is sampled every minute over the past 12 hours, and correlation is calculated over hour- and day-long windows.

WITH data AS (
WITH
ETHUSD AS (
SELECT timestamp, last(price) AS price
FROM trades
WHERE dateadd('h', -12, now()) < timestamp AND symbol = 'ETH-USDT'
SAMPLE BY 1s
),
asset AS (
SELECT timestamp, last(price) AS price
FROM trades
WHERE dateadd('h', -12, now()) < timestamp AND symbol = 'BTC-USDT'
SAMPLE BY 1s
)
SELECT ETHUSD.timestamp, corr(ETHUSD.price, asset.price) AS corr
FROM ETHUSD
ASOF JOIN asset
SAMPLE BY 1m
)
SELECT
timestamp,
avg(corr) OVER (
ORDER BY timestamp RANGE BETWEEN 1 hour PRECEDING AND CURRENT ROW
) hourly_corr_rolling,
avg(corr) OVER (
ORDER BY timestamp RANGE BETWEEN 24 hour PRECEDING AND CURRENT ROW
) daily_corr_rolling
FROM data;
Run in live demo

VWAP - Yesterday vs Today - BTC-USDT

Volume Weighted Average Price of BTC-USDT from yesterday compared to today. It uses the `trades_OHLC_15m` materialized view, so data is returned at 15 minute intervals

DECLARE
@symbol := 'BTC-USDT'
WITH
sampled AS (
SELECT
timestamp,
symbol,
volume AS volume,
((open + close) / 2) * volume AS traded_value
FROM trades_OHLC_15m
WHERE timestamp IN yesterday()
AND symbol = @symbol
),
cumulative AS (
SELECT
timestamp,
symbol,
sum(traded_value) OVER (ORDER BY timestamp) AS cumulative_value,
sum(volume) OVER (ORDER BY timestamp) AS cumulative_volume
FROM sampled
)
SELECT timestamp AS time, cumulative_value / cumulative_volume AS vwap_yesterday
FROM cumulative;
Run in live demo
DECLARE
@symbol := 'BTC-USDT'
WITH
sampled AS (
SELECT
timestamp,
symbol,
volume AS volume,
((open + close) / 2) * volume AS traded_value
FROM trades_OHLC_15m
WHERE timestamp IN today()
AND symbol = @symbol
),
cumulative AS (
SELECT
timestamp,
symbol,
sum(traded_value) OVER (ORDER BY timestamp) AS cumulative_value,
sum(volume) OVER (ORDER BY timestamp) AS cumulative_volume
FROM sampled
)
SELECT timestamp AS time, cumulative_value / cumulative_volume AS vwap_today
FROM cumulative;
Run in live demo

Bollinger Bands, Average True Range and RSI

The standard crypto volatility and momentum indicators, over 15-minute and daily bars.

Bollinger Bands BTC-USDT

Bollinger Bands. We are using the moving average over the past 20 closing prices of BTC-USDT at 15 minute intervals, plus/minus twice of the standard deviation. It can help identify volatility. This query uses the `trades_OHLC_15m` materialized view

WITH stats AS (
SELECT
timestamp,
close,
avg(close) OVER (
ORDER BY timestamp
ROWS BETWEEN 19 PRECEDING AND CURRENT ROW
) AS sma20,
avg(close * close) OVER (
ORDER BY timestamp
ROWS BETWEEN 19 PRECEDING AND CURRENT ROW
) AS avg_close_sq
FROM trades_OHLC_15m
WHERE timestamp BETWEEN dateadd('h', -24, now()) AND now()
AND symbol = 'BTC-USDT'
)
SELECT
timestamp AS time,
sma20,
-- sqrt(avg_close_sq - (sma20 * sma20)) as stdev20,
sma20 + 2 * sqrt(avg_close_sq - (sma20 * sma20)) AS upper_band,
sma20 - 2 * sqrt(avg_close_sq - (sma20 * sma20)) AS lower_band
FROM stats
ORDER BY timestamp;
Run in live demo

Average True Range BTC-USDT

This chart shows the 14-period Average True Range (ATR) for BTC-USDT, using 15-minute OHLC bars from the `trades_OHLC_15m` materialized view, over the past 15 days. The ATR measures short-term volatility by averaging the True Range, defined as the greatest of: • High − Low • |High − Previous Close| • |Low − Previous Close| Higher ATR values indicate greater price movement and market volatility; lower values reflect more stable, range-bound behavior.

DECLARE
@symbol := 'BTC-USDT'
WITH
prev_close AS (
SELECT
timestamp, symbol, high, low,
lag(close) OVER (PARTITION BY symbol ORDER BY timestamp) AS prev_close
FROM trades_OHLC_15m
WHERE symbol = @symbol
AND dateadd('d', -15, now()) < timestamp
),
true_range AS (
SELECT
timestamp, symbol,
greatest(
high - low,
abs(high - prev_close),
abs(low - prev_close)
) AS tr
FROM prev_close
)
SELECT
timestamp AS time,
symbol,
avg(tr) OVER (
PARTITION BY symbol ORDER BY timestamp
ROWS BETWEEN 13 PRECEDING AND CURRENT ROW
) AS atr_14
FROM true_range
ORDER BY timestamp;
Run in live demo

Relative Strength Index 14 days - BTC-USDT

14-day RSI (Relative Strength Index) for BTC-USDT using daily closes from the trades_latest_1d table over the selected 1-month range. RSI is calculated by averaging 14 days of gains and losses. Values near 70 suggest overbought conditions; values near 30 suggest oversold. A smoothing window of 14 periods is applied using window functions.

DECLARE
@symbol := 'BTC-USDT'
WITH
price_changes AS (
SELECT
timestamp,
symbol,
close,
close - prev_close price_change
FROM (
SELECT
timestamp,
symbol,
price AS close,
lag(price) OVER (PARTITION BY symbol ORDER BY timestamp) AS prev_close
FROM trades_latest_1d
WHERE dateadd('M', -1, now()) < timestamp
AND symbol = @symbol
)
),
gains_losses AS (
SELECT
timestamp,
symbol,
close,
CASE WHEN price_change > 0 THEN price_change ELSE 0 END AS gain,
CASE WHEN price_change < 0 THEN abs(price_change) ELSE 0 END AS loss
FROM price_changes
),
avg_gains_losses AS (
SELECT
timestamp,
symbol,
close,
avg(gain) OVER (
PARTITION BY symbol ORDER BY timestamp
ROWS BETWEEN 13 PRECEDING AND CURRENT ROW
) AS avg_gain,
avg(loss) OVER (
PARTITION BY symbol ORDER BY timestamp
ROWS BETWEEN 13 PRECEDING AND CURRENT ROW
) AS avg_loss
FROM gains_losses
)
SELECT
timestamp AS time,
symbol,
CASE
WHEN avg_loss = 0 THEN 100
ELSE 100 - (100 / (1 + (avg_gain / nullif(avg_loss, 0))))
END AS rsi_14
FROM avg_gains_losses
ORDER BY timestamp;
Run in live demo

Relative Strength Index 14 days - All Symbols

14-day RSI (Relative Strength Index) computed for all symbols ending in -USDT, -ETH, or -BTC using daily closing prices from the `trades_latest_1d` materialized view. Uses a 14-period rolling window of average gains and losses per symbol. Highlights overbought (>70) or oversold (<30) conditions across assets.

WITH
price_changes AS (
SELECT
timestamp,
symbol,
close,
close - prev_close price_change
FROM (
SELECT
timestamp,
symbol,
price AS close,
lag(price) OVER (PARTITION BY symbol ORDER BY timestamp) AS prev_close
FROM trades_latest_1d
WHERE dateadd('M', -1, now()) < timestamp
AND (
symbol LIKE '%-USDT'
OR symbol LIKE '%-ETH'
OR symbol LIKE '%-BTC'
)
)
),
gains_losses AS (
SELECT
timestamp,
symbol,
close,
CASE WHEN price_change > 0 THEN price_change ELSE 0 END AS gain,
CASE WHEN price_change < 0 THEN abs(price_change) ELSE 0 END AS loss
FROM price_changes
),
avg_gains_losses AS (
SELECT
timestamp,
symbol,
close,
avg(gain) OVER (
PARTITION BY symbol ORDER BY timestamp
ROWS BETWEEN 13 PRECEDING AND CURRENT ROW
) AS avg_gain,
avg(loss) OVER (
PARTITION BY symbol ORDER BY timestamp
ROWS BETWEEN 13 PRECEDING AND CURRENT ROW
) AS avg_loss
FROM gains_losses
)
SELECT
timestamp AS time,
symbol,
CASE
WHEN avg_loss = 0 THEN 100
ELSE 100 - (100 / (1 + (avg_gain / nullif(avg_loss, 0))))
END AS rsi_14
FROM avg_gains_losses;
Run in live demo

Build your own on QuestDB

Every panel on this page is a SQL query against QuestDB, rendered in Grafana. Run the queries yourself in the live demo, or use our Grafana tutorials to chart your own data.