diff --git a/docs/blockchain/Solana/solana-dextrades.mdx b/docs/blockchain/Solana/solana-dextrades.mdx index b6a00e13..42ca0982 100644 --- a/docs/blockchain/Solana/solana-dextrades.mdx +++ b/docs/blockchain/Solana/solana-dextrades.mdx @@ -2003,18 +2003,18 @@ Check data here on [DEXrabbit](https://dexrabbit.bitquery.io/solana/pair/9Fv7n7H Three things about `DEXTradeByTokens` aggregates that are easy to miss: -- **`PriceInUSD` groups by side currency.** Any `Trade { PriceInUSD(minimum: ...) }` or `PriceInUSD(maximum: ...)` selector adds `Trade.Side.Currency.MintAddress` to the grouping key, even if you do not select it, because USD conversion is computed per side currency. A minute in which WSOL traded against 797 different tokens returns 797 rows, one per side currency. The rows do not overlap and `count` stays additive. `Trade { Price(...) }` behaves the same way but groups by the side currency's `Decimals`. To get one row per token and interval, filter `Trade.Side.Currency.MintAddress` to the quote currencies you care about (for WSOL: USDC and USDT; for other tokens add WSOL) and select `Trade { Side { Currency { MintAddress } } }` so the grain is visible. If more than one quote currency traded, you get one row per quote currency; combine them on your side. -- **Use `before`, not `till`, for the end of a candle.** `till` is inclusive. On the pre-aggregated path (below) `Block.Time` is stored at minute resolution, so `till: "…T02:35:00Z"` matches every trade in the 02:35 minute. `since` + `before` gives the half-open interval `[since, end)` on every path. -- **Two backing tables on `dataset: realtime`.** A query that selects only `Block.Time(interval: …)`, `Trade.Price…` measures and `count` is served from a per-minute pre-aggregated table. Adding `Block { Slot(minimum: Block_Slot) }` or `uniq(of: Transaction_Signature)` switches it to the raw trades. The two can differ: the pre-aggregated table does not return the raw fill extremes, while the raw path returns the true highest and lowest fill, including dust-sized trades. Pick the path that matches your definition and keep it fixed. `dataset: combined` serves the price selectors but not `Slot(minimum/maximum)` or `uniq` on this cube. +- **On the pre-aggregated path, price measures are grouped by side currency.** By default (`aggregates: yes`) a `DEXTradeByTokens` query on `dataset: realtime` that selects only `Block.Time(interval: …)`, price measures and `count` is served from a per-minute pre-aggregated table. On that table any `Trade { PriceInUSD(minimum: ...) }` or `PriceInUSD(maximum: ...)` selector adds `Trade.Side.Currency.MintAddress` to the grouping key even if you do not select it, because USD conversion is stored per side currency (`Trade { Price(...) }` groups by the side currency's `Decimals` instead). A minute in which WSOL traded against 797 different tokens returns 797 rows. The rows do not overlap and `count` stays additive. This table also stores `Block.Time` at minute resolution and its extremes are not the raw fill extremes. +- **`aggregates: no` selects the raw trades.** `Solana(dataset: realtime, aggregates: no)` serves the same query from the raw fills: one row per token and interval across all side currencies, exact highest and lowest fill (dust trades included), `Block.Time` at second resolution, and `Block.Slot(minimum/maximum: ...)` and `uniq(...)` available. Selecting one of those raw-only fields switches to the raw path even without the flag. The raw path is not available on `dataset: combined`, and it keeps a much shorter window than the pre-aggregated table (hours to about a day, against roughly 7 days), so collect promptly. +- **Use `before`, not `till`, for the end of a candle.** `till` is inclusive. On the pre-aggregated path `till: "…T02:35:00Z"` matches every trade in the 02:35 minute; on the raw path it adds the fills at second 02:35:00. `since` + `before` gives the half-open interval `[since, end)` on both. -One candle per token and minute from raw trades, half-open interval: +For a price series, pin the side currency to the quote currencies you care about (for WSOL: USDC and USDT; for other tokens add WSOL), because unpriced side currencies push the all-side USD extremes to absurd values. Count activity separately, across all side currencies, with a `count`-only query. One candle per token, minute and quote currency from raw trades, half-open interval:
Click to expand GraphQL query ```graphql query SolMinuteOHLC($token: String!, $quotes: [String!]!, $since: DateTime!, $end: DateTime!) { - Solana(dataset: realtime) { + Solana(dataset: realtime, aggregates: no) { DEXTradeByTokens( where: { Block: {Time: {since: $since, before: $end}} @@ -2043,7 +2043,7 @@ query SolMinuteOHLC($token: String!, $quotes: [String!]!, $since: DateTime!, $en } { "token": "So11111111111111111111111111111111111111112", - "quotes": ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCdmmxZ2o8"], + "quotes": ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"], "since": "2026-09-10T02:34:00Z", "end": "2026-09-10T02:35:00Z" } @@ -2051,7 +2051,7 @@ query SolMinuteOHLC($token: String!, $quotes: [String!]!, $since: DateTime!, $en
-`count` is the number of DEX fills in which the token is one side; a routed swap with several fills counts each of them. `open` and `close` pick one fill from the first and last slot; when several fills share that slot the choice is not defined by transaction order. For a strict first and last, query the raw trades of those two slots and sort by `Block.Slot`, `Transaction.Index`, `Trade.Index`. If you want a single all-venue candle without choosing quote currencies, use the [Trading API](/docs/trading/crypto-price-api/) `Trading { Tokens }` cube (price index, about 30 days of history). +Selecting `Side { Currency }` gives one row per quote currency; fills add up across those rows, but `uniq` of transaction signatures does not, because a routed transaction can fill against both quotes. Count transactions with one `uniq` over the union filter. `count` is the number of DEX fills in which the token is one side; a routed swap with several fills counts each of them. `open` and `close` pick one fill from the first and last slot; when several fills share that slot the choice is not defined by transaction order. For a strict first and last, query the raw trades of those two slots and sort by `Block.Slot`, `Transaction.Index`, `Trade.Index` (add `Instruction.Index` and `Instruction.InternalSeqNumber` as further tie-breakers). If you want a single all-venue candle without choosing quote currencies, use the [Trading API](/docs/trading/crypto-price-api/) `Trading { Tokens }` cube (price index, about 30 days of history). ## Solana Real time prices from multiple Markets