Skip to main content

Depths Query

Retrieve aggregated order book depth at each price level. This is more efficient than querying individual orders when you only need total depth.

Try It Now

curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"query": "{ depths(first: 10, where: { market: \"0xd99802ee8f16d6ff929e27546de15d03fdcce4bd\" }, orderBy: priceIndex) { id priceIndex price isBid rawAmount baseAmount } }"}' \
  https://api.goldsky.com/api/public/project_cmicv6kkbhyto01u3agb155hg/subgraphs/sera-pro/1.0.9/gn

Schema

type Depth {
  id: ID!                     # market address + "-" + priceIndex + "-" + isBid
  market: Market!             # Parent market
  priceIndex: BigInt!         # Price book index
  price: BigInt!              # Actual price
  isBid: Boolean!             # true = bid side, false = ask side
  rawAmount: BigInt!          # Total raw amount at this level
  baseAmount: BigInt!         # Total base token amount
  latestTakenOrderIndex: BigInt!  # Index of last filled order
}

Example Queries

Get Order Book Depth

query GetOrderBookDepth($marketId: String!) {
  bids: depths(
    where: { 
      market: $marketId
      isBid: true
      rawAmount_gt: "0"
    }
    orderBy: priceIndex
    orderDirection: desc
    first: 20
  ) {
    priceIndex
    price
    rawAmount
    baseAmount
  }
  
  asks: depths(
    where: { 
      market: $marketId
      isBid: false
      rawAmount_gt: "0"
    }
    orderBy: priceIndex
    orderDirection: asc
    first: 20
  ) {
    priceIndex
    price
    rawAmount
    baseAmount
  }
}
Variables:
{
  "marketId": "0xd99802ee8f16d6ff929e27546de15d03fdcce4bd"
}

Get Depth at Specific Price

query GetDepthAtPrice($marketId: String!, $priceIndex: BigInt!, $isBid: Boolean!) {
  depths(
    where: { 
      market: $marketId
      priceIndex: $priceIndex
      isBid: $isBid
    }
  ) {
    id
    priceIndex
    price
    rawAmount
    baseAmount
  }
}

Get All Non-Zero Depths

query GetAllDepths($marketId: String!) {
  depths(
    where: { 
      market: $marketId
      rawAmount_gt: "0"
    }
    orderBy: priceIndex
    first: 1000
  ) {
    priceIndex
    price
    isBid
    rawAmount
    baseAmount
  }
}

Get Top of Book

query GetTopOfBook($marketId: String!) {
  bestBid: depths(
    where: { 
      market: $marketId
      isBid: true
      rawAmount_gt: "0"
    }
    orderBy: priceIndex
    orderDirection: desc
    first: 1
  ) {
    priceIndex
    price
    rawAmount
  }
  
  bestAsk: depths(
    where: { 
      market: $marketId
      isBid: false
      rawAmount_gt: "0"
    }
    orderBy: priceIndex
    orderDirection: asc
    first: 1
  ) {
    priceIndex
    price
    rawAmount
  }
}

Response Example

{
  "data": {
    "bids": [
      {
        "priceIndex": "2499",
        "price": "2499000000000000000000",
        "rawAmount": "5000",
        "baseAmount": "2000800320128051220"
      },
      {
        "priceIndex": "2498",
        "price": "2498000000000000000000",
        "rawAmount": "3000",
        "baseAmount": "1200960384153661464"
      }
    ],
    "asks": [
      {
        "priceIndex": "2501",
        "price": "2501000000000000000000",
        "rawAmount": "4000",
        "baseAmount": "1599360255897641343"
      },
      {
        "priceIndex": "2502",
        "price": "2502000000000000000000",
        "rawAmount": "2500",
        "baseAmount": "999200639488409272"
      }
    ]
  }
}

Building a Depth Chart

async function getDepthChart(marketId, levels = 20) {
  const query = `
    query DepthChart($marketId: String!, $levels: Int!) {
      market(id: $marketId) {
        quoteUnit
        quoteToken { decimals }
        baseToken { decimals }
      }
      bids: depths(
        where: { market: $marketId, isBid: true, rawAmount_gt: "0" }
        orderBy: priceIndex
        orderDirection: desc
        first: $levels
      ) {
        priceIndex
        price
        rawAmount
        baseAmount
      }
      asks: depths(
        where: { market: $marketId, isBid: false, rawAmount_gt: "0" }
        orderBy: priceIndex
        orderDirection: asc
        first: $levels
      ) {
        priceIndex
        price
        rawAmount
        baseAmount
      }
    }
  `;
  
  const data = await querySubgraph(query, { marketId, levels });
  
  const quoteDecimals = Number(data.market.quoteToken.decimals);
  const baseDecimals = Number(data.market.baseToken.decimals);
  const quoteUnit = BigInt(data.market.quoteUnit);
  
  const formatLevel = (depth) => {
    const price = Number(depth.price) / 1e18;  // Assuming 18 decimal price
    const quoteAmount = Number(BigInt(depth.rawAmount) * quoteUnit) / (10 ** quoteDecimals);
    const baseAmount = Number(depth.baseAmount) / (10 ** baseDecimals);
    
    return { price, quoteAmount, baseAmount };
  };
  
  // Calculate cumulative depths
  let bidCumulative = 0;
  let askCumulative = 0;
  
  const bids = data.bids.map(d => {
    const level = formatLevel(d);
    bidCumulative += level.quoteAmount;
    return { ...level, cumulative: bidCumulative };
  });
  
  const asks = data.asks.map(d => {
    const level = formatLevel(d);
    askCumulative += level.quoteAmount;
    return { ...level, cumulative: askCumulative };
  });
  
  return { bids, asks };
}

Calculating Spread

async function getSpread(marketId) {
  const data = await querySubgraph(`
    query Spread($marketId: String!) {
      bestBid: depths(
        where: { market: $marketId, isBid: true, rawAmount_gt: "0" }
        orderBy: priceIndex
        orderDirection: desc
        first: 1
      ) { price priceIndex }
      
      bestAsk: depths(
        where: { market: $marketId, isBid: false, rawAmount_gt: "0" }
        orderBy: priceIndex
        orderDirection: asc
        first: 1
      ) { price priceIndex }
    }
  `, { marketId });
  
  if (!data.bestBid.length || !data.bestAsk.length) {
    return null;  // One side is empty
  }
  
  const bidPrice = BigInt(data.bestBid[0].price);
  const askPrice = BigInt(data.bestAsk[0].price);
  const midPrice = (bidPrice + askPrice) / 2n;
  
  const spreadAbs = askPrice - bidPrice;
  const spreadBps = Number((spreadAbs * 10000n) / midPrice);
  
  return {
    bidPrice: data.bestBid[0].price,
    askPrice: data.bestAsk[0].price,
    spreadTicks: Number(data.bestAsk[0].priceIndex) - Number(data.bestBid[0].priceIndex),
    spreadBps: spreadBps
  };
}

Checking Liquidity

async function checkLiquidity(marketId, minDepthUSD = 1000) {
  const data = await querySubgraph(`
    query Liquidity($marketId: String!) {
      market(id: $marketId) {
        quoteUnit
        quoteToken { decimals }
      }
      bids: depths(
        where: { market: $marketId, isBid: true, rawAmount_gt: "0" }
      ) { rawAmount }
      asks: depths(
        where: { market: $marketId, isBid: false, rawAmount_gt: "0" }
      ) { rawAmount }
    }
  `, { marketId });
  
  const quoteUnit = BigInt(data.market.quoteUnit);
  const decimals = Number(data.market.quoteToken.decimals);
  
  const totalBidRaw = data.bids.reduce((sum, d) => sum + BigInt(d.rawAmount), 0n);
  const totalAskRaw = data.asks.reduce((sum, d) => sum + BigInt(d.rawAmount), 0n);
  
  const bidDepth = Number(totalBidRaw * quoteUnit) / (10 ** decimals);
  const askDepth = Number(totalAskRaw * quoteUnit) / (10 ** decimals);
  
  return {
    bidDepth,
    askDepth,
    hasSufficientLiquidity: bidDepth >= minDepthUSD && askDepth >= minDepthUSD
  };
}