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

# Prediction Traders

> Learn how to build trader leaderboards, profiles, and portfolio analytics for prediction market traders

In this recipe we'll show you how to discover top prediction market traders, display detailed trader profiles with performance stats, show their market positions and P\&L, and chart their trading activity over time.

Prediction market traders have rich on-chain performance data: win rate, P\&L, volume, position sizing, and per-market breakdowns. This recipe covers 5 queries that work together: discover traders → view profile → see positions → chart performance → trade history.

## Step 1: Trader Leaderboard

Build a sortable trader leaderboard with performance metrics across configurable time windows using [`filterPredictionTraders`](/api-reference/queries/filterpredictiontraders).

<AccordionGroup>
  <Accordion title="Top all-time profitable traders">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query TopTraders {
      filterPredictionTraders(
        rankings: [{ attribute: TOTAL_PROFIT_CT_ALL, direction: DESC }]
        limit: 25
      ) {
        count
        page
        results {
          id
          trader {
            id
            venueTraderId
            protocol
            alias
            primaryAddress
            profileImageUrl
            profileUrl
            labels
          }
          totalVolumeUsdAll
          totalProfitUsdAll
          totalProfitCTAll
          totalTradesAll
          activeMarketsCount
          pnlPerVolumeAll
          biggestWinUsd
          biggestLossUsd
          firstTradeTimestamp
          lastTradeTimestamp
          volumeUsd24h
          realizedPnlUsd24h
          realizedProfitPercentage24h
          trades24h
          winRate24h
          heldTokenAcquisitionCostUsd
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Best win rate this week (minimum volume filter)">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query BestWinRate {
      filterPredictionTraders(
        filters: { totalVolumeUsdAll: { gte: 10000 } }
        rankings: [{ attribute: WIN_RATE_1W, direction: DESC }]
        limit: 25
      ) {
        count
        results {
          id
          trader {
            alias
            primaryAddress
            profileImageUrl
          }
          totalVolumeUsdAll
          totalProfitCTAll
          winRate24h
          trades24h
          realizedPnlUsd24h
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Highest 24h PnL">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query HighestPnL {
      filterPredictionTraders(
        rankings: [{ attribute: REALIZED_PNL_USD_24H, direction: DESC }]
        limit: 25
      ) {
        count
        results {
          id
          trader {
            alias
            primaryAddress
            profileImageUrl
          }
          realizedPnlUsd24h
          realizedPnlCT24h
          realizedProfitPercentage24h
          volumeUsd24h
          trades24h
          winRate24h
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Search for a trader">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query SearchTrader {
      filterPredictionTraders(phrase: "HorizonSplendidView", limit: 10) {
        count
        results {
          id
          trader {
            alias
            primaryAddress
            profileImageUrl
            labels
          }
          totalVolumeUsdAll
          totalProfitCTAll
          winRate24h
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

<Info>
  **Ranking attributes** are available at multiple windows: 12h, 24h, 1w, 1m, and "All" (all-time).

  **Volume filters** (e.g., `totalVolumeUsdAll: { gte: 10000 }`) are essential for meaningful leaderboards. Filter out low-activity traders.

  **P\&L per volume** (`pnlPerVolumeAll`) normalizes profit by capital deployed, making it better for comparing traders of different sizes.

  **Search** matches against alias, primary address, or venue trader ID.
</Info>

## Step 2: Trader Profile & Detailed Stats

Fetch comprehensive stats for a single trader, broken down by time window, using [`detailedPredictionTraderStats`](/api-reference/queries/detailedpredictiontraderstats).

<Info>
  Grab the trader ID from the previous queries to use here. We've used a sample trader ID for this example. Feel free to change it.
</Info>

<AccordionGroup>
  <Accordion title="Full trader profile with windowed stats">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query TraderProfile {
      detailedPredictionTraderStats(
        input: { traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket" }
      ) {
        traderId
        lastTransactionAt
        trader {
          id
          protocol
          venueTraderId
          alias
          primaryAddress
          linkedAddresses
          profileImageUrl
          profileUrl
          labels
          totalVolumeUsd
          totalVolumeCT
          allTimeProfitUsd
          allTimeProfitCT
          biggestWinUsd
          biggestWinCT
          biggestLossUsd
          biggestLossCT
          totalTradesCount
          activeMarketsCount
          firstTradeTimestamp
          lastTradeTimestamp
        }
        allTimeStats {
          totalVolumeUsd
          totalVolumeCT
          totalProfitUsd
          totalProfitCT
        }
        statsDay1 {
          start
          end
          lastTransactionAt
          statsCurrency {
            volumeUsd
            volumeCT
            buyVolumeUsd
            sellVolumeUsd
            realizedPnlUsd
            realizedPnlCT
            averageSwapAmountUsd
            averageProfitUsdPerTrade
            realizedProfitPercentage
            heldTokenAcquisitionCostUsd
            soldTokenAcquisitionCostUsd
          }
          statsNonCurrency {
            trades
            buys
            sells
            wins
            losses
            uniqueMarkets
          }
          statsChange {
            volumeChange
            realizedPnlChange
            tradesChange
            winsChange
            lossesChange
            uniqueMarketsChange
          }
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

* The `trader` object has the all-time aggregate profile: total volume, profit, biggest win/loss, trade count, active markets
* Windowed stats (`statsHour1` through `statsDay30`) give recent performance breakdowns
* `statsCurrency` has all the monetary metrics, `statsNonCurrency` has counts, `statsChange` has period-over-period changes
* `heldTokenAcquisitionCostUsd` / `soldTokenAcquisitionCostUsd` show the cost basis of currently held and already-sold positions
* `realizedProfitPercentage` is the return on capital for the window
* Use the windowed stats to build a time-period toggle (1h, 4h, 12h, 24h, 1w, 30d) on the trader profile

<Note>
  Each toggle interval maps to one exact field name:

  | Time window | Field name     |
  | ----------- | -------------- |
  | 1 hour      | `statsHour1`   |
  | 4 hours     | `statsHour4`   |
  | 12 hours    | `statsHour12`  |
  | 24 hours    | `statsDay1`    |
  | 1 week      | `statsWeek1`   |
  | 30 days     | `statsDay30`   |
  | All-time    | `allTimeStats` |

  Note the one-week window is `statsWeek1`, not `statsDay7`.

  Note the 30-day window is `statsDay30`, not `statsMonth1`.

  These six windowed fields plus `allTimeStats` are the complete set. There is no `statsDay7`, `statsDay3`, `statsDay14`, or `statsMonth1`.
</Note>

## Step 3: Trader's Market Positions

Show which markets a trader is active in, their positions, and per-market P\&L with [`filterPredictionTraderMarkets`](/api-reference/queries/filterpredictiontradermarkets).

<Info>
  Grab the trader ID, market ID, or event ID from the previous queries to use here. Or use the corresponding [`filterPredictionMarkets`](/api-reference/queries/filterpredictionmarkets), [`filterPredictionEvents`](/api-reference/queries/filterpredictionevents), or [`filterPredictionTraders`](/api-reference/queries/filterpredictiontraders) queries to find relevant IDs.
</Info>

<AccordionGroup>
  <Accordion title="Open positions sorted by P&L">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query OpenPositions {
      filterPredictionTraderMarkets(
        traderIds: ["0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"]
        filters: { hasOpenPosition: true }
        rankings: [{ attribute: totalVolumeUsd, direction: DESC }]
        limit: 25
      ) {
        count
        results {
          id
          traderId
          marketId
          eventId
          market {
            id
            eventId
            label
            question
            eventLabel
            imageThumbUrl
            outcome0Label
            outcome1Label
          }
          hasOpenPosition
          totalRealizedPnlUsd
          totalRealizedPnlCT
          totalVolumeUsd
          totalTrades
          totalCostBasisUsd
          totalSharesHeld
          pnlPerVolumeMarket
          outcome0 {
            outcomeId
            isWinningOutcome
            sharesHeld
            avgEntryPriceUsd
            avgEntryPriceCT
            costBasisUsd
            buys
            sells
            buyVolumeUsd
            sellVolumeUsd
            realizedPnlUsd
            pnlStatus
          }
          outcome1 {
            outcomeId
            isWinningOutcome
            sharesHeld
            avgEntryPriceCT
            costBasisUsd
            buys
            sells
            realizedPnlUsd
            pnlStatus
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Top traders for a specific market">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query MarketTopTraders {
      filterPredictionTraderMarkets(
        marketIds: ["yourMarketId"]
        rankings: [{ attribute: totalVolumeUsd, direction: DESC }]
        limit: 25
      ) {
        count
        results {
          id
          traderId
          marketId
          market {
            id
            label
            question
            eventLabel
          }
          totalRealizedPnlUsd
          totalVolumeUsd
          totalTrades
          hasOpenPosition
          outcome0 {
            sharesHeld
            avgEntryPriceCT
            realizedPnlUsd
            pnlStatus
          }
          outcome1 {
            sharesHeld
            avgEntryPriceCT
            realizedPnlUsd
            pnlStatus
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Top traders in a specific event">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query EventTopTraders {
      filterPredictionTraderMarkets(
        eventIds: ["yourEventId"]
        rankings: [{ attribute: totalVolumeUsd, direction: DESC }]
        limit: 25
      ) {
        count
        results {
          id
          traderId
          marketId
          market {
            id
            label
            eventLabel
          }
          totalRealizedPnlUsd
          totalVolumeUsd
          hasOpenPosition
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

<Info>
  **Per-outcome position data:** Each result has `outcome0` and `outcome1` with shares held, avg entry price, cost basis, realized P\&L.

  **`hasOpenPosition`:** Filter to show only active positions vs historical ones.

  **`pnlStatus`:** Indicates the P\&L state for the outcome (e.g., PROFIT, LOSS).

  **`avgEntryPriceCT`:** The average price the trader paid. Compare with current market price to estimate unrealized P\&L.

  **Cross-referencing:** Use `marketIds` to find top traders for a market, or `eventIds` for an event. This powers "Top Traders" tabs on market/event pages.
</Info>

You can also use `predictionTraderMarketsStats` as a simpler alternative for fetching a trader's per-market stats without the filtering/ranking system:

<Info>
  Grab the trader ID from the previous queries to use here. We've used a sample trader ID for this example. Feel free to change it.
</Info>

<Accordion title="Simple position list with predictionTraderMarketsStats">
  [Test this query in the Explorer →](/explore)

  ```graphql theme={null} theme={null}
  query TraderPositions {
    predictionTraderMarketsStats(
      input: {
        traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"
        limit: 25
      }
    ) {
      items {
        traderId
        marketId
        hasOpenPosition
        predictionMarket {
          id
          label
          question
          eventLabel
          outcomeLabels
          winningOutcomeId
          resolution {
            result
            source
          }
        }
        outcome0Stats {
          sharesHeld
          avgEntryPriceCT
          costBasisCT
          realizedPnlCT
          pnlStatus
          buys
          sells
          buyVolumeCT
          sellVolumeCT
        }
        outcome1Stats {
          sharesHeld
          avgEntryPriceCT
          costBasisCT
          realizedPnlCT
          pnlStatus
          buys
          sells
          buyVolumeCT
          sellVolumeCT
        }
      }
      cursor
    }
  }
  ```
</Accordion>

## Step 4: Trader Performance Charts

Chart a trader's performance over time (volume, P\&L, trade activity, and cumulative profit) using [`predictionTraderBars`](/api-reference/queries/predictiontraderbars).

<Info>
  Grab the trader ID from the previous queries to use here. We've used a sample trader ID for this example. Feel free to change it.
</Info>

<AccordionGroup>
  <Accordion title="Trader performance bars">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query TraderPerformance {
      predictionTraderBars(
        input: {
          traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"
          from: 1773100000
          to: 1773700000
          resolution: day1
        }
      ) {
        traderId
        trader {
          id
          alias
          primaryAddress
          profileImageUrl
        }
        bars {
          t
          trades
          buys
          sells
          uniqueMarkets
          volumeUsd
          volumeCT
          buyVolumeUsd
          sellVolumeUsd
          wins
          losses
          realizedPnlUsd
          realizedPnlCT
          cumulativeRealizedPnlUsd
          cumulativeRealizedPnlCT
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

**Chart types from this data:**

**Cumulative P\&L (line chart, the hero chart):**

* Plot `cumulativeRealizedPnlCT` over time. This is the signature trader performance chart
* Shows the running total of realized profit/loss
* Color the line green when positive, red when negative

**Period P\&L (bar chart):**

* `realizedPnlUsd` per bar. Green bars for profit, red for loss
* Pair with the cumulative line above for a combo chart

**Volume (bar chart):**

* `volumeUsd` or split into `buyVolumeUsd` / `sellVolumeUsd`

**Win/Loss (stacked bar):**

* `wins` and `losses` per bar. Stacked or grouped bars showing resolution outcomes

**Activity (line):**

* `trades`, `buys`, `sells`: trade frequency
* `uniqueMarkets`: how diversified the trader is per period

**Resolutions available:** HOUR1, HOUR4, DAY1, WEEK1

## Step 5: Trader's Trade History

Show the individual trade-by-trade history for a trader with [`predictionTrades`](/api-reference/queries/predictiontrades).

<Info>
  Grab the trader ID from the previous queries to use here. We've used a sample trader ID for this example. Feel free to change it.
</Info>

<AccordionGroup>
  <Accordion title="Trader trade history">
    [Test this query in the Explorer →](/explore)

    ```graphql theme={null} theme={null}
    query TraderTrades {
      predictionTrades(
        input: {
          traderId: "0x02227b8f5a9636e895607edd3185ed6ee5598ff7:Polymarket"
          limit: 50
        }
      ) {
        items {
          marketId
          outcomeId
          protocol
          tradeType
          maker
          traderId
          timestamp
          outcomeIndex
          outcomeLabel
          priceUsd
          priceCollateral
          amount
          amountCollateral
          amountUsd
          transactionHash
          blockNumber
          networkId
          predictionMarket {
            id
            label
            question
            eventLabel
            outcomeLabels
          }
        }
        cursor
      }
    }
    ```
  </Accordion>
</AccordionGroup>

* Returns individual trades with full context: market, outcome, price, size, direction
* `tradeType` indicates BUY or SELL
* `outcomeLabel` shows which outcome was traded (e.g., "Yes" or "No")
* `priceCollateral` is the price paid per share
* `amount` is the number of shares, `amountUsd` is the USD value
* `cursor` enables pagination for loading more trades
* Include `predictionMarket` to show market context alongside each trade

## Putting It All Together

Here's the recommended data flow:

**For a trader profile page, on page load (parallel queries):**

1. `detailedPredictionTraderStats`: profile header, summary stats, windowed performance
2. `filterPredictionTraderMarkets(traderIds, hasOpenPosition: true)`: active positions table
3. `predictionTraderBars`: cumulative P\&L chart

**On tab switch:**

4. `filterPredictionTraderMarkets(traderIds)`: all positions (when user switches to "All Positions" tab)
5. `predictionTrades(traderId)`: trade history (when user switches to "Trades" tab)

**For a leaderboard page:**

1. `filterPredictionTraders`: the main ranked list with configurable sort
2. Click a trader → navigate to their profile using the data flow above

<Tip>
  **Trader IDs:** Format is typically `protocol:address` (e.g., `Polymarket:0x1234...`).

  **CT vs USD:** Collateral token (CT) values are preferred for prediction market P\&L since the collateral is usually a stablecoin.

  **Unrealized P\&L:** The API provides realized P\&L. To estimate unrealized, compare `avgEntryPriceCT` from positions with current market price from `filterPredictionMarkets`.

  **Win rate context:** Always show win rate alongside trade count. A 100% win rate on 2 trades is less meaningful than 60% on 500 trades.

  **Position sizing:** `totalCostBasisUsd` shows how much capital a trader has deployed in a market, providing useful context alongside P\&L.

  **Cross-query use:** `filterPredictionTraderMarkets` works bidirectionally. Filter by `traderIds` for a trader's portfolio, or by `marketIds`/`eventIds` to find top traders for a market/event.
</Tip>

Check out the related endpoints in their respective API reference pages:

* [filterPredictionTraders](/api-reference/queries/filterpredictiontraders)
* [detailedPredictionTraderStats](/api-reference/queries/detailedpredictiontraderstats)
* [filterPredictionTraderMarkets](/api-reference/queries/filterpredictiontradermarkets)
* [predictionTraderMarketsStats](/api-reference/queries/predictiontradermarketsstats)
* [predictionTraderBars](/api-reference/queries/predictiontraderbars)
* [predictionTrades](/api-reference/queries/predictiontrades)
