Introduction: Why Do We Need a Unified API?
If you've worked on financial data development, you've likely experienced this scenario: checking A-share prices requires connecting to East Money or Tushare, Hong Kong stocks need LongBridge or Futu, US stocks require Polygon.io or Yahoo Finance, and forex and precious metals demand OANDA or other data sources. Before your project is even finished, you've already collected a full set of API keys, with each interface having different data formats—just mapping fields can take days.
In reality, while A-shares, Hong Kong stocks, US stocks, forex, and precious metals all belong to price discovery instruments in terms of financial attributes, their API design logic naturally has huge gaps due to fundamental differences in trading rules, data sources, and technical architecture. This article will systematically analyze these five market categories around market data characteristics, quote update mechanisms, API interface forms, data latency requirements, integration complexity, and costs. Finally, we'll demonstrate the complete code implementation from REST queries to WebSocket subscriptions using a specific unified API service (iTick) as an example—this access pattern is equally applicable to other similar services (such as FCS API, OpenClaw, etc.).
I. Comparative Analysis of Market Data and API Solutions
1. A-Share Market
The core characteristic of the A-share market is concentrated trading hours (9:30-11:30, 13:00-15:00) under strict regulatory supervision. For quantitative developers, A-share data has clear tiering: Level-1 quotes provide 5-level bid/ask order books and basic tick data, while Level-2 quotes include 10-level order books, transaction-by-transaction records, and order-by-order high-frequency microstructure data that can reveal the true intentions of market participants.
Official A-share market data comes from the Shanghai Stock Exchange and Shenzhen Stock Exchange. Ordinary developers typically access it through third-party service providers such as Wind, Tonghuashun iFinD, etc., while the open-source Tushare Pro is also a popular entry-level choice for individual developers. Obtaining Level-2 data requires corporate qualifications or cooperation with brokerages, resulting in higher barriers to entry.
Regarding interface protocols, mainstream A-share data services provide both RESTful and WebSocket methods: the former is used for batch retrieval of stock lists, historical K-lines, and other low-frequency data, while the latter is used for subscribing to real-time quote push notifications, with update frequencies reaching snapshot updates every 3 seconds.
2. Hong Kong Stock Market
The Hong Kong stock market has significant differences in trading rules compared to A-shares, such as implementing T+0 intraday trading, no price limit restrictions, and longer trading hours (morning session 9:30-12:00, afternoon session 13:00-16:00). The Hong Kong Exchanges and Clearing Limited (HKEX) officially provides various real-time data subscription services, including real-time trading information push for derivatives markets and stock option markets.
In terms of API access, LongPort OpenAPI is a representative solution in the Hong Kong stock market. It provides both RESTful and WebSocket interfaces, encapsulates multi-language SDKs including Python and C++, supports real-time quote subscriptions and order status push notifications, and can assist developers in building trading or quote analysis tools based on their own investment strategies. Additionally, platforms like Alibaba Cloud Market also provide standardized RESTful API interfaces covering Hong Kong stock real-time quotes and historical data queries.
3. US Stock Market
The US stock market is one of the most liquid stock markets globally, covering major exchanges such as NYSE and NASDAQ. It has extremely high real-time data requirements, supports after-hours and pre-market trading, and its trading hours are almost completely offset from Asian markets. The US stock API ecosystem is relatively mature, with abundant open-source and commercial options.
Represented by high-frequency data service providers like Polygon.io, tick-level real-time data is available with WebSocket push latency below 20 milliseconds. For cost-sensitive developers and startup teams, Yahoo Finance API and Alpha Vantage (providing free call quotas) are common entry-level choices—the former has broad data coverage but occasional stability fluctuations, while the latter is easy to integrate but insufficient for high-frequency trading support.
US stock API access usually only requires configuring simple parameters like region=US to obtain real-time quotes, K-line charts, and company fundamental information from NASDAQ and NYSE. Features supporting batch queries and paginated result returns also make it more efficient when monitoring multiple stocks.
4. Forex Market
The forex market is the largest financial market by trading volume globally, with 24-hour continuous trading spanning four major trading sessions in Sydney, Tokyo, London, and New York. This means APIs must maintain continuous operation around the clock. Another characteristic of forex trading is spread sensitivity—trading costs are directly reflected in bid-ask spreads, so APIs need to provide real Bid/Ask quotes rather than single prices.
Mainstream forex data APIs include professional-grade service providers like OANDA and Forex Feed, with data sources directly from interbank markets providing authentic spread data. Additionally, Open Exchange Rates and CurrencyAPI provide REST APIs for real-time and historical exchange rate queries covering over 200 global currencies, suitable for currency conversion calculations and exchange rate monitoring scenarios.
From a technical implementation perspective, real-time forex trading scenarios must prioritize forex real-time quote APIs supporting WebSocket protocol to ensure quote data push latency is controlled at the millisecond level, avoiding trading losses caused by data lag.
5. Precious Metals Market
The precious metals market includes varieties such as gold and silver, with both spot prices (such as London Gold XAU/USD) and futures contracts. Gold data query APIs are typically built on HTTPS protocol, returning real-time prices in JSON data format, supporting high-concurrency requests and millisecond-level data response. In international markets, London Gold (XAU/USD) serves as the global gold pricing benchmark, with API quotes highly correlated with the US Dollar Index and geopolitical events, requiring data refresh frequencies at second-level or higher. From an interface type perspective, precious metals APIs similarly prioritize WebSocket for real-time data, with REST as supplementary, covering multi-dimensional data including real-time prices, K-line trends, and futures contracts.
II. Architecture Design of Unified API Solutions
Faced with the huge differences in data sources, trading hours, and interface protocols among the five markets mentioned above, how should the architecture of a unified API solution be designed? The core design philosophy lies in building an aggregation gateway layer that encapsulates differences from different data sources in adapter modules, exposing a standardized unified calling specification to the upper layer.
2.1 Layered Architecture
A unified API solution can be divided into three layers from bottom to top: data source access layer, unified gateway layer, and business calling layer.
The data source access layer is responsible for connecting to raw APIs from various markets—A-shares connect to Level-1/Level-2 data sources from Shanghai and Shenzhen Stock Exchanges, Hong Kong stocks connect to HKEX or third-party provider interfaces, US stocks接入 Polygon.io and other data sources, while forex and precious metals each connect to professional quote services. The key at this layer is implementing "protocol adaptation middleware" that encapsulates different protocols from various exchanges such as WebSocket, RESTful, FIX, etc., into unified internal formats.
The unified gateway layer is the core of the entire solution. It receives standard requests from the business calling layer (e.g., { asset: "stock", market: "hk", symbol: "00700", field: "price" }), determines which data source the request should be routed to through routing modules, converts raw data to unified field naming conventions through data normalization modules (for example, "latest price" fields from various markets are all named last_price rather than price or latest), and then manages short-term caching of high-frequency query data through cache management modules to reduce calls to downstream APIs.
The business calling layer is the final SDK or REST interface provided to developers, supporting both HTTP polling and WebSocket real-time push access modes. Developers can unlock multi-scenario data query capabilities with just one API Key, from stock quotes to gold price queries to exchange rate conversions, with unified calling throughout the entire process.
2.2 Core Challenges of Normalization Design
In the above architecture, the most difficult part is field mapping and protocol adaptation. A-share interfaces might call the latest price trade, US stock interfaces call it last, and forex interfaces call them bid and ask—the normalization layer needs a complete mapping table to handle these differences. Currently, solutions like iTick, FCS API, and OpenClaw are practicing this approach in the market, unifying interface differences from different data sources through a single SDK, allowing developers to avoid focusing on lower-level data source implementation details.
2.3 Reasonable Division of Labor Between WebSocket and REST
In unified API solutions, WebSocket and REST each have irreplaceable positions. REST is suitable for initial data pulling, historical K-line queries, stock list maintenance, and other low-frequency operations, while WebSocket is essential for real-time monitoring and quantitative trading scenarios—for T+0 varieties like forex and precious metals, whether disconnection reconnection and heartbeat keep-alive mechanisms are natively supported directly relates to strategy stability. Unified API solutions need to provide both access methods simultaneously, allowing developers to choose as needed.
2.4 Multi-Market Trading Time Misalignment
This is a design challenge often overlooked. When A-shares close, Hong Kong stocks are suspended, and US stocks are just opening, how does the API determine whether the target market being queried is currently trading? Unified solutions need to implement trading calendar management and market status query functions at the gateway layer, returning market status codes rather than data query failure error messages for requests during non-trading hours.
III. Code Examples: Using Unified API to Obtain Multi-Market Quotes
Below demonstrates the complete process from environment preparation to multi-market data access. This access pattern has reference value in other similar services—most unified APIs provide similar REST and WebSocket interfaces, with slight differences only in authentication methods, field naming, and endpoint addresses.
3.1 Environment Preparation
Install necessary Python libraries:
pip install requests websocket-client
3.2 REST API Examples
REST API is the most basic access method for all unified solutions, accessing data endpoints through HTTPS GET requests, usually requiring Token carriage in headers.
Forex Real-Time Quotes
import requests
# Taking iTick as an example, replace with corresponding service provider's endpoint and token in actual use
url = "https://api.itick.org/forex/quote?region=GB&code=EURUSD"
headers = {
"accept": "application/json",
"token": "your_token_here"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
# Different service providers may return different field names, but usually there will be a latest price field
print("EUR/USD Latest Price:", data.get('data', {}).get('ld'))
else:
print("Request Failed:", response.text)
Note: The
ld(last price) in the code is iTick's naming for "latest price"; switching to other service providers might uselast,price, orclose, requiring consultation of corresponding documentation.
A-Share Real-Time Quotes
A-share market usually distinguishes exchanges through the region parameter—for example, SH represents Shanghai Stock Exchange, SZ represents Shenzhen Stock Exchange.
# Get Kweichow Moutai (600519) real-time quote
url = "https://api.itick.org/stock/quote?region=SH&code=600519"
headers = {"accept": "application/json", "token": "your_token"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
stock = data.get('data', {})
print(f"{stock.get('s')} Latest Price: {stock.get('ld')}")
print(f"Change Rate: {stock.get('chp')}% Volume: {stock.get('v')}")
Hong Kong and US Stock Real-Time Quotes
# Get Tencent Holdings (00700) Hong Kong stock real-time quote
url_hk = "https://api.itick.org/stock/quote?region=HK&code=00700"
# Get Apple (AAPL) US stock real-time quote
url_us = "https://api.itick.org/stock/quote?region=US&code=AAPL"
headers = {"accept": "application/json", "token": "your_token"}
response_hk = requests.get(url_hk, headers=headers)
if response_hk.status_code == 200:
tencent = response_hk.json().get('data', {})
print(f"Tencent Holdings Latest Price: {tencent.get('ld')} HKD")
response_us = requests.get(url_us, headers=headers)
if response_us.status_code == 200:
aapl = response_us.json().get('data', {})
print(f"Apple Latest Price: {aapl.get('ld')} USD")
Market code mappings for different unified API service providers are largely similar, commonly being: SH (Shanghai), SZ (Shenzhen), HK (Hong Kong), US (US Stocks). Returned key fields usually include latest price, opening price, highest price, lowest price, previous closing price, change rate, trading volume, etc.
Order Book (Depth Quotes)
For scenarios requiring analysis of pending order data, unified APIs usually provide separate depth interfaces:
url_depth = "https://api.itick.org/stock/depth?region=SH&code=600519"
headers = {"accept": "application/json", "token": "your_token"}
response = requests.get(url_depth, headers=headers)
if response.status_code == 200:
data = response.json()
depth = data.get('data', {})
print("Buy Side (Bids): Top 5 levels")
for bid in depth.get('b', [])[:5]:
print(f" Price: {bid.get('p')} Order Volume: {bid.get('v')}")
print("Sell Side (Asks): Top 5 levels")
for ask in depth.get('a', [])[:5]:
print(f" Price: {ask.get('p')} Order Volume: {ask.get('v')}")
Historical K-Line Queries
# Get EUR/USD 1-hour K-lines, latest 100 bars
url_kline = "https://api.itick.org/forex/kline?region=GB&code=EURUSD&kType=5&limit=100"
headers = {"accept": "application/json", "token": "your_token"}
response = requests.get(url_kline, headers=headers)
if response.status_code == 200:
klines = response.json().get('data', [])
for kline in klines[-5:]:
print(f"Open:{kline.get('o')} High:{kline.get('h')} "
f"Low:{kline.get('l')} Close:{kline.get('c')}")
K-line period parameters (such as kType=5) are defined differently by various service providers, please consult corresponding documentation before use.
3.3 WebSocket Real-Time Quote Subscription
REST interfaces are suitable for batch queries and historical data retrieval, but for scenarios with high real-time requirements, WebSocket is a more appropriate choice. Unified API solutions usually provide independent WebSocket endpoints for different varieties and support subscribing to multiple instruments.
Below uses forex real-time quote subscription as an example, with code structure equally applicable to other service providers (only requiring replacement of endpoint and authentication method).
import websocket
import json
WS_URL = "wss://api-free.itick.org/forex"
API_TOKEN = "your_token"
def on_message(ws, message):
data = json.loads(message)
if "data" in data and "quote" in data["data"]:
q = data["data"]["quote"]
print(f"{q['code']} Latest Price: {q['ld']} Bid: {q.get('bid')} Ask: {q.get('ask')}")
elif data.get("msg") == "Connected Successfully":
print("✅ WebSocket Connection Successful")
elif data.get("resAc") == "subscribe" and data.get("code") == 1:
print("✅ Subscription Successful")
def on_open(ws):
# Subscribe to multiple currency pairs, format varies by service provider
subscribe_msg = json.dumps({
"ac": "subscribe",
"params": "EURUSD$GB,GBPUSD$GB",
"types": "quote"
})
ws.send(subscribe_msg)
def on_error(ws, error):
print(f"❌ Error: {error}")
def on_close(ws, close_status_code, close_msg):
print("Connection closed, attempting reconnection...")
reconnect()
def reconnect():
import time
time.sleep(5)
start_websocket()
def start_websocket():
ws = websocket.WebSocketApp(WS_URL,
header={"token": API_TOKEN},
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.run_forever()
if __name__ == "__main__":
start_websocket()
Notes:
- Tokens are usually placed in the
tokenfield of the header; some service providers may require placement in URL parameters or use Bearer Auth.- WebSocket connections are prone to disconnection due to network fluctuations; production environments must implement automatic reconnection and heartbeat keep-alive mechanisms (e.g., sending ping every 30 seconds).
- Subscription message formats (such as
ac,params,types) vary among different service providers; please refer to specific documentation.
Stock Market WebSocket Subscription (Multiple Instruments)
For scenarios requiring simultaneous monitoring of A-shares, Hong Kong stocks, and US stocks, unified APIs generally allow mixed subscription within a single connection:
def start_stock_websocket():
ws_url = "wss://api-free.itick.org/stock" # Replace with actual endpoint
api_token = "your_token"
def on_open(ws):
subscribe_msg = json.dumps({
"ac": "subscribe",
"params": "600519$SH,000858$SZ,00700$HK,AAPL$US,MSFT$US",
"types": "tick,quote,depth"
})
ws.send(subscribe_msg)
print("✅ Subscription request sent")
def on_message(ws, message):
data = json.loads(message)
if "data" in data:
market_data = data["data"]
if "quote" in market_data:
q = market_data["quote"]
print(f"{q.get('code')} Latest Price: {q.get('ld')} Change Rate: {q.get('chp')}%")
elif "tick" in market_data:
t = market_data["tick"]
print(f"Trade: {t.get('code')} Price:{t.get('p')} Volume:{t.get('v')}")
ws = websocket.WebSocketApp(ws_url,
header={"token": api_token},
on_open=on_open,
on_message=on_message)
ws.run_forever()
Java Access Example
For Java technology stacks, standard JSR-356 WebSocket clients can also be used for access:
import javax.websocket.*;
import java.net.URI;
@ClientEndpoint
public class MarketDataClient {
private static final String WS_URL = "wss://api.itick.org/stock";
private static final String AUTH_MSG = "{\"ac\":\"auth\",\"params\":\"your_apikey\"}";
private static final String SUB_MSG = "{\"ac\":\"subscribe\",\"params\":\"EURUSD$GB,GBPUSD$GB\",\"types\":\"quote\"}";
@OnOpen
public void onOpen(Session session) throws IOException {
session.getBasicRemote().sendText(AUTH_MSG);
session.getBasicRemote().sendText(SUB_MSG);
}
@OnMessage
public void onMessage(String message) {
System.out.println("Received: " + message);
}
public static void main(String[] args) throws Exception {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(MarketDataClient.class, new URI(WS_URL));
}
}
Different service providers may have slight differences in authentication steps: some require sending authentication messages first, while others complete authentication through Headers during connection. Be sure to read corresponding documentation before access.
Production Environment Best Practices:
- Store sensitive information (Tokens) in environment variables or configuration files; never hardcode.
- WebSocket connections must implement automatic reconnection mechanisms and heartbeat keep-alive (recommended to send ping every 30 seconds).
- Pay attention to start/end times and period granularity supported by different service providers when backtesting with historical K-line data.
- Free tiers usually have call frequency limits and concurrent connection number caps; upgrade to paid plans if high throughput is required.
IV. Comparison of Mainstream Service Provider Solutions
In the 2026 market, there are various unified API solutions available, with significant differences in coverage and pricing strategies:
- iTick: Provides three access protocols: REST + WebSocket + FIX, covering stocks (A-shares/US stocks/Hong Kong stocks), forex, precious metals, indices, cryptocurrencies, and other assets. Free tier supports basic real-time quotes and K-line queries, while paid versions provide higher throughput and depth data.
- FCS API: Focuses on cost-effectiveness, covering over 2000 forex pairs, mainly using RESTful interfaces with approximately 200 milliseconds latency, suitable for multi-asset retail investors and startup teams.
- OpenClaw: Lightweight open-source solution that can cover full-category data including A-shares, US stocks, Hong Kong stocks, forex, and precious metals by configuring standard quote interfaces, supporting both HTTP and WebSocket.
- Polygon.io: Specializes in the US stock market, supporting tick-level data, but does not provide forex and precious metals, suitable for developers focusing only on US stocks.
Pitfall Warning: When choosing unified API solutions, pay special attention to whether they truly cover all your required varieties. For example, while Polygon.io performs excellently in the US market, it doesn't support forex and gold data. Choosing it would require purchasing additional APIs separately, directly doubling costs and maintenance complexity.
V. Summary of Key Decision Factors
When evaluating and selecting multi-market unified API solutions, the following four dimensions deserve focused attention:
Latency and Real-Time Performance is the first dimension. Quantitative trading usually requires WebSocket latency below 50 milliseconds. If only doing basic quote monitoring, REST polling can also meet requirements; but if involving real-time trading of forex and precious metals, WebSocket is almost a mandatory requirement.
Data Coverage Range is the second dimension. Confirm whether the API truly supports target markets—A-share Level-1 or Level-2, Hong Kong stock real-time quotes or historical data, US stock tick-level or minute-level, and specific varieties of forex and precious metals (such as London Gold XAU/USD, Silver XAG/USD, etc.).
Pricing Model is the third dimension. Commercial solutions usually charge by call count, with free versions often having call frequency limits or data delays. Most service providers offer free tiers for developer evaluation and prototype verification.
Developer Experience is the fourth dimension, including whether documentation is comprehensive, whether SDKs support mainstream languages, and whether WebSocket connection reconnection mechanisms and heartbeat keep-alive are natively implemented.
Conclusion
From A-share tick-by-tick order books to US stock tick-level data, from forex spreads to precious metals K-line trends, each asset category corresponds to unique trading logic and data characteristics. The significance of multi-market unified API solutions lies not in smoothing out these differences, but in encapsulating differences at the gateway layer, allowing developers to avoid reinventing the wheel—no need to relearn a set of API signatures for each market, nor maintain an increasingly bloated API Key list.
The code examples provided in this article have design patterns (REST + WebSocket, Token authentication, market parameter separation) that are widely applicable in other similar services. Whichever service provider you ultimately choose, mastering the idea of unified access can help you quickly build cross-market quote monitoring or quantitative trading systems. Before starting integration, be sure to carefully read the official documentation of your chosen service, as each platform has its uniqueness in authentication methods, field naming, and rate limiting.
Reference Documentation: https://blog.itick.org/stock-api/hkus-stock-api-comparison-guide
GitHub: https://github.com/itick-org/
Top comments (0)