PoolPrice fields
What it is
Trading.Pairs carries two prices for each liquidity pool:
Priceis the traded price: OHLC built from the swaps in the interval.PoolPriceis the pool's own price: what the pool's curve quotes at its current liquidity, after the last swap the pool reported.
PoolPrice is a marginal price, not an executed one. On a thin liquidity pool it sits beyond the traded close by that swap's price impact, so it legitimately differs from Price.Ohlc.Close on the same row. On deep liquidity pools the two agree within a percent.
PoolPrice is on Pairs only. Tokens and Currencies have no pool price: a token's price is a blend of its pools, and the token row's LeadingPool names the pool whose price counts most.
How to get it
Select PoolPrice { … } on Trading.Pairs next to Price, in queries and subscriptions. Filter on PoolPrice.Source to keep only rows that have a pool price.
The same values are on the trading.prices Kafka topic as PairUpdate.PoolPriceUpdate (see Kafka).
How it is derived
The price is read from the pool's state after each pool event. PoolPrice.Source says where:
Source | Read from | Where |
|---|---|---|
table | The spot of the pool's slippage table | EVM |
event | The post-swap state the venue's swap event reports | Solana |
reserves | Quote reserve divided by base reserve of a constant-product pool | Solana constant-product venues, such as pump AMM |
"" (empty) | No pool price | Pools that report no price state |
Unit. PoolPrice follows the row's unit exactly like Price: USD on rows where Price.IsQuotedInUsd is true (the default), quote tokens per base token when you filter Price: {IsQuotedInUsd: false}.
OHLC. Open is the close of the previous interval. High and Low are the extremes the curve quoted after a swap inside the interval, so on a thin pool they sit beyond the traded High and Low by each swap's own impact.
Not blended. The pool price belongs to one pool. The token's blended price stays the index; see the Price Index Algorithm.
Fields
| Field | Type | Meaning |
|---|---|---|
PoolPrice.Price | Float | The pool's price at the end of the row's interval. Equals PoolPrice.Ohlc.Close. |
PoolPrice.Ohlc { Open High Low Close } | Float | The pool price over the row's interval. |
PoolPrice.Average { Mean SimpleMoving WeightedSimpleMoving ExponentialMoving } | Float | Averages over the last five intervals of this length. |
PoolPrice.Source | String | table, event or reserves, above. Empty when the pool has no price. |
PoolPrice.UpdatedAt | DateTime | Time of the pool event the price came from. On EVM it can trail the row's block by a few seconds. On Solana it equals the block time. |
When PoolPrice is empty
Not every pool reports a price. When it does not, PoolPrice.Price, Ohlc, Average and UpdatedAt are null and Source is "". Filter on PoolPrice.Source to keep only priced rows, as the examples below do.
Examples
Pool price candles next to traded candles
The WETH/USDC Uniswap v3 liquidity pool on Ethereum, 1-minute bars for the last 30 minutes. PoolPrice.Ohlc and Price.Ohlc come back on the same row.
query PoolPriceVsTradeCandles {
Trading {
Pairs(
limit: {count: 30}
orderBy: {descending: Interval_Time_Start}
where: {
Pool: {Address: {is: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640"}}
Interval: {Time: {Duration: {eq: 60}}}
Block: {Time: {since_relative: {minutes_ago: 30}}}
}
) {
Interval { Time { Start Duration } }
Token { Symbol }
QuoteToken { Symbol }
PoolPrice {
Source
UpdatedAt
Ohlc { Open High Low Close }
}
Price {
Ohlc { Open High Low Close }
}
}
}
}
Does a liquidity pool have a pool price?
Returns the latest hour with a pool price. An empty list means the pool has none. Do not add a time bound here: the pool address alone is the fast path.
query HasPoolPrice {
Trading {
Pairs(
limit: {count: 1}
orderBy: {descending: Interval_Time_Start}
where: {
Pool: {Address: {is: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640"}}
Interval: {Time: {Duration: {eq: 3600}}}
PoolPrice: {Source: {not: ""}}
}
) {
Interval { Time { Start } }
PoolPrice { Price Source UpdatedAt }
}
}
}
Pool price in quote tokens
SOL's liquidity pools on Solana, priced in quote tokens per SOL instead of USD. Source: {is: "event"} keeps pools whose price comes from the venue's swap event.
query PoolPriceInQuoteTokens {
Trading {
Pairs(
limit: {count: 10}
orderBy: {descending: Interval_Time_Start}
where: {
Token: {Id: {is: "bid:solana:So11111111111111111111111111111111111111112"}}
Price: {IsQuotedInUsd: false}
Interval: {Time: {Duration: {eq: 60}}}
Block: {Time: {since_relative: {minutes_ago: 5}}}
PoolPrice: {Source: {is: "event"}}
}
) {
Market { Protocol }
Pool { Address }
QuoteToken { Symbol }
PoolPrice { Price Source UpdatedAt }
Price { Ohlc { Close } }
}
}
}
Stream the pool price live
The same where works on a subscription. A pair whose pool never prices sends nothing when filtered on Source.
subscription PoolPriceLive {
Trading {
Pairs(
where: {
Pool: {Address: {is: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640"}}
Interval: {Time: {Duration: {eq: 60}}}
PoolPrice: {Source: {not: ""}}
}
) {
Interval { Time { Start } }
PoolPrice { Price Source UpdatedAt }
Price { Ohlc { Close } }
}
}
}
Pool price of one Uniswap v4 liquidity pool
Uniswap v4 and other singleton designs share one manager address across many pools. Add Pool: {Id: {is: …}} to select one pool. This is LSK/ETH on Ethereum, with the pool price's moving averages.
query PoolPriceUniswapV4Pool {
Trading {
Pairs(
limit: {count: 10}
orderBy: {descending: Interval_Time_Start}
where: {
Pool: {
Address: {is: "0x000000000004444c5dc75cb358380d2e3de08a90"}
Id: {is: "0x6af632b8235f1a9d95a816f7a4090736346b763a8ab4e8327017aaae72d0d1d2"}
}
Interval: {Time: {Duration: {eq: 60}}}
Block: {Time: {since_relative: {minutes_ago: 30}}}
}
) {
Interval { Time { Start } }
Market { Protocol Id }
Token { Symbol }
QuoteToken { Symbol }
PoolPrice {
Price
Source
UpdatedAt
Average { Mean SimpleMoving WeightedSimpleMoving ExponentialMoving }
}
Price { Ohlc { Close } }
}
}
}
Kafka: trading.prices
The pool price is on the trading.prices topic from protobuf v2.6.8, defined in market/price_index.proto. It is on PairUpdate only, not on token, currency or trade messages.
| Message | Field | Number | Unit |
|---|---|---|---|
PairUpdate | PoolPriceUpdate PoolPriceUpdate | 13 | USD |
PairUpdate | PoolPriceUpdate PoolPriceUpdateInQuoteTokens | 14 | Quote tokens per base token |
PoolPriceUpdate:
| Field | Type | Number | Meaning |
|---|---|---|---|
Price | float | 1 | The latest pool price, the close of the shortest interval. |
Source | string | 2 | table, event or reserves, as in GraphQL. |
UpdatedAt | uint32 | 3 | Unix second of the pool event the price was read from. |
PriceByTimeIntervals | repeated PriceByTimeInterval | 4 | The pool price over each interval, one entry per interval of PriceUpdate.PriceByTimeIntervals on the same PairUpdate, matched by TimeInterval. Ohlc and the moving averages are set; Amounts, MeanPrice and Ohlc.Volume are not, because a pool price has no volume. |
Differences from GraphQL:
PoolPriceUpdateis absent when the pool has no priced state. The USD one is also absent when the quote currency has no USD rate. CheckHasFieldbefore reading.UpdatedAtis a unix second, not a DateTime.
Archive columns
Rows of the Trading.Pairs cube in the parquet archive (pairs_by_token_id, pairs_by_currency_id, pairs_by_token_address, pairs_by_pool_address, pairs_by_interval_start) carry the same values as twelve columns:
| Column | Type | Meaning |
|---|---|---|
PoolPrice_Price | Float32 | The pool's price at the end of the row's interval, in the row's unit. Equals PoolPrice_Ohlc_Close. |
PoolPrice_Ohlc_Open / _High / _Low / _Close | Float32 | The pool price over the row's interval. |
PoolPrice_Average_Mean / _SimpleMoving / _WeightedSimpleMoving / _ExponentialMoving | Float32 | Moving averages over the pool price of the last five intervals of this length. PoolPrice_Average_Estimate is always 0. |
PoolPrice_Source | LowCardinality(String) | table, event or reserves. Empty when there is no pool price. |
PoolPrice_UpdatedAt | UInt32 | Unix second of the pool event the price was read from. |
The unit follows the row, like the Price_* columns: USD when Price_IsQuotedInUsd = 1, quote tokens per base token otherwise. A row with no pool price has PoolPrice_Price = 0 and an empty PoolPrice_Source, not NULL.
Related
- Pairs cube: every field on a
Pairsrow. - Liquidity, RankingDetail and LeadingPool fields: the reserve behind the price, and which pool leads a token's blend.
- Price Index Algorithm: how pool prices are blended into one token price.
- Solana Liquidity Pool Price API: the pool price after every pool event on the Solana
DEXPoolscube.
Ready to run this in production?
Get an API key and run these queries in minutes, or talk to us about plans and enterprise delivery.