How to Choose a Real-Time Market Data API: Verify Coverage First, Then Test Latency and Cost

TickDB Research ·

How to Choose a Real-Time Market Data API: Verify Coverage First, Then Test Latency and Cost

Summary: When integrating stock, foreign exchange, futures, index, or cryptocurrency quotes, how do you determine whether a real-time market data API is suitable for your project? First, turn your asset classes, fields, and business use cases into a requirements matrix. Then validate REST queries and WebSocket streams separately, and finally decide whether to purchase based on sampling, reconnection tests, and license verification. Receiving quotes does not mean that tick-by-tick data, a complete order book, or backfillable history is available. The difference between receipt time and source time is meaningful only after the time definitions are clear and clocks are synchronized.

image.png

The most common mistake in vendor selection occurs after the first quote arrives. A successful API response proves only that the request or subscription produced a response. It does not answer whether the feed can keep up during peak periods, recover after a disconnection, provide sufficient history, or support the intended use of the data in your product.

A practical sequence is: first confirm the capabilities that cannot be missing, then validate actual delivery quality, and finally compare total cost under the same usage scope. Missing functionality cannot be offset by lower prices, and technical connectivity cannot replace license verification. The following method applies to market dashboards, price alerts, research tools, and data-service integrations. A market data feed itself is not an order-entry or trading interface.

I. Start with a Requirements Matrix, with Coverage Specified Down to Assets and Fields

Begin with a real use case. A watchlist dashboard may require only the latest price, percentage change, and update time. A spread alert needs bid and ask quotes and their timestamps. Order-book analysis needs clearly defined price levels, quantity units, and update methods. Backtesting also requires history at the corresponding granularity, adjusted prices, or continuous-contract conventions. Do not collapse all of these tasks into a single statement such as “real-time market data is required.”

Mark every requirement as either “mandatory” or “optional,” and specify how the system will handle the absence of each mandatory item. “To be verified” is an evidence status; it must not automatically become “optional.”

Requirement dimensionWhat to specifyAcceptance evidence
Assets and identifiersMarket, asset class, contract month, symbol, pricing unitSymbol mappings and responses for target assets
Fields and semanticsLatest price, bid and ask, volume, timestamp, order-book levelsField dictionary and valid samples
Updates and trading hoursEvent-driven or periodic updates, regular and extended sessions, calendarSampling records for each session
History and methodologyStart and end dates, daily or minute bars, adjustments, continuous-contract rulesBoundary dates and paginated queries
Capacity and usageConcurrent subscriptions, request volume, user scale, internal use or external displayLoad testing and written authorization

Differences among asset classes often lead to misunderstandings when fields have the same names. Stock volume may be expressed in shares or lots. Futures require a distinction between a specific expiry contract and a continuous series. An index value is not the traded price of an executable instrument. For crypto assets, the venue and trading pair must be specified. A foreign-exchange bid/ask quote stream cannot be interpreted directly as a centralized order book, nor can every quote change be treated as one completed trade.

When evaluating TickDB as a multi-asset candidate, the official documentation provides REST and WebSocket integration methods and lists the available markets and fields by channel. Evaluation should still focus on the target assets and channels: Ticker, Depth, and Trade have different scopes. Support for quotes in a market does not imply that every asset in that market has tick-by-tick data, depth, or complete history.

II. Assign REST and WebSocket by Task, and Verify Channel Permissions Separately

For historical range queries, initial loads, and low-frequency point queries, validate REST first. For continuous quotes, tick-by-tick trades, or order-book changes, validate WebSocket first. Most real-time applications use both, but whether historical backfills, snapshots, and streams can be joined depends on interface capabilities and time or sequence rules.

image.png

Figure 1: Division of responsibilities between queries and streaming. The connection between snapshots, backfills, and streamed data must be validated rather than assumed to be seamless.

For REST, verify the number of assets queryable per request, time windows, pagination, rate limits, timeouts, and error responses. For WebSocket, verify authentication, subscription acknowledgments, channel fields, subscriptions per connection, total connections, heartbeats, and resubscription after reconnection.

“The connection is open” does not mean “the subscription is active.” Record the subscription request, its success or failure response, and the first valid business message received for each target asset. If the protocol does not specify an explicit success acknowledgment, use the method prescribed in the documentation together with the first valid data message. Do not invent your own confirmation mechanism.

Likewise, “WebSocket support” does not mean “a complete order book.” Determine separately which channels provide quotes, tick-by-tick trades, and depth; whether depth consists of complete snapshots or increments; and which levels and frequencies are covered. TickDB’s official Depth documentation describes timestamp as server time, while the Trade documentation uses trade time. Therefore, even when field names match, the feeds should not be placed on the same latency leaderboard without verification.

III. Use Explainable Samples to Validate Latency, Completeness, and Recovery

First, fix the sampling conditions: vendor, plan, target assets, channels, test date, trading session, collection machine region, and network environment. Include at least active and less active assets, periods near the open and close, and regular trading hours. If overnight or extended sessions are required, cover them separately. Test duration should depend on business risk; a single short trial connection cannot represent long-term availability.

Separate the Time Definitions Before Calculating Percentiles

For every message, retain the raw payload, the vendor timestamp field, the client receipt time, and the connection identifier. Establish whether the timestamp represents when the event occurred, when the source processed it, when the server sent it, or when a snapshot was generated. Standardize units and time zones, and record the clock-synchronization status of the collection machine. If the meaning of a field cannot be confirmed, report only the “difference between arrival time and source time”; do not call it exchange-to-client latency.

Use wall-clock time to calculate the difference between source and receipt times, and use a monotonic clock to measure local processing and reconnection durations. Preserve negative differences as clock or time-definition anomalies. Reporting only an average hides tail-end backlog, so also report the sample size, P50, P95, P99, and the number of anomalies. Break percentiles down by asset, channel, and session so that low-frequency and high-frequency assets do not obscure each other.

The following standard-library script reads an already standardized CSV file and calculates percentiles for nonnegative time differences and time regressions. The CSV columns are symbol,channel,event_ms,recv_ms; times are standardized as integer milliseconds, and arrival order is preserved. event_ms is a field normalized by the collection layer and should be interpreted as event time only when the source time truly represents the event time; otherwise, preserve the actual time semantics in the report.

import csv, math, sys
from collections import defaultdict

groups = defaultdict(list)
with open(sys.argv[1], newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        groups[(row["symbol"], row["channel"])].append(row)

for key, rows in sorted(groups.items()):
    ages, negative, missing, regressions = [], 0, 0, 0
    high_water = None
    for row in rows:  # Input must preserve arrival order.
        try:
            event = int(row["event_ms"])
            recv = int(row["recv_ms"])
        except (ValueError, KeyError, TypeError):
            missing += 1
            continue
        age = recv - event
        negative += age < 0
        if age >= 0:
            ages.append(age)
        regressions += high_water is not None and event < high_water
        high_water = event if high_water is None else max(high_water, event)
    ages.sort()
    def pct(q):
        return ages[math.ceil(len(ages) * q) - 1] if ages else None
    print(key, {"rows": len(rows), "invalid_time": missing,
                "negative_age": negative, "time_regressions": regressions,
                "nonnegative_n": len(ages),
                "p50_ms": pct(.50), "p95_ms": pct(.95), "p99_ms": pct(.99)})

Save it as audit_samples.py and run it with python audit_samples.py samples.csv. This code is intended for offline sample analysis; it does not connect to a vendor or measure network packet loss. Negative differences are excluded from percentiles and must be reported separately with their counts. When there are no valid nonnegative samples, the result is None and should not be recorded as zero. A time regression only indicates that investigation is needed; it does not, by itself, prove network reordering or a data error. Subscription snapshots, correction messages, and time precision may all affect the results.

Completeness Requires a Denominator; Fewer Messages Do Not Necessarily Mean Packet Loss

If the protocol provides sequence numbers, first determine whether sequences increase globally, by asset, or by channel, and whether reconnection resets them. Then check for gaps. Without sequence numbers, a reconcilable set of all events, or a reliable backfill interface, the number of received messages cannot be converted into a “message loss rate.” Missing messages at the WebSocket application layer are not equivalent to packet loss at the network layer.

Even without a complete denominator, you can still validate the missing-field rate for mandatory fields, silent intervals during active sessions, historical time-slot coverage, and sampled consistency. Silence is not necessarily a fault: trading suspensions, market closures, low trading activity, and feeds that push only changed values may all be normal. The recovery mechanism for a missing order-book increment differs from that for a quote snapshot. Backfilling only the latest quote cannot reconstruct missed tick-by-tick history.

Reconnection Must Restore Business State Before Restoring the “Real-Time” Indicator

image.png

Figure 2: Disconnection-recovery acceptance diagram. Restoring the connection, restoring subscriptions, and restoring data continuity are three distinct outcomes.

In the test environment, deliberately disconnect the connection and record the time required for disconnect detection, reauthentication, resubscription, the first valid data message, and state synchronization. After recovery, check whether subscriptions were lost, old messages were processed again, or stale cached data was incorrectly marked as real-time. Channels that maintain incremental state should have their snapshots and sequences resynchronized according to the protocol. Any interval that cannot be backfilled should remain marked as a gap in storage and in the user interface.

Then cross-check samples against an independent authoritative source. Before comparing, standardize the assets, sessions, quote or trade types, adjustments, time precision, and source coverage. Prices from different venues or different quote contributors are not necessarily identical. Sample-based cross-checks can help locate problems but cannot prove full completeness. The report should distinguish vendor documentation, observations from the current test, and elements that remain unverified.

IV. Put History, Licensing, and Scaling Costs into the Same Cost Table

Historical coverage should be checked by “asset × granularity × date.” The ability to retrieve daily bars from five years ago does not mean that minute bars, tick data, or order-book data from the same period are available. At minimum, spot-check the earliest required date, the most recent trading day, and records that cross pagination boundaries. Verify trading suspensions, contract expirations, adjustments, daylight-saving time, and trading-day attribution.

Plans must be compared using the same workload. Suppose a dashboard requires 300 assets, each REST request can query 50 assets, and the dashboard polls every 5 seconds. Basic polling alone then requires ceil(300 / 50) × 60 / 5 = 72 requests per minute; initial loading, retries, and historical queries must be calculated separately. This is only a capacity-budget example and does not represent any vendor’s actual quotas. If WebSocket is used instead, verify how subscriptions are counted, whether channels are counted separately, connection quotas, and downstream distribution costs.

Cost itemQuestions that must be answeredEvidence to retain
API and data entitlementsWhich markets, channels, history, and concurrency are includedCurrent plan documentation and pricing
Data-use authorizationAre internal use, external display, derived results, and redistribution permittedWritten terms covering the relevant use case
Deployment and redundancyHow are backup sources, traffic, storage, connections, and scaling billedCapacity budget based on consistent assumptions
Implementation and maintenanceHow much effort is required for symbol mapping, field adaptation, monitoring, and incident handlingEffort estimates and the operations plan

Use a consistent period for comparisons: total cost = subscription and additional data fees + licensing fees + infrastructure and redundancy costs + implementation and maintenance effort. Do not assume that a specific item will necessarily be charged separately, and do not assume that the monthly fee includes every right of use. The ability to forward data to users from an engineering perspective does not mean that the contract permits redistribution. Whether “derived metrics” may be displayed or sold must also be confirmed separately.

V. The Acceptance Decision Should Be One of Three: Pass, Conditional Pass, or Fail

Turn the preceding checks into a one-page acceptance record containing requirements, thresholds, evidence, results, limitations, and owners. Determine thresholds according to the business’s tolerance and document them before testing. For example, dashboard refresh performance and tick-by-tick research have different requirements and should not share an unsubstantiated millisecond threshold.

  • Pass: There is evidence for all mandatory assets, fields, permissions, and capacity requirements; latency and recovery meet the predefined targets; and total cost falls within budget.
  • Conditional Pass: Only noncritical limitations that the business has explicitly accepted remain, and the permitted scope, temporary measures, and revalidation date are documented. Unverified mandatory items must not be approved under this outcome.
  • Fail: A mandatory capability is missing, a critical quality target is not met, or authorization for the intended use remains unclear.

The final procurement comparison should retain documentation and pricing from the same day or within the same validity period, sampling records collected under identical conditions, and the results of reconnection and backfill tests. Regardless of the candidate, only this evidence can answer whether it is suitable for the project. The total number of assets, the ability to establish a connection, and a single plan price cannot complete the acceptance process on their own.

Sources: TickDB official integration documentation and Ticker, Depth, and Trade documentation, reviewed on October 23, 2026. This article provides a selection methodology and analysis examples; it does not provide live vendor performance-test results. Specific coverage, permissions, authorizations, and prices are subject to the materials available at the time of purchase and validation for the target use case.

Related articles

Stock API: Pricing, Permissions & Access Limits

Stock API: Pricing, Permissions & Access Limits How are stock API interfaces charged, what data can you access after paying, and what restrictions apply during integration? Pricing typically depend…

TickDB Research ·