How to Use Subgraphs for Crypto Trading Signals: A Uniswap Example

Learn how to use Uniswap subgraphs to turn swaps, liquidity changes, LP behavior, and stablecoin flows into structured market data for crypto trading signals, bots, dashboards, and alerts.

How to Use Subgraphs for Crypto Trading Signals: A Uniswap Example
Crypto trading signals using Subgraphs

Trading bots and AI agents need more than a price feed.

Price alone rarely explains what is happening in a market. Volume may be accelerating, liquidity could be thinning near the active range, LPs might be repositioning capital, or stablecoins may be rotating into risk assets. All of that activity exists on-chain.

The challenge is turning raw activity into usable market data.

One approach is to pull logs directly from RPC, decode events, query contract state, and maintain a custom indexing pipeline. That can work at a small scale, but it becomes difficult once a system needs to monitor many pools, compare historical behavior, or generate signals continuously across multiple markets.

Subgraphs solve this by indexing blockchain events into structured, queryable datasets.

Swaps, liquidity changes, LP behavior, pool state, tick movement, and time-based snapshots can all be queried through GraphQL instead of being reconstructed from raw logs on every request.

Using Uniswap as an example, it exposes what trading systems require, such as volume, liquidity depth, LP positioning, stablecoin flow, and pool activity.

A subgraph does not generate the trading signal itself, but it provides the structured market data underneath it.

Subgraphs provide the data required for signals

A good trading system usually has three layers.

The first layer is the data layer. It indexes swaps, liquidity changes, pool state, ticks, positions, and snapshots.

The second layer is the signal layer. It turns that data into metrics, baselines, ratios, alerts, and confidence scores.

The third layer is the execution layer. It decides whether to trade, route, resize, pause, or do nothing.

Subgraphs belong in the data layer. Their role is to continuously structure on-chain activity into data that trading systems can query, compare, and analyze.

What a trading system can get from a Uniswap subgraph

A single swap event usually means very little on its own. Useful signals appear when activity changes relative to historical behavior or surrounding market conditions.

For example:

  • Is the current volume unusually high compared to the average trading volume
  • Is liquidity near the current price getting thinner?
  • Did LPs pull liquidity after a price move?
  • Is the pool still deep enough for this trade size?
  • Are stablecoins flowing into volatile assets?

These patterns are difficult to track directly from raw logs, but become easier once the data is indexed into snapshots and historical baselines.

Start with volume, then add context

The simplest first signal is abnormal volume.

A Uniswap subgraph can index Swap events and maintain hourly snapshots for each pool. Recent snapshots can then be compared against a historical baseline.

For example:

Current hourly volume is 3.5x higher than the 7-day hourly average.

On its own, that does not mean buy or sell. It only shows that the pool is behaving differently from its normal pattern.

A trading system might use that signal to increase monitoring, adjust volatility assumptions, reduce quote size, widen spreads, or check related pools.

Volume becomes more useful when paired with liquidity. And rising volume with rising liquidity can suggest healthier activity. Rising volume with falling liquidity points to thinner execution and higher slippage risk.

If volume rises while price stays flat, the activity may reflect arbitrage or two-sided flow. If volume rises while price moves quickly, the pool may be repricing.

Subgraphs provide the snapshots needed to compare these conditions over time.

Liquidity tells you whether the market can absorb size

On Uniswap, liquidity directly affects execution quality.

This is especially true for concentrated liquidity pools. A pool can show high TVL while still having thin liquidity near the current price if most capital sits outside the active range.

Pool-level TVL is not enough.

For Uniswap v3-style pools, useful liquidity signals often require tick-level or range-level data. A subgraph can track liquidity added, liquidity removed, current liquidity, active tick, tick ranges, LP position changes, and pool TVL.

A useful signal might be:

Liquidity near the current tick fell 30% in the last 6 hours.

This can adjust execution behavior. A strategy may reduce trade size, split execution, route elsewhere, widen spreads, or avoid the pool until depth returns.

Price shows where the market is trading. Liquidity shows how much depth exists around that price.

LP behavior is integral to a pool's health

Liquidity providers react to volatility, incentives, expected fees, and risk. Their behavior can change execution conditions before it's reflected in the price.

A Uniswap subgraph can track events such as Mint, Burn, Collect, IncreaseLiquidity, and DecreaseLiquidity.

From there, a system can monitor whether large LPs are depositing, withdrawing, collecting fees, moving liquidity closer to price, or pulling liquidity away from the active range.

Signals might look like:

A large LP removed liquidity after a volume spike.

Or:

Liquidity is concentrating around the current price range.

For LP strategies, this helps determine where to place liquidity. For trading bots, it helps identify when execution conditions are changing.

Stablecoin flows can be useful, but they need context

tablecoins can act as a proxy for deployable liquidity.

On Uniswap, stablecoin pairs can show whether capital is moving into risk assets, returning to stables, or rotating between pools.

A subgraph can track pairs such as USDC/WETH, USDC/WBTC, USDC/USDT, and USDC pairs against newer tokens.

Useful features might include:

USDC volume into WETH is 4x higher than the prior daily average.

Or:

A new token pair is attracting stablecoin liquidity.

Or:

Large stablecoin swaps into volatile assets are increasing.

These features should not be read in isolation. Stablecoin flow can reflect risk appetite, but it can also reflect arbitrage, liquidations, routing behavior, inventory rebalancing, or market maker activity.

The stablecoin side of a trade only becomes useful when interpreted alongside volume, liquidity, price movement, and pool depth.

What the subgraph should store

A subgraph should be used to store three kinds of data.

First, it should store raw events. Raw event entities are useful for backtesting, debugging, and explaining why a signal fired.

type Swap @entity(immutable: true) {
  id: Bytes!
  pool: Pool!
  sender: Bytes!
  recipient: Bytes!
  amount0: BigInt!
  amount1: BigInt!
  amountUSD: BigDecimal
  sqrtPriceX96: BigInt
  tick: BigInt
  txHash: Bytes!
  blockNumber: BigInt!
  timestamp: BigInt!
}

Second, it should store the current state. This gives the trader or bot a fast view of the market now.

type Pool @entity {
  id: Bytes!
  token0: Token!
  token1: Token!
  feeTier: BigInt!
  liquidity: BigInt!
  sqrtPriceX96: BigInt
  tick: BigInt
  token0Price: BigDecimal
  token1Price: BigDecimal
  volumeUSD: BigDecimal!
  txCount: BigInt!
  totalValueLockedUSD: BigDecimal!
}

Third, it should store snapshots. Snapshots are usually the most useful entities for signal generation because they avoid aggregating millions of swaps at query time.

type PoolHourSnapshot @entity {
  id: Bytes!
  pool: Pool!
  periodStartUnix: Int!
  volumeUSD: BigDecimal!
  txCount: BigInt!
  liquidity: BigInt!
  totalValueLockedUSD: BigDecimal!
  open: BigDecimal
  high: BigDecimal
  low: BigDecimal
  close: BigDecimal
}

Snapshots make it easy to compare the current hour against the last day, week, or month. They also make query performance more predictable because aggregation has already happened during indexing.

One caveat matters. If USD values are stored, the pricing method should be explicit, as pricing assumptions can misprice the assets.

A simple first signal

Start with one chain, one pool, and one signal.

A liquid pool such as WETH/USDC, WBTC/USDC, or USDC/USDT is usually a good starting point.

Index the core events first:

  • PoolCreated
  • Swap
  • Mint
  • Burn
  • Collect

Then build hourly snapshots that track volume, swap count, liquidity, TVL, and OHLC prices.

A first signal can be simple:

If current hourly volume is greater than 3x the 7-day hourly average, flag the pool as unusually active.

Then add liquidity context:

If volume is up and liquidity is down more than 20%, flag execution risk.

The workflow is straightforward: index the data, query the snapshot, compute the metric, generate the signal, then test its accuracy.

Example query

A bot might query recent hourly snapshots like this:

{
  poolHourSnapshots(
    first: 168
    orderBy: periodStartUnix
    orderDirection: desc
    where: { pool: "0x..." }
  ) {
    periodStartUnix
    volumeUSD
    txCount
    liquidity
    totalValueLockedUSD
  }
}

From that result, the system can calculate current hourly volume, 7-day hourly average, volume ratio, current liquidity, average liquidity, and liquidity change.

Metric computation should run outside the subgraph. Thresholds, comparisons, confidence scoring, routing decisions, and execution logic belong in the strategy layer.

What not to put in the subgraph

Keep mappings simple and deterministic.

The subgraph should handle events, state, snapshots, and relationships.

Buy or sell decisions should not live inside mapping logic. Complex models, heavy off-chain APIs, excessive handler calls, and routing rules belong outside the subgraph.

Having this separation makes the system easier to debug and safer to change.

The subgraph prepares the data. The strategy decides what the data means.

What subgraphs are good for in trading

Subgraphs work best for structured, replayable market context.

They are useful for:

  • historical swaps
  • pool activity
  • liquidity changes
  • LP behavior
  • time-based snapshots
  • protocol-specific entities
  • dashboards and alerts
  • slower-moving or medium-frequency signals

They are less suited for sub-second execution, mempool-aware strategies, latency arbitrage, or strategies that require direct order routing data.

Most trading systems combine multiple data sources. A subgraph can provide structured market context, while RPC, WebSockets, mempool endpoints, exchange APIs, or execution infrastructure handle lower-latency needs.

The value of the subgraph is making on-chain market activity easier to query, compare, and test.

An example architecture

A simple architecture looks like this:

  1. Uniswap contracts
    Source of swaps, liquidity changes, pool state, and LP events.
  2. Subgraph indexing layer
    Indexes swaps, pool state, liquidity changes, and hourly snapshots.
  3. Signal computation
    Runs freshness checks, thresholds, backtests, and confidence scoring.
  4. Alert, dashboard, routing system, or execution engine
    Uses the computed signal to decide whether any action should happen.

Each layer has a clear responsibility.

The subgraph prepares structured data. The signal engine interprets it. The execution layer decides whether to act.

Recap

Subgraphs are a practical way to turn Uniswap activity into market data, but trading signals only matter when the data is fresh enough to act on.

Subgraphs make on-chain market data usable. Fast indexing makes that data actionable.

About Ormi

Ormi is the next-generation data layer for Web3, purpose-built for real-time, high-throughput applications like DeFi, gaming, wallets, and on-chain infrastructure. Its hybrid architecture ensures sub-30ms latency and up to 4,000 RPS for live subgraph indexing.

With 99.9% uptime and deployments across ecosystems representing $50B+ in TVL and $100B+ in annual transaction volume, Ormi is trusted to power the most demanding production environments without throttling or delay.