Skip to content

Dated Futures Basis

Buy spot, sell a dated future, and hold to expiry: the cash-and-carry trade. The scanner prices every Binance, OKX and Bybit dated contract at the spot ask and the futures bid, charges each venue's taker fees, and ranks rows by fee-adjusted annualized basis, executable rows first.


GET/v1/arbitrage/dated-futures-basis

List dated futures basis rows

While a venue's quotes in the 5-minute dated-quotes snapshot (dataset arbitrage_dated_quotes, written by the arbitrage-boards cron with top-20 book walks and VWAP fills at the default $10,000 notional) are at most 10 minutes old, the board prices that venue from it, so rows can be executable at any minute of the hour; the answer is then dated by the snapshot (dataset_id: "arbitrage_dated_quotes", stale after 10 minutes) and cached up to s-maxage=100, stale-while-revalidate=200. A venue the snapshot lacks, or holds only older quotes for, is served from the hourly term-structure snapshot (written at :03 UTC, stale after 2 hours), its rows indicative. Days to expiry are recomputed from the expiry on every request. When the stored snapshot is past its 2-hour SLA, empty, or holds only reference quotes, the scanner reads the venues live (meta.source: "live") and merges per venue: a venue that answered replaces its stored rows, a venue that failed keeps its stored rows, judged by their own age. A failed data-store read returns 503 (service_unavailable, Retry-After: 30).

Order: rows at least 3 days from expiry first, then nearExpiry rows; within each group executable rows, then rows executable on a live read (indicativeReason: snapshot_quote), then every other indicative row, each by netAprPct, highest first.

Query parameters

  • Name
    coin
    Type
    string
    Description
    Optional base coin. Supported launch coins: BTC, ETH, SOL, XRP, DOGE, MNT, XAUT.
  • Name
    exchanges
    Type
    string
    Description
    Comma-separated exchanges: Binance, OKX, and Bybit. Deribit has no spot leg, so it appears only in calendar spreads.
  • Name
    minApr
    Type
    number
    Description
    Minimum netAprPct in percentage points.
  • Name
    minOiUsd
    Type
    number
    Description
    Minimum open interest in USD.
  • Name
    minVolumeUsd
    Type
    number
    Description
    Minimum 24h futures volume in USD.
  • Name
    minDepthUsd
    Type
    number
    Description
    Minimum executable depth in USD. Rows without depth are filtered out when this is set.
  • Name
    marginType
    Type
    string
    Description
    Futures margin filter: linear, inverse, or both.
  • Name
    notional
    Type
    number
    Description
    Position notional in USD. Defaults to 10000. A row is executable only when its depth, any reported open interest and its 24h volume are at least this notional; a smaller notional widens the executable set. minDepthUsd filters rows out instead.
  • Name
    limit
    Type
    integer
    Description
    Rows per page. Defaults to 100.
  • Name
    cursor
    Type
    string
    Description
    Opaque cursor from the previous page.

Request

GET
/v1/arbitrage/dated-futures-basis
curl -G https://www.sharpe.ai/api/v1/arbitrage/dated-futures-basis \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -d coin=BTC \
  -d minApr=4

Response

{
  "data": {
    "rows": [
      {
        "rank": 1,
        "coin": "BTC",
        "spotVenue": "OKX",
        "futuresVenue": "OKX",
        "contract": "BTC-USDT-270326",
        "expiry": "2027-03-26T08:00:00.000Z",
        "days": 179.979167,
        "spotAsk": 100020.001,
        "futureBid": 102889.71,
        "basisUsd": 2869.709,
        "basisPct": 2.869135,
        "annualizedBasisPct": 5.818642,
        "netAprPct": 5.210238,
        "volume24hUsd": 90000000,
        "openInterestUsd": 300000000,
        "oiToVolume": 3.3333,
        "depthUsd": 400000,
        "executionStatus": "indicative",
        "indicativeReason": "snapshot_quote",
        "nearExpiry": false,
        "feesPct": 0.3,
        "marginType": "linear",
        "updatedAt": "2026-09-27T08:03:00.000Z",
        "isStale": false
      }
    ],
    "scannerMeta": {
      "kind": "dated-futures-basis",
      "status": "ok",
      "source": "supabase",
      "freshnessSlaSeconds": 7200,
      "notionalUsd": 10000
    },
    "pagination": { "cursor": null, "has_more": false, "total": 1 }
  },
  "meta": {
    "request_id": "req_abc123def456ghij",
    "timestamp": "2026-09-27T08:30:00.000Z",
    "elapsed_ms": 18
  }
}

Formula

basisPct = (futureBid / spotAsk − 1) × 100 (buy spot at the ask, sell the future at the bid)

annualizedBasisPct = basisPct × 365 / days

feesPct = (2 × spot taker fee + 2 × futures taker fee) × 100, at the venue's standard (VIP 0) rates: 0.30 on Binance and OKX, 0.31 on Bybit. Not annualized.

netAprPct = (basisPct − feesPct) × 365 / days

days is ACT/365 and fractional, recomputed from expiry on every request (a stored snapshot is up to two hours old). OKX USD-quoted contracts (BTC-USD-*, ETH-USD_UM-*) are compared with OKX's USD index rather than the USDT book. depthUsd is the smaller of the spot-ask and futures-bid depth: level 1 from the venue's ticker, or the top 20 levels where level 1 is thinner than $10,000. It is summed book size, not a fill: a notional-sized order still pays the slippage within those levels.

A row is executable only when all of these hold; otherwise it is indicative and indicativeReason names the first check that failed. Every figure is kept either way.

indicativeReasonThe check that failed
stale_snapshotThe row's snapshot is inside the 2-hour term-structure SLA.
no_depthThe depth behind the spot ask and futures bid is known.
depth_below_notionalThat depth is at least notional.
oi_below_notionalThe contract's open interest, when reported, is at least notional (unknown open interest does not demote a row).
no_volumeThe contract's 24h volume is known and at least notional.
backwardation_needs_borrowThe basis is not negative. A negative basis is the reverse trade (sell spot, buy the future), which needs a spot borrow the board does not price.
snapshot_quoteEvery other check passes, but the quotes are older than 10 minutes: the row is executable on a live read of the books. Most rows read from the hourly snapshot carry this reason; rows priced from the dated-quotes snapshot usually do not.

Rows under 3 days to expiry are served with nearExpiry: true and ranked after every other row: the round-trip fee annualized over a few days dominates their APR.

aggregate summarizes each coin over the ranked contracts at least 3 days from expiry, weighting netAprPct by open interest; a coin with no qualifying contract has no entry. Basis covers Binance, OKX, and Bybit: Deribit's index is a reference price rather than a tradable spot quote, so Deribit appears only in calendar spreads. Binance COIN-M (dapi) and Bybit inverse delivery contracts are ingested beside the USDT-margined ones (marginType: inverse, since 2026-09-30); a USD-quoted contract's spot leg is the venue's own USD index, with the USDT book converted at the USDT-USD index.

Was this page helpful?