Skip to main content

Limit Order Price API

What it is​

Raw DEX trades make a bad trigger for limit orders: one swap in a thin pool, a sandwich leg or an MEV print can print far from the market and fire an order that should have stayed inactive. The Trading cubes give an aggregated price instead: OHLC and averages per interval, blended across a token's pools by liquidity, with outlier pools kept out of the blend.

How to get it​

All three routes are on the Trading cubes at https://streaming.bitquery.io/graphql, as a query, a subscription, or the trading.prices Kafka topic.

  • Tokens: one price per token per interval, blended across every pool. Smoothest; thin pools still carry a small weight.
  • Pairs with Ranking: { Position: { eq: 1 } }: the price of the pool with the most weight in the blend, followed automatically as pools change. Closest to the price you can execute against.
  • Currencies: one price per asset across chains, such as bid:bitcoin or bid:eth.

Set Interval.Time.Duration to one of 1, 3, 5, 10, 30, 60, 300, 900, 1800, 3600 seconds. Network filters take display names ("Ethereum", not "ethereum").

The rank-1 stream for SOL on Solana:

Try SOL rank-1 pair stream ➤

subscription {
Trading {
Pairs(
where: {
Token: {Id: {is: "bid:solana:So11111111111111111111111111111111111111112"}}
Ranking: {Position: {eq: 1}}
Interval: {Time: {Duration: {eq: 1}}}
}
) {
Block {
Time
}
Market {
Name
}
Pool {
Address
}
QuoteToken {
Symbol
}
Price {
Ohlc {
Close
}
}
Volume {
Base
Quote
Usd
}
Liquidity {
Usd
Source
}
Ranking {
Position
Weight
}
}
}
}

See Getting the most accurate token price for how rank 1 behaves.

TradingView. A datafeed over these streams gives live bars at every interval from 1 s to 1 h: tutorial, repository and demo, @bitquery/tradingview-sdk.

How it is derived​

A Tokens row blends the interval's pool prices. Each pool is weighted by its liquidity after the staleness discount: a measured reserve where the index has one, a volume-derived estimate otherwise. Pools the blend rejects as outliers or ineligible contribute no price, and rank 1 on Pairs is the pool with the largest discounted liquidity share.

Since 2026-10-19 the blend is liquidity-weighted; rows before that date in the 30-day history are volume-weighted. The full method, including which trades are filtered out, is on the Price Index Algorithm page.

Examples​

What does a raw trade feed look like next to the aggregated one?​

Raw trades from DEXTradeByTokens on the chain schema:

subscription {
EVM {
DEXTradeByTokens(
where: {Trade: {Currency: {Symbol: {is: "WETH"}}}}
) {
Trade {
PriceInUSD
AmountInUSD
}
Block {
Time
}
}
}
}

Run this query ➤

  • Every swap prints, including sandwich legs, MEV prints and thin-pool fills. A limit order keyed to PriceInUSD fires on the first bad print.

The same token through Tokens at 5-second intervals:

subscription {
Trading {
Tokens(
where: {
Token: {Symbol: {is: "WETH"}, Network: {is: "Ethereum"}}
Interval: {Time: {Duration: {eq: 5}}}
}
) {
Price {
Ohlc {
Open
High
Low
Close
}
Average {
Mean
SimpleMoving
WeightedSimpleMoving
}
}
Volume {
Usd
}
Supply {
TotalSupply
FullyDilutedValuationUsd
MarketCap
}
}
}
}

Run this query ➤

  • One row per 5 s with OHLC, Average.Mean and moving averages; key the order to Average.Mean or Ohlc.Close.
  • A single bad print in one pool is a small share of the liquidity-weighted blend, so it does not move the row to the trigger.
  • Side-by-side comparison in the IDE ➤

Which interval should a limit order watch?​

Available intervals: 1, 3, 5, 10, 30, 60, 300, 900, 1800, 3600 seconds.

  • 1–3 s: fast bots, minimal smoothing.
  • 5–10 s: typical automated platforms.
  • 30–60 s: swing trading and portfolio management.
  • 300 s and up: position management.

Real-time 1-second price stream ➤ and multi-interval aggregation ➤.

Can I aggregate by traded volume instead of time?​

Not as of October 2026: Interval.VolumeBased and Interval.TargetVolume exist in the schema but carry no rows, so filtering on them returns zero rows with HTTP 200 and no error. Approximate the intent with a time interval and a Volume.Usd floor:

subscription {
Trading {
Tokens(
where: {
Token: {Symbol: {is: "USDC"}}
Interval: {Time: {Duration: {eq: 300}}}
Volume: {Usd: {gt: 100000}}
}
) {
Price { Ohlc { Close } }
Volume { Usd }
Supply { TotalSupply FullyDilutedValuationUsd MarketCap }
}
}
}

How do I get one price for an asset across chains?​

subscription {
Trading {
Currencies(
where: {Currency: {Id: {is: "bid:bitcoin"}}}
) {
Price {
Ohlc {
Close
}
}
Volume {
Usd
}
Supply {
TotalSupply
FullyDilutedValuationUsd
MarketCap
}
}
}
}

Run cross-chain Bitcoin query ➤

  • bid:bitcoin blends every covered chain's representation of bitcoin (WBTC and the like) into one price.
  • Supply on this row is the on-chain wrapped supply, not bitcoin's issued supply; see supply fields.

Should I pin an order to one named pool?​

No. Pinning a limit order to a named pool reintroduces the single-pool risk above: that pool can thin out or stop being where the token trades. Use the rank-1 Pairs stream from How to get it when you want the price you can execute against, and the blended Tokens price when you want smoothing across the whole market.

Pitfalls​

  • History before 2026-10-19 is volume-weighted. Those rows carry Liquidity fields of 0.
  • Volume-based intervals return zero rows silently. No error, no data.
  • Network is case-sensitive: "Ethereum", "Solana", "Binance Smart Chain".
  • Rank 1 can be an estimated pool. The leading pool can have Liquidity.Source: "volume"; read Source next to Ranking.Position.
Build with Bitquery

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.