Docs/Developers/Subgraph

Subgraph

Indexed view of every position, deposit, and liquidation. Query by trader, market, time range, or any combination - GraphQL endpoint live on The Graph.

● Last updated May 08, 20264 min readEdit on GitHub →

Overview

Atomic's subgraph indexes every event emitted by the core contracts: position opens and closes, liquidations, lender deposits and withdrawals. Use it for historical queries, analytics dashboards, or any read pattern the REST API does not cover.

i
Hosted on The Graph

Atomic uses the standard subgraph endpoint format. If you have used The Graph before, you already know the workflow.

Endpoint

text
https://api.thegraph.com/subgraphs/name/atomic-protocol/atomic-arbitrum-v3

GraphQL over HTTPS. POST queries to the URL with Content-Type: application/json.

Schema overview

The five primary entities:

EntityWhat it represents
PositionLifecycle of a single trade - open, edits, close or liquidation
TraderAn address with at least one position; aggregate stats
MarketA trading pair - running totals, utilization, OI
LenderDeposit / WithdrawLender-side flows into and out of the pool
PoolSnapshotHourly snapshot of pool TVL, utilization, APY

Full GraphQL schema is published with the subgraph; explore it interactively at the endpoint above.

Example queries

Recent liquidations

graphql
{
positions(
  where: { closeReason: "LIQUIDATION" }
  orderBy: closedAt
  orderDirection: desc
  first: 20
) {
  id
  trader { id }
  market { symbol }
  side
  margin
  leverage
  entryPrice
  liquidationPrice
  realizedPnl
  closedAt
}
}

Trader history

graphql
{
trader(id: "0xabc...") {
  id
  totalTrades
  winRate
  realizedPnl
  positions(orderBy: openedAt, orderDirection: desc, first: 50) {
    id
    market { symbol }
    side
    margin
    leverage
    realizedPnl
    openedAt
    closedAt
    closeReason
  }
}
}

Pool APY over time

graphql
{
poolSnapshots(
  orderBy: timestamp
  orderDirection: desc
  first: 168          # last week, hourly
) {
  timestamp
  tvl
  borrowed
  utilization
  apy
}
}

Daily trading volume per market

graphql
{
marketDailyStats(
  orderBy: date
  orderDirection: desc
  first: 30
) {
  date
  market { symbol }
  volumeUsd
  trades
  feesUsd
  liquidations
}
}

Pagination

The Graph caps first at 1000 entities per query. For larger result sets:

  • Use first: 1000 plus skip: N for offset-based pagination (works up to skip ~5000).
  • Beyond that, use cursor-style pagination: filter by where: { id_gt: <last_id> } and order by id ascending.

The cursor approach is faster on large traders / markets with millions of events.

Latency and freshness

  • Indexing latency: typically 1–2 blocks (~3 seconds on Arbitrum) behind real-time.
  • Cache: queries are cached at the gateway for ~1 second.
  • Reorgs: the subgraph re-indexes on reorg automatically; readers see eventual consistency.

For sub-second freshness on a single position, query the contract directly via the SDK - the subgraph is the wrong tool for high-frequency reads.

Indexing your own copy

The subgraph definition is open-source. To run your own indexed copy:

  1. Clone the subgraph repo (link in Contract addresses).
  2. Deploy to your own Graph node, or to The Graph's hosted service under your namespace.
  3. Point your queries at the new endpoint.

A self-hosted indexer is recommended for production analytics workloads where you need control over latency and uptime.

What the subgraph does not do

  • Real-time prices. Price marks are computed at query time from on-chain liquidity, not stored. Use the REST quote endpoint or the SDK.
  • PnL projections. The subgraph returns realized PnL only. Open-position unrealized PnL is computed off-chain.
  • Liquidity routing detail. Aggregator-side splits (which Uniswap pool the swap touched) are not in the schema; they live in the aggregator's own logs.