> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raze.bot/llms.txt
> Use this file to discover all available pages before exploring further.

# Trades

> Queries for individual trades and aggregate trading volume

All trade queries return rows with a common shape:

```graphql theme={null}
type Trade {
  # ── Legacy / SOL-denominated fields (retrocompat with old clients) ──
  # solAmount + avgPrice are ALWAYS in SOL units, even for USDC-quoted pools
  # (PumpSwap Token-2022 mints, etc.). The parser normalises USDC into
  # SOL-equivalent via a live SOL/USD price hook before emitting the row.
  signature: String!
  timestamp: String!
  tokenMint: String!
  signer: String!
  transactionType: String!      # "buy" | "sell"
  solAmount: String!            # SOL units
  solAmountUsd: String!         # solAmount × live SOL/USD
  tokensAmount: String!
  avgPrice: String!             # SOL per token
  avgPriceUsd: String!          # avgPrice × live SOL/USD
  fee: String!
  slot: String
  proTrade: Boolean
  isBundle: Boolean
  isSniper: Boolean

  # ── Enriched fields (added 2026-05-26) ──
  # Native pool-quote denomination + explicit USD pricing + venue/source
  # attribution. All optional — empty / 0 when the row pre-dates the
  # enrichment, or the parser couldn't derive them confidently (e.g. exotic
  # multihops, meme-event-only fallbacks).
  quoteMint: String       # USDC / wSOL / USDT / USD1 / PYUSD mint
  quoteSymbol: String     # "USDC" | "SOL" | "USDT" | "USD1" | "PYUSD"
  quoteAmount: String     # Raw quote-side UI amount the user paid / received
  quoteDecimals: Int      # 6 for USD stables, 9 for SOL
  usdAmount: String       # Notional USD value of the trade
  priceUsd: String        # Per-token USD price
  venue: String           # "PumpSwap" | "PumpFun" | "Raydium" | "RaydiumCPMM"
                          # | "RaydiumLaunchpad" | "MeteoraDammV2" | …
  source: String          # "yellowstone" (live Yellowstone gRPC),
                          # "shred"       (jito-shred local-sim gap-fill),
                          # "car"         (historical Old-Faithful backfill)
  baseReserves: String    # Token-side reserves AFTER the swap (where available)
  quoteReserves: String   # Quote-side reserves AFTER the swap
  liquidityUsd: String    # Pool liquidity in USD (= 2 × quoteReserves × quoteUsdPrice)
}

type TradeConnection {
  data: [Trade!]!
  count: Int!
  hasMore: Boolean!
  nextCursor: String
}
```

> **Why two price denominations?** `solAmount` / `avgPrice` are the
> retrocompat legacy contract — old clients keep working unchanged.
> `quoteAmount` / `usdAmount` / `priceUsd` expose the native pool
> quote currency for clients that want to render trades in their
> actual settlement asset (USDC trades show "paid 11.65 USDC"
> instead of "paid 0.138 SOL-equivalent"). See
> [USDC-quoted PumpSwap pools](#usdc-quoted-pools) below.

Every `TradeConnection` uses opaque cursor pagination. When `hasMore` is `true`, pass `nextCursor` back as `cursor` on the next call.

All three `trades*` queries below share the same **`fromTime` / `toTime`** time-window arguments. Both accept either **milliseconds since epoch** as a decimal string (`"1776180666000"`) **or** ISO-8601 / RFC-3339 (`"2026-04-14T00:00:00Z"`). `fromTime` is inclusive, `toTime` is exclusive. The bounds are optional and independent — pass only `fromTime` to get "everything since T", only `toTime` for "everything before T", or both for a strict window. The filters compose with `cursor` for paginating inside the window.

***

## `tradesByMint`

Trades for a single token mint, ordered by `timestamp`.

### Arguments

| Name       | Type     | Required | Description                                        |
| ---------- | -------- | -------- | -------------------------------------------------- |
| `mint`     | `String` | yes      | Token mint address (≥ 32 chars).                   |
| `limit`    | `Int`    | no       | Default `100`, max `1000`.                         |
| `sort`     | `String` | no       | `"desc"` (default) or `"asc"`.                     |
| `cursor`   | `String` | no       | Opaque cursor from a prior response.               |
| `fromTime` | `String` | no       | Inclusive lower bound. Ms-since-epoch or ISO-8601. |
| `toTime`   | `String` | no       | Exclusive upper bound. Ms-since-epoch or ISO-8601. |

### Example

```graphql theme={null}
query {
  tradesByMint(mint: "So11111111111111111111111111111111111111112", limit: 50) {
    count hasMore nextCursor
    data { signature timestamp signer transactionType solAmountUsd }
  }
}
```

***

## `tradesBySigner`

Trades for one **or many** signers, merged and sorted across the whole list. The batch form is the recommended way to fetch trades across large cohorts (up to 1000 wallets) in a single round trip.

### Arguments

| Name       | Type        | Required | Description                                                                             |
| ---------- | ----------- | -------- | --------------------------------------------------------------------------------------- |
| `signer`   | `String`    | one of   | Single wallet address (≥ 32 chars). Mutually exclusive with `signers`.                  |
| `signers`  | `[String!]` | one of   | Array of 1-1000 wallet addresses. Malformed entries (\< 32 chars) are silently dropped. |
| `limit`    | `Int`       | no       | Default `100`, max `1000`. Applies to the merged result, not per-signer.                |
| `sort`     | `String`    | no       | `"desc"` (default) or `"asc"`.                                                          |
| `cursor`   | `String`    | no       | Opaque cursor from a prior response.                                                    |
| `fromTime` | `String`    | no       | Inclusive lower bound. Ms-since-epoch or ISO-8601.                                      |
| `toTime`   | `String`    | no       | Exclusive upper bound. Ms-since-epoch or ISO-8601.                                      |

Provide **exactly one** of `signer` or `signers`.

### Single-signer example

```graphql theme={null}
query {
  tradesBySigner(signer: "3ixtZXbbJjNEq89GbeFu8vJMGDMNSePofNEf5kecVhsA", limit: 50) {
    count hasMore nextCursor
    data { signature timestamp tokenMint transactionType solAmountUsd }
  }
}
```

### Batch example

```graphql theme={null}
query TradesForCohort($signers: [String!]!, $cursor: String) {
  tradesBySigner(signers: $signers, limit: 200, cursor: $cursor) {
    count hasMore nextCursor
    data { signature timestamp signer tokenMint transactionType solAmountUsd }
  }
}
```

```json theme={null}
{
  "signers": [
    "3ixtZXbbJjNEq89GbeFu8vJMGDMNSePofNEf5kecVhsA",
    "4wuudpdbJzUFpsu1MgwbGEWg93NQcb9Wxyoaya9i7FMF"
  ],
  "cursor": null
}
```

Drive pagination from the merged cursor — pass `signers` and the returned `nextCursor` back together until `hasMore` is `false`.

### Time-window example (3-day rolling history)

```graphql theme={null}
query RecentTradesForCohort($signers: [String!]!, $from: String) {
  tradesBySigner(signers: $signers, fromTime: $from, limit: 200) {
    count hasMore nextCursor
    data { signature timestamp signer tokenMint transactionType solAmountUsd }
  }
}
```

```json theme={null}
{
  "signers": ["3ixt...", "4wuu...", "…"],
  "fromTime": "2026-04-14T00:00:00Z"
}
```

Using `fromTime` lets ClickHouse prune partitions outside the window — strictly faster than paginating until you see old rows on the client.

### Limits & behavior

* **Max signers per call:** 1000.
* **Empty/unknown signers:** contribute zero rows, do not fail the query.
* **Latency:** \~100-400 ms p50, \~1-2 s p99 for 500 signers at `limit ≤ 200`.

***

## `tradesBySignerAndMint`

Trades for a specific `(signer, mint)` pair — one wallet's history on one specific token.

### Arguments

| Name       | Type     | Required | Description                                        |
| ---------- | -------- | -------- | -------------------------------------------------- |
| `signer`   | `String` | yes      | Wallet address (≥ 32 chars).                       |
| `mint`     | `String` | yes      | Token mint address (≥ 32 chars).                   |
| `limit`    | `Int`    | no       | Default `100`, max `1000`.                         |
| `sort`     | `String` | no       | `"desc"` (default) or `"asc"`.                     |
| `cursor`   | `String` | no       | Opaque cursor.                                     |
| `fromTime` | `String` | no       | Inclusive lower bound. Ms-since-epoch or ISO-8601. |
| `toTime`   | `String` | no       | Exclusive upper bound. Ms-since-epoch or ISO-8601. |

### Example

```graphql theme={null}
query {
  tradesBySignerAndMint(
    signer: "3ixtZXbbJjNEq89GbeFu8vJMGDMNSePofNEf5kecVhsA"
    mint:   "So11111111111111111111111111111111111111112"
    limit: 100
  ) {
    count hasMore nextCursor
    data { signature timestamp transactionType solAmountUsd avgPriceUsd }
  }
}
```

***

## `tradingVolume`

Aggregate trading activity for a single mint over a rolling window. Returns a free-form JSON payload (not a typed object).

### Arguments

| Name    | Type     | Required | Description                                        |
| ------- | -------- | -------- | -------------------------------------------------- |
| `mint`  | `String` | yes      | Token mint address (≥ 32 chars).                   |
| `hours` | `Int`    | no       | Rolling window. Default `24`, max `720` (30 days). |

### Example

```graphql theme={null}
query { tradingVolume(mint: "So11111111111111111111111111111111111111112", hours: 24) }
```

Typical response fields: `trades`, `buys`, `sells`, `volume_sol`, `unique_traders`.

***

## USDC-quoted pools

A handful of Token-2022 mints (TRALALERO `2MBq3mrK…`, Bank `2jCt3hj9…` and others) launch direct on **PumpSwap with USDC as the pool's quote mint**, not wSOL. The parser detects these aggregate-level (no SOL leg in the swap) and:

1. Normalises the USDC notional into SOL-equivalent via the live SOL/USD price hook, so `solAmount` and `avgPrice` stay SOL-denominated — old clients keep rendering price × supply correctly.
2. Drops the trade entirely when the price hook hasn't been set yet (early startup window). The row reappears on the next price tick rather than being emitted with USDC units in a SOL-denominated field.
3. Exposes the *real* USDC amount in `quoteAmount`, the per-token USD price in `priceUsd`, and the notional in `usdAmount` — so new clients can render the actual settlement asset.

Example response row for a TRALALERO USDC buy:

```jsonc theme={null}
{
  "signature":     "5k5FKirx…",
  "transactionType": "buy",
  "tokenMint":     "2MBq3mrKSKf6NnG5x29rBK4B9f7CWR4N1EQJ18NsViRL",
  "solAmount":     "0.000117",          // USDC paid ÷ live SOL/USD
  "avgPrice":      "0.00000835",        // SOL per token
  "avgPriceUsd":   "0.000709",          // ≈ priceUsd
  "tokensAmount":  "13.971925",

  "quoteMint":     "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "quoteSymbol":   "USDC",
  "quoteAmount":   "0.009915",          // the actual USDC the user paid
  "quoteDecimals": 6,
  "usdAmount":     "0.009915",
  "priceUsd":      "0.000709",
  "venue":         "PumpSwap",
  "source":        "yellowstone"
}
```

> Pre-fix rows (before 2026-05-26 09:00 UTC) for USDC-quoted Token-2022 pools may have `solAmount` set to the priority-fee delta (\~0.0001 SOL) and `avgPrice` in USDC/token units. Historical backfill of those rows is in flight; until it completes, filter with `quoteSymbol != ''` to restrict to corrected rows.

***

## Querying ClickHouse directly

The columns above mirror `raze.trades` 1:1. If you have a ClickHouse user with `SELECT` on the `raze` database (region DB hosts only), you can query directly:

```sql theme={null}
-- Top USDC-quoted PumpSwap trades by notional USD value, last hour
SELECT
  time,
  type,
  mint,
  quote_symbol,
  quote_amount AS usdc_paid,
  usd_amount   AS usd_notional,
  venue,
  source
FROM raze.trades
WHERE time > now() - INTERVAL 1 HOUR
  AND quote_symbol = 'USDC'
  AND venue        = 'PumpSwap'
ORDER BY usd_amount DESC
LIMIT 50;
```

`source` lets you distinguish ingestion paths: `yellowstone` for live Yellowstone gRPC (canonical), `shred` for jito-shred local-sim gap-fills (deferred 3 s after Yellowstone), `car` for historical Old-Faithful backfill rows.
