Skip to main content

Market Data Vendors

These are examples, not shipped integrations. Each shows how one vendor's data model maps onto the chart contracts so you can adapt the pattern to whichever provider you have a contract with. Endpoints, schema names, and pricing change — confirm the current details against the vendor's own documentation before building.

The shape is always the same: the vendor client lives in your gateway, and the chart sees only normalized SDK types.

Choosing between them

DatabentoAlpacaMassive
PositioningNormalized venue-native data, including full order bookBroker with a bundled market data APIMulti-asset market data API
Asset classesEquities, futures, options across many venuesUS equities, crypto, optionsStocks, options, forex, crypto
Order bookYes, including full book by orderTop of bookQuote-level
History depthDeep tick and book historyBars, trades, quotesBars, trades, quotes, plus bulk flat files
Execution includedNoYes, same accountNo
Best fitOrder-flow surfaces, book replay, research-grade historyGetting a chart and a broker running from one vendorBroad multi-asset coverage without venue-level detail

If your product shows the depth ladder, liquidity heatmap, or footprint, you need genuine book data. A top-of-book feed cannot render those surfaces honestly, and synthesizing depth from quotes produces a chart that looks right and is wrong.

Databento

Databento publishes venue data under one normalized model, with identical schemas for historical and live. That property matters here: one normalizer serves both loadBars and subscribeRealTimeBars.

Schemas to SDK contracts

SchemaContainsMaps to
ohlcv-1s, ohlcv-1m, ohlcv-1h, ohlcv-1dAggregate barsloadBars, subscribeRealTimeBars
tradesEvery trade printgetTimeAndSales, subscribeTimeAndSales, and bar aggregation
tbboTrades with the book at the time of tradeTape with aggressor inference
mbp-1Top of bookgetQuotes, subscribeQuotes
mbp-10Ten levels per sidegetDepth, subscribeDepth
mboFull book, order by ordergetBookHistory, book replay
definitionInstrument reference dataresolveSymbol, searchSymbols, price increments
statistics, statusSession statistics and venue stateSession and market status surfaces

Conversions

Two conversions are mandatory and easy to miss:

  • Timestamps are UTC nanoseconds. The chart takes Unix milliseconds.
  • Prices are fixed-precision integers scaled by 1e-9. The chart takes floats in display units.
const bar = {
time: Number(record.ts_event / 1_000_000n),
open: Number(record.open) / 1e9,
high: Number(record.high) / 1e9,
low: Number(record.low) / 1e9,
close: Number(record.close) / 1e9,
volume: Number(record.volume),
};

Do this once, in the gateway. A scaling error that reaches the browser is indistinguishable from a market move.

Instrument identity is per-dataset and per-venue rather than a bare ticker, so resolve it from the definition schema and keep your own map from the ticker users type to the vendor's instrument id. That map belongs in SdkSymbolInfo.ticker and canonicalSymbol.

Alpaca

Alpaca is a broker whose market data API is separate from its trading API, so it can serve both contracts — but the two have independent credentials, tiers, and limits.

Transports

PurposeEndpoint
REST market datahttps://data.alpaca.markets/v2/...
WebSocket, IEX feedwss://stream.data.alpaca.markets/v2/iex
WebSocket, SIP feedwss://stream.data.alpaca.markets/v2/sip
Sandbox WebSocketwss://stream.data.sandbox.alpaca.markets/v2/...

REST calls authenticate with the APCA-API-KEY-ID and APCA-API-SECRET-KEY headers. The stream authenticates in-band, then subscribes:

{ "action": "auth", "key": "YOUR_KEY", "secret": "YOUR_SECRET" }
{ "action": "subscribe", "bars": ["AAPL"], "trades": ["AAPL"], "quotes": ["AAPL"] }

Stream messages are compact. Bars arrive as "b" with S symbol, o, h, l, c, v, vw volume-weighted price, n trade count, and t timestamp. Trades arrive as "t" with S, p price, s size, x exchange, c conditions, z tape, and i trade id. Expand these into SDK shapes in the gateway rather than teaching the chart a vendor's field names.

The feed distinction

The free Basic tier serves IEX only — a single venue, roughly a few percent of consolidated volume. Charts built on IEX show real trades but not the consolidated market, so bars and volume differ from any other terminal the trader compares against. SIP is the consolidated feed and requires a paid plan. Decide this before users see a chart, because the difference is visible and gets reported as a data bug.

Alpaca also publishes updatedBars, which correct a previously delivered bar. Route those to the same replace-by-timestamp path as a normal live bar; the chart replaces a bar whose time already exists.

Massive

Massive covers stocks, options, forex, and crypto over REST and WebSocket, with bulk historical delivered as flat files. Its US equity coverage spans the major exchanges plus dark pools, FINRA facilities, and OTC.

The integration split that works well here:

  • Flat files for backfill. Load history into your own store once, then serve loadBars from that store rather than paying per-request latency on every scroll.
  • REST for gap filling and on-demand ranges the store does not yet cover.
  • WebSocket for the developing bar and the tape.

That pattern is not Massive-specific — it is the right architecture for any vendor that sells both bulk history and a live stream, and it is what makes scroll-back on a chart feel instant.

Licensing

Vendor licensing constrains architecture more than any technical detail on this page.

  • Display versus non-display use is priced separately by most venues, and a chart is display use.
  • Redistribution — showing a vendor's data to anyone who is not the licensee — usually requires a separate agreement. A chart you build for your own desk and a chart you offer to clients are different licenses even with identical code.
  • Per-seat counting is typically per user, not per connection, which is one reason the gateway deduplicates upstream subscriptions.
  • Delayed and end-of-day data carry lighter obligations. If the product does not need real time, saying so early saves real money.

Enforce entitlements at the gateway, and make an entitlement failure a typed error rather than an empty result. See Build the data gateway.

Next steps