Essential Data Sources for HK Stock Investors: Comparing Three Options — Which is Best for Real-Time Data and Backtesting?
TickDB Research ·
Essential Data Sources for HK Stock Investors: Comparing Three Options — Which is Best for Real-Time Data and Backtesting?

Building a Hong Kong stock watchlist dashboard or backtesting a HK stock strategy — the first step is usually finding a data interface. But once you actually start integrating, the questions become concrete: Is this the latest quote or a changing daily candlestick? The volume is already in shares — do you need to multiply by lot size? There's a gap in historical data — is the market closed, the stock suspended, or did the interface only return partial records?
These questions directly affect your selection. Dashboards prioritize update methods and staleness detection; backtesting prioritizes historical coverage, field definitions, and reproducibility. The same "HK stock support" feature description may not answer both types of needs.
This article compares Futu OpenAPI, Interactive Brokers (IBKR) API, and TickDB for their data capabilities in HK stock quotes and price strategy backtesting. The first two connect to broker accounts and trading tools; the third provides market data via a standalone interface. This article compares data access only — it does not evaluate broker trading services. "Three major" here refers only to the three objects selected for this article, not market share or industry ranking. Interface documentation was verified as of October 8, 2026; this article is a documentation and engineering methodology comparison, not a latency test under identical conditions across all three.
1. First, Clarify Which Type of "Real-Time" You Need
If the page refreshes the latest price at intervals, your primary need is market data snapshots: each request returns the state near the query moment. If price changes need to trigger alerts or update local state, your need is continuous streaming: establish a connection, subscribe to symbols, then process subsequent messages one by one.
There's also a commonly confused type of data: real-time daily bars. This describes the open, high, low, close, and volume statistics forming since market open — it is not tick-by-tick trade data, and cannot reconstruct the sequence of every price change during the session.
Backtesting faces a different requirement: when a strategy makes a decision at a historical moment, what data was already confirmed? Using the day's final closing price in the morning, or bringing in that day's final volume into morning filtering criteria — even with perfectly accurate data — introduces look-ahead bias.
Therefore, start by writing your task as a verifiable statement. For example: "Track 30 stocks, stop triggering alerts when data expires," or "Save daily bars and adjustment factors for a specified three-year range, and be able to run the same backtest repeatedly." Only with this statement can you identify which capability gaps affect your project.
2. Where to Start with Each of the Three Options
Futu OpenAPI: Best for validating from an existing HK stock toolchain
Futu provides quote, tick, order book, and candlestick market data interfaces. When choosing the OpenD + SDK path, you need to run and log into OpenD, then have your program connect to the gateway, subscribe, and process streaming data. The official portal also lists gateway-free REST access, so it's inaccurate to broadly state "Futu can only be used via a local gateway" — different paths should be verified against their respective documentation. Futu access paths, Market data interface overview
If you're already using Futu and plan to connect your HK stock dashboard, research programs, and existing tools, this is a path worth trying first. However, market data available in the app doesn't guarantee identical API permissions. Futu's documentation describes market data permissions, subscription quotas, and historical candlestick quotas separately — verify against your own account before using someone else's free entitlements as assurance. Permissions and quotas
On the history side, OpenD's request_history_kline supports range queries and pagination. The documentation lists minute bars covering approximately 8 years and daily bars approximately 20 years, with symbol-based historical quotas. This range description doesn't replace checking actual coverage per security. When batch backfilling, you need to handle page_req_key while managing symbol quotas and request frequency. Historical candlestick interface
Interactive Brokers IBKR: Best for cross-market programmatic workflows with an existing account
If you're already using Interactive Brokers and want HK stocks and other markets on a unified programmatic workflow, IBKR is worth considering. Its TWS API connects via TCP Socket to TWS or IB Gateway; there's also a Web API path — these two interfaces have different authentication, session, and rate-limiting characteristics and shouldn't be mixed. TWS API introduction, Web API documentation
Selection requires confirming not just "whether an API exists" but also whether the username has the required market data subscriptions, which session type the program uses, and whether you're getting real-time or delayed data. IBKR's official documentation states that most securities require corresponding Level 1 subscriptions to receive market data via API; specific HK stock varieties and depth requirements still need verification against your account entitlements. API market data subscription requirements
Historical backtesting requires even more caution: the official documentation lists categories of unavailable data, such as 30-second or shorter candlesticks older than six months, and data for securities no longer trading. Don't misread this as "all minute bars can only query six months back" — but also don't assume that because you can query current stocks, delisted samples are equally complete. For strategies requiring full-market historical samples, this could determine whether you need to supplement with independent research data. Historical data limitations documentation
Market Data Service Interfaces: Clarify the data task first, then verify operational boundaries
If your project primarily handles dashboards, scanning, and data storage, you can select market data access as a separate module. The ability to return current prices, push updates, and query historical ranges are three distinct capabilities — one should not be used as a proxy for the other two.
The three candidates are placed in the same diagram below, with access paths and required verification conditions listed for each. The scenario recommendations are based on interface characteristics, not latency, stability, or pricing rankings.

Figure 1: Paths and conditions for the three access options. Actual permissions, data coverage, and operational performance require separate verification.
Streaming applications also need to distinguish between "restore latest state" and "backfill all events during disconnection." A dashboard may only need the latest price restored; tick-level research requires explicit event compensation mechanisms. Reconnection itself doesn't prove both have been completed.
3. Choose Your Test Order Based on Existing Conditions
| Your primary task | Path to verify first | Conditions determining feasibility |
|---|---|---|
| Already have a Futu account, building HK stock dashboard or research tools | Futu OpenAPI | Selected path can be deployed; API permissions and subscription quotas meet requirements |
| Already have an IBKR account, need cross-market programmatic integration | IBKR corresponding API | Market data subscriptions, session management, contract identification, and historical coverage meet requirements |
| Primary need is market data ingestion, dashboard, and data service integration | Market data service interfaces in Figure 1 | Subscription scale, range queries, field definitions, and reconnection recovery meet requirements |
| Multi-year full-market backtesting, including delisted securities | Verify each candidate's data coverage individually | Sample range and corporate action data complete — cannot rely on existing stocks only |
Existing accounts may reduce some integration steps but don't automatically mean lowest cost; not needing trading functionality doesn't mean any standalone market data interface can satisfy full-market historical research. Calculate market data entitlements, subscription scale, historical backfill volume, and maintenance costs together.
Data can also be used in combination, but sources should be preserved. When using one source for real-time data and another's historical candlesticks, only by first aligning symbols, statistical windows, and adjustment specifications can differences be interpreted as quality issues.
4. Before HK Stock Backtesting, Block Four Types of Errors
1. Stock codes, markets, and currencies must be saved together
The same security may use zero-padded codes, market suffixes, or another standard format across different interfaces. Don't let spreadsheet software convert codes to integers first, then try to recover the original identifier by guessing padding. Keep the original code and map to an internal identifier through a security master table.
The master table should also include security type, listing status, pricing currency, and trading unit. For interfaces like IBKR that use contract objects, you can't just reformat another vendor's string code and assume it identifies the same security — verify contract identifier, market, and currency, and save the mapping.
This is especially important for cross-market portfolios: "yuan" is part of the monetary denomination and cannot alone determine whether it's RMB. Keep original currency amounts first; when conversion is needed, specify the exchange rate source, corresponding date, and conversion timestamp.
2. Handle volume fields and lot sizes separately
Lot size is a security attribute; volume unit is an interface field attribute. Only when a field explicitly states it's measured in "lots" do you need to convert using the corresponding trading unit; values already measured in "shares" should not be multiplied by lot size. Adaptation rules should be bound to specific interfaces and fields, not applied as a single fixed multiplier to all HK stock data.
Below, simulated input demonstrates a strict conversion function. Conversion is permitted only when the source explicitly declares the unit as "lot" and you have obtained the lot size for that security on that date. The 500 in the example is a hypothetical value and does not reference any real stock.
from decimal import Decimal
def volume_shares(value, unit, lot_size=None):
n = Decimal(str(value))
if not n.is_finite() or n < 0:
raise ValueError("Volume must be a finite non-negative number")
if unit == "share":
result = n
elif unit == "lot" and lot_size is not None:
size = Decimal(str(lot_size))
if not size.is_finite() or size <= 0:
raise ValueError("Lot size must be a finite positive number")
if size != size.to_integral_value():
raise ValueError("Lot size must be an integer")
result = n * size
else:
raise ValueError("Unit or lot size for the corresponding date not confirmed")
if result != result.to_integral_value():
raise ValueError("Result must be an integer share count")
return int(result)
# Simulated data, not vendor return values.
assert volume_shares("1000", "share") == 1000
assert volume_shares("2", "lot", 500) == 1000
This function only handles units; it doesn't check whether a record is duplicated, nor whether volume is a cumulative daily value or a single candlestick value. The adaptation table should also retain the statistical window — don't directly sum cumulative volumes as if they were daily volumes.
3. Same trading date doesn't mean same statistical period
Minute data should use HK market's own trading calendar and session rules, handling midday breaks, half-day sessions, and call auctions separately — don't mechanically fill an entire day with a continuous minute sequence. For missing minutes, first determine whether that period should have records and whether the data source omitted zero-volume periods, then decide how to handle.
Even for candlesticks, confirm whether they describe trade prices, bid-ask quotes, or midpoints. IBKR's official troubleshooting documentation lists TRADES, MIDPOINT, BID_ASK, and timezone differences as common causes of chart discrepancies. Before comparing, save the data type and period parameters from the request — don't assume rows with the same OHLC field names are directly comparable. IBKR chart specification troubleshooting
Timestamps should also be separated clearly: source time, receipt time, trading date, and candlestick label should each be saved separately. Displaying a timestamp as Hong Kong local time only completes timezone conversion — it doesn't yet determine whether it represents period start, period end, or most recent state update.
4. Adjustment data needs versions; playback needs point-in-time availability
Adjusted prices are suitable for continuous indicator calculation, but original prices, adjustment method, obtainable factors or corporate action references, and retrieval dates should all be preserved. One easily overlooked detail: Futu OpenD's request_history_kline default parameter is AuType.QFQ, which is forward adjustment. When cross-source reconciling, explicitly specify the same specification — don't assume all interfaces default to unadjusted prices. Historical candlestick parameters
Also, indicator prices and simulated execution prices should be handled separately. Dividends, splits, consolidations, and position changes need to coordinate with price sequences to avoid using already-adjusted prices while also double-counting the same corporate action. Whether look-ahead bias exists depends on what data the strategy used at that time — not just the word "forward-adjusted."

Figure 2: Verification sequence before HK stock data ingestion and playback. This diagram illustrates methodology.
5. Turn "Suitable" into Verifiable Conclusions with a Small Sample
Before full integration, assign each candidate the same acceptance task: select one actively traded stock, a period with suspension records, and a historical range covering corporate actions. Real-time tasks observe one trading session continuously; backtesting tasks fix start/end dates, period, and adjustment method.
Below is a minimal request example to fetch recent daily bars — valid keys must be configured on the local machine. Endpoint, authentication method, and parameters have been verified against official documentation; this article did not execute live requests and does not present this as a quality comparison across the three.
: "${TICKDB_API_KEY:?Please set the API key environment variable first}"
curl --fail-with-body --silent --show-error --get \
'https://api.tickdb.ai/v1/market/kline' \
-H "X-API-Key: ${TICKDB_API_KEY}" \
--data-urlencode 'symbol=700.HK' \
--data-urlencode 'interval=1d' \
--data-urlencode 'adjust=none' \
--data-urlencode 'limit=10'
After the response arrives, first check the HTTP status and whether the business code is 0, then check the date range and content of data.klines. Requesting 10 bars doesn't guarantee 10 are returned; the last bar may still be forming. This request doesn't specify start and end times and cannot replace completeness verification for your target historical range.
When verifying, retain the following records to facilitate explaining differences:
- Coverage records: Compare expected set with returned set date-by-date or time-window-by-time-window, distinguishing closed markets, suspensions, not-yet-listed, and collection failures.
- Specification records: Save original code, currency, unit, period, and adjustment method — only align these before comparing prices and volumes.
- Real-time records: Save source time, receipt time, and connection status. When time semantics aren't confirmed, don't subtract the two and claim the result is end-to-end latency.
- Recovery records: Actively interrupt collection, check whether the application-required state is rebuilt after recovery, and separately annotate event gaps.
- Version records: Save original responses, conversion rules, factors, and query times; rerun with the same input to confirm results are reproducible.
If you already have a Futu or IBKR account, start by verifying a small sample from the corresponding API; if you're primarily building a market data application, compare access conditions based on data module requirements. Regardless of which path you choose, long-term backtesting first resolves coverage, specifications, and version preservation; intraday operations first verify update semantics and failure recovery.
For HK stocks, selection can't stop at "whether quotes are available." Connecting code, currency, unit, trading session, and adjustment references into a traceable data chain is the only way to know whether your data can support the current task.
Official Reference Materials
- Futu: Access paths, Market data interface overview, Permissions and quotas, Historical candlesticks.
- Interactive Brokers IBKR: TWS API, API market data subscriptions, Unavailable historical data.
- Streaming and request examples: Ticker subscription protocol, Candlestick parameters and limits, Connection recovery documentation.