Skip to content
Liquidity Lens

Rangefinder, LP range and capital backtests

API docs

Two studies on replayed state: a range backtest that ranks range widths by fees minus divergence loss and gas, and a depth curve that shows how much of a pair's volume and fees added capital would capture.

Base URL https://llens.abanchev.com/api/v1. Authentication, deadlines, metering and errors are on Getting started. See the Rangefinder live demo.

Example values are illustrative. Token addresses are real Base contracts; amounts are raw integer units as decimal strings.

POST/api/v1/ext/market/lp-research

Range backtest

Forks a concentrated pool at a block you pin in the last 14 days, replays every swap of the horizon after it, and ranks your candidate range widths by fees minus divergence loss and gas.

Cost
50 CU
Headers
Send your key in x-api-key.
BodyRequiredDescription
chainIdyes8453 (Base) or 146 (Sonic).
poolyesA concentrated pool.
blockyesThe block to fork at, within the 14-day window.
halfWidthsBpsyes1 to 12 distinct range half-widths in bps.
horizonHoursyesHours after the block, at most 336.
capitalUsdyesCapital per range.
gasUsdPerActionnoUSD per position transaction; two are charged.

The answer is a task id. Poll /ext/market/research-task for the ranked result.

curl -s -X POST "https://llens.abanchev.com/api/v1/ext/market/lp-research" \
  -H "x-api-key: $LL_API_KEY" \
  -H "content-type: application/json" \
  -d '{"chainId":"8453","pool":"0xd0b53d9277642d899df5c87a3966a349a798f224","block":"52870000","halfWidthsBps":[50,100,250,500],"horizonHours":24,"capitalUsd":"250000","gasUsdPerAction":"0.05"}'
Example response
{
  "taskId": "3f8f6a52-6f0e-4d2b-9a43-1b2c3d4e5f60",
  "status": "queued",
  "cached": false,
  "attachedToTaskId": null
}
POST/api/v1/ext/market/depth-curve

Depth-threshold curve

For each capital amount: the pool's share of the pair's routed volume and fees, the increase over today, and your capital's share of those fees, routed by the production router over every pool of the pair.

Cost
50 CU
Headers
Send your key in x-api-key.
BodyRequiredDescription
chainIdyes8453 (Base) or 146 (Sonic).
poolyesPool to add capital to.
capitalUsdyes1 to 8 distinct capital points.
blocknoDefaults to the previous full hour.
windowHoursnoTrade window, at most 336 (the default).
rangeHalfWidthBpsnoConcentrated pools: the added position's half-width (100 by default).
fullRangenoConcentrated pools: add the position over the widest usable ticks instead of a half-width.
flownoall (default) routes every trade of the window; aggregator routes only aggregator transactions.
curl -s -X POST "https://llens.abanchev.com/api/v1/ext/market/depth-curve" \
  -H "x-api-key: $LL_API_KEY" \
  -H "content-type: application/json" \
  -d '{"chainId":"8453","pool":"0xcdac0d6c6c59727a65f871236188350531885c43","capitalUsd":["250000","1000000","5000000"],"windowHours":168}'
Example response
{
  "taskId": "3f8f6a52-6f0e-4d2b-9a43-1b2c3d4e5f60",
  "status": "queued",
  "cached": false,
  "attachedToTaskId": null
}
GET/api/v1/ext/market/research-task

Task status and result

Status, progress and result of this key's own range backtest or depth curve.

Cost
50 CU
Headers
Send your key in x-api-key.
QueryRequiredDescription
taskIdyesThe id the enqueue call returned.

Abridged: two ranges and two method lines of each kind shown. A depth-curve result has the same envelope; see the next example.

curl -s "https://llens.abanchev.com/api/v1/ext/market/research-task?taskId=3f8f6a52-6f0e-4d2b-9a43-1b2c3d4e5f60" \
  -H "x-api-key: $LL_API_KEY"
Example response
{
  "taskId": "3f8f6a52-6f0e-4d2b-9a43-1b2c3d4e5f60",
  "taskType": "ranges",
  "status": "succeeded",
  "progressPct": 100,
  "progressMessage": null,
  "errorCode": null,
  "errorMessage": null,
  "result": {
    "kind": "ranges",
    "chainId": "8453",
    "pool": "0xd0b53d9277642d899df5c87a3966a349a798f224",
    "family": "UniV3",
    "token0": "0x4200000000000000000000000000000000000006",
    "token1": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "decimals0": 18,
    "decimals1": 6,
    "tickSpacing": 10,
    "pin": {
      "requestedBlock": "52870000",
      "forkBlock": "52869998",
      "forkBlockHash": "0x2a6c8e0b1d3f5a7c9e2b4d6f8a0c1e3f5b7d9a2c4e6f8b0d1a3c5e7f9b2d4a6c",
      "forkTimestamp": "1792319755"
    },
    "window": {
      "fromBlock": "52869999",
      "toBlock": "52913199",
      "fromHour": "2026-10-18T07:00:00.000Z",
      "toHour": "2026-10-19T07:00:00.000Z",
      "horizonHours": 24,
      "replayedHours": 22,
      "modelledHours": 2,
      "missingHours": 0,
      "swapsReplayed": 9412
    },
    "capitalUsd": "250000",
    "prices": {
      "token0Usd": "2604.18",
      "token1Usd": "1",
      "source": "engine-one-token-sell-reference-at-fork"
    },
    "feeModel": {
      "swapFeeSources": {
        "eventFee": 0,
        "forkStaticFee": 9412,
        "hourlyReplayEffectiveFee": 0,
        "forkCurrentFee": 0
      },
      "hourlyFeeModels": [
        "concentrated-replay"
      ],
      "hoursWithoutExactFees": 0,
      "protocolShare": "not-subtracted: gross swap fees, as market-stats reports them"
    },
    "costs": {
      "strategy": "static-range-over-the-horizon",
      "gasUsdPerAction": "0.05",
      "actions": 2,
      "lvrMethod": "divergence-loss-at-window-end"
    },
    "method": {
      "exact": [
        "price path: each journal swap's own sqrtPriceX96, replayed in block and log order; each swap starts where the previous one left the price",
        "position math: TickMath.getSqrtRatioAtTick and SqrtPriceMath amount deltas (bigint, bit-identical to the engine's JSBI) with the contract's roundings"
      ],
      "modelled": [
        "the added position does not change the price path or the order flow (fixed-path, fixed-flow backtest): each swap's fee is shared L / (L + the fork's active liquidity), in replayed and M3-only hours alike",
        "costs: two position transactions at the caller's gas price; divergence loss at the window end valued at the end price (LVR is not estimated separately)"
      ]
    },
    "ranges": [
      {
        "rank": 1,
        "halfWidthBps": 250,
        "tickLower": -197870,
        "tickUpper": -197370,
        "liquidity": "5824410211907731",
        "amount0": "47200000000000000000",
        "amount1": "127083441902",
        "fees0": "39210440177301248",
        "fees1": "104118230",
        "feesUsd": "206.229718",
        "replayedFeesUsd": "188.904121",
        "modelledFeesUsd": "17.325597",
        "swapsInRange": 9412,
        "exits": 0,
        "liquidityShareAtFork": "0.014211",
        "divergenceLossUsd": "61.443008",
        "gasUsd": "0.100000",
        "netUsd": "144.686710"
      },
      {
        "rank": 2,
        "halfWidthBps": 100,
        "tickLower": -197720,
        "tickUpper": -197520,
        "liquidity": "14420117301884210",
        "amount0": "47100000000000000000",
        "amount1": "127341220910",
        "fees0": "62110904771230208",
        "fees1": "171223904",
        "feesUsd": "332.969201",
        "replayedFeesUsd": "301.110442",
        "modelledFeesUsd": "31.858759",
        "swapsInRange": 7930,
        "exits": 3,
        "liquidityShareAtFork": "0.034402",
        "divergenceLossUsd": "214.118702",
        "gasUsd": "0.100000",
        "netUsd": "118.750499"
      }
    ]
  }
}
GET/api/v1/ext/market/research-task

A depth-curve result

The capital-0 baseline and each capital point, with the trade window and size buckets behind them.

Cost
50 CU
Headers
Send your key in x-api-key.
curl -s "https://llens.abanchev.com/api/v1/ext/market/research-task?taskId=8c21d0e4-5b7a-4f19-b3e2-7d6a9c0f1e28" \
  -H "x-api-key: $LL_API_KEY"
Example response
{
  "taskId": "8c21d0e4-5b7a-4f19-b3e2-7d6a9c0f1e28",
  "taskType": "depth-curve",
  "status": "succeeded",
  "progressPct": 100,
  "progressMessage": null,
  "errorCode": null,
  "errorMessage": null,
  "result": {
    "kind": "depth-curve",
    "chainId": "8453",
    "pool": "0xcdac0d6c6c59727a65f871236188350531885c43",
    "family": "UniV2",
    "token0": "0x4200000000000000000000000000000000000006",
    "token1": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "decimals0": 18,
    "decimals1": 6,
    "pin": {
      "requestedBlock": "52912199",
      "forkBlock": "52912191",
      "forkBlockHash": "0x2a6c8e0b1d3f5a7c9e2b4d6f8a0c1e3f5b7d9a2c4e6f8b0d1a3c5e7f9b2d4a6c",
      "forkTimestamp": "1792319755",
      "routingRule": "before-newest-pair-swap"
    },
    "window": {
      "fromHour": "2026-10-12T13:00:00.000Z",
      "toHour": "2026-10-19T13:00:00.000Z",
      "windowHours": 168,
      "journalHours": 24,
      "hourlyRowHours": 144,
      "missingHours": 0,
      "trades": 284112,
      "routedVolumeShare": "0.987412"
    },
    "prices": {
      "token0Usd": "2604.18",
      "token1Usd": "1",
      "source": "engine-one-token-sell-reference-at-fork"
    },
    "rangeHalfWidthBps": 100,
    "buckets": [
      {
        "tokenIn": "0x4200000000000000000000000000000000000006",
        "tokenOut": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "amountIn": "4096000000000000000",
        "trades": 18233,
        "volumeIn": "74682368000000000000000"
      }
    ],
    "pairPools": [
      {
        "pool": "0xcdac0d6c6c59727a65f871236188350531885c43",
        "dex": "Aerodrome v2",
        "family": "solidly-v2",
        "token0": "0x4200000000000000000000000000000000000006",
        "token1": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "decimals0": 18,
        "decimals1": 6,
        "feeModel": {
          "kind": "static",
          "feeZeroToOneBps": "30",
          "feeOneToZeroBps": "30",
          "reason": null
        },
        "reserves": {
          "amount0": "803311902117480263680",
          "amount1": "2103418877410"
        },
        "inRange": [
          {
            "bandBps": 10,
            "amount0": "401455890211304448",
            "amount1": "1051446918"
          },
          {
            "bandBps": 50,
            "amount0": "2003788201117392896",
            "amount1": "5251972011"
          },
          {
            "bandBps": 100,
            "amount0": "3994613190027460608",
            "amount1": "10490762018"
          }
        ],
        "unavailable": null,
        "fees7d": {
          "fees0": "2914002711840092160",
          "fees1": "7630127440",
          "swaps": 3922,
          "computedHours": 168,
          "from": "2026-10-12T14:00:00.000Z"
        }
      }
    ],
    "unavailable": null,
    "baseline": {
      "capitalUsd": "0",
      "depth": "0",
      "added": {
        "amount0": "0",
        "amount1": "0",
        "liquidity": null,
        "tickLower": null,
        "tickUpper": null
      },
      "volumeShare": "0.021904",
      "poolVolumeUsd": "6470779.003333",
      "poolFeesUsd": "19412.337010",
      "poolFeesPerDayUsd": "2773.191001",
      "incrementalPoolFeesUsd": "0.000000",
      "capitalFeeShare": "0.000000",
      "capitalFeesUsd": "0.000000",
      "capitalFeesPerDayUsd": "0.000000",
      "unroutedBuckets": 0
    },
    "points": [
      {
        "capitalUsd": "250000",
        "depth": "250000000000",
        "added": {
          "amount0": "48001234117201920000",
          "amount1": "125000000000",
          "liquidity": null,
          "tickLower": null,
          "tickUpper": null
        },
        "volumeShare": "0.024411",
        "poolVolumeUsd": "7211003.048000",
        "poolFeesUsd": "21633.009144",
        "poolFeesPerDayUsd": "3090.429878",
        "incrementalPoolFeesUsd": "2220.672134",
        "capitalFeeShare": "0.056121",
        "capitalFeesUsd": "1214.072401",
        "capitalFeesPerDayUsd": "173.438914",
        "unroutedBuckets": 0
      },
      {
        "capitalUsd": "1000000",
        "depth": "1000000000000",
        "added": {
          "amount0": "192004936468807680000",
          "amount1": "500000000000",
          "liquidity": null,
          "tickLower": null,
          "tickUpper": null
        },
        "volumeShare": "0.031870",
        "poolVolumeUsd": "9414372.735000",
        "poolFeesUsd": "28243.118205",
        "poolFeesPerDayUsd": "4034.731172",
        "incrementalPoolFeesUsd": "8830.781195",
        "capitalFeeShare": "0.192047",
        "capitalFeesUsd": "5424.006012",
        "capitalFeesPerDayUsd": "774.858002",
        "unroutedBuckets": 0
      }
    ],
    "method": {
      "exact": [
        "router: routeV33 over the oracle's relevant-pool selection, the pool always included, the production router",
        "pool fees: the router's own leg fees"
      ],
      "modelled": [
        "one routing state for the whole window's size distribution (the trades did not all meet that state)",
        "the new capital's share of the pool's fees: its share of active liquidity (concentrated) or of reserves (v2) at the routing state"
      ]
    }
  }
}
Liquidity LensPrices are informational and instantaneous. They are not investment advice or a guarantee of execution.