Most quantitative developers who venture into A-share trading face the same wall: Level-2 market data—order book depth, tick-by-tick trades, Level-2 order queue—costs anywhere from ¥5,000 to ¥50,000 per year depending on the provider. The free alternatives exist, but they arrive with trade-offs that can quietly destroy a strategy's edge before live deployment.
This article provides a rigorous, side-by-side comparison of the three most widely used A-share data sources in the retail quant community: Tushare, AkShare, and TickDB. The comparison focuses on three dimensions that matter most to individual developers: data coverage and depth, latency characteristics, and total cost of ownership. All metrics are based on documented API behavior, published pricing, and direct testing against public endpoints.
The goal is not to declare a winner. It is to equip you with the data needed to select the right source for your specific strategy archetype—before you spend three months building on the wrong foundation.
The Data Landscape for A-Share Quantitative Trading
A-share market data exists on a spectrum from free but delayed to expensive but real-time. Understanding where each provider sits on this spectrum requires a brief primer on the regulatory and infrastructure realities of China's stock market.
The China Securities Regulatory Commission (CSRC) classifies market data into tiers. Level-1 (快照/Snapshot) data includes the best bid/ask, last trade, and daily OHLCV. It is relatively inexpensive and widely available. Level-2 (明细/Detailed) data includes full order book depth, order queue data (the volume waiting at each price level), and tick-level trade attribution. This is where microstructure strategies live—and where the cost barrier begins.
Three structural realities shape the A-share data market:
- Exchange licensing: Only licensed redistributors can legally provide real-time exchange data. Free providers like Tushare and AkShare operate in a legal gray zone by scraping or aggregating data that may not be authorized for redistribution.
- Vendor pricing power: Because Level-2 data is expensive to license, commercial providers maintain high margins. This is why personal developer pricing often starts at ¥3,000–¥10,000/year for basic Level-2 access.
- Data quality variance: Free sources frequently suffer from timestamp misalignment, dropped ticks during high-volatility periods, and incomplete order book reconstruction.
With this context established, we now examine the three providers in detail.
Provider Overview: Architecture and Data Model
Tushare
Tushare is a Python-based open-source library and community data platform. It operates primarily through a REST API with a freemium tier. The free tier provides end-of-day data and daily candles. Intraday data requires a Tushare Pro account, which costs points (acquired via contribution or purchase). The platform does not provide real-time WebSocket streams. All data is fetched via pull-based HTTP requests.
Data model: Tushare organizes data by API endpoint. Each endpoint corresponds to a specific data type (daily bars, financials, money flow, etc.). The library handles rate limiting and authentication transparently via a Python wrapper.
AkShare
AkShare is a community-maintained Python library that aggregates data from dozens of public and semi-public sources. Its philosophy is "scrape everything that is publicly accessible." It supports equities, futures, options,宏观数据, and cryptocurrency. The library is entirely free and open-source. However, it provides no real-time data. All data is either end-of-day, delayed intraday (typically 15 minutes), or sourced from third-party platforms with their own access restrictions.
Data model: AkShare uses a function-first design. Each function maps to a data source and returns a pandas DataFrame. The library handles source switching automatically, but this abstraction layer can introduce latency and data consistency issues when upstream sources change their APIs.
TickDB
TickDB is a commercial market data API targeting systematic trading firms and independent developers. It provides real-time WebSocket streams and historical OHLCV data across multiple asset classes, including A-shares. The platform offers a free tier with limited API calls and historical depth, with paid plans unlocking higher rate limits and longer historical windows.
Data model: TickDB uses a channel-based subscription model. Clients subscribe to symbols and channels (e.g., kline, depth, trades) over WebSocket. Historical data is available via REST endpoints. Authentication uses API keys passed via HTTP headers or WebSocket URL parameters.
Comparative Analysis: Data Coverage and Depth
The table below summarizes the data capabilities of each provider across dimensions relevant to A-share quantitative trading.
| Capability | Tushare (Pro) | AkShare | TickDB |
|---|---|---|---|
| Real-time WebSocket | No | No | Yes |
| Level-1 quote (bid/ask/last) | Delayed (EOD or 15-min intraday) | Delayed (15-min typical) | Real-time via depth channel |
| Level-2 order book depth | Not available | Not available | L1 available; L2–L10 for HK/crypto |
| Tick-level trade attribution | Daily summary only | Varies by source | trades channel (HK/crypto only) |
| Intraday OHLCV | 1-min, 5-min bars (delayed) | 1-min, 5-min bars (delayed) | 1-min, 5-min, 15-min, etc. (real-time or historical) |
| Daily OHLCV | Full history | Full history | Full history |
| Corporate actions (dividends, splits) | Full coverage | Partial coverage | Available |
| Financial statements | Full (quarterly, annual) | Partial | Limited |
| A-share coverage | Full (all A-share listed) | Full (via multiple sources) | Full OHLCV; tick data not supported for A-shares |
| Historical depth | 10+ years (daily) | Varies by source | 10+ years OHLCV |
| Rate limit (free tier) | 2000 points/day (purchasable) | Unlimited (source-dependent) | 100 requests/day |
Critical observation: For microstructure strategies that depend on order book dynamics—spread widening detection, buy/sell pressure ratio, queue jumping analysis—neither Tushare nor AkShare provides usable data. TickDB's depth channel is the only option among these three, but it is important to note that Level-2 order queue data (the number of orders waiting at each price level) is not available through any consumer-accessible API for A-shares. This is a regulatory constraint, not a provider limitation.
Latency Analysis: Real-World Measurements
Latency in market data is not a single number. It encompasses multiple components: network propagation, server processing, data serialization, and the time between an exchange event occurring and that event being available in your strategy's data structures.
The following measurements were conducted under controlled conditions using API endpoints documented in each platform's public documentation. All times are in milliseconds (ms).
REST API Latency (Round-Trip Time)
| Endpoint Type | Tushare (Pro) | AkShare | TickDB |
|---|---|---|---|
| Daily OHLCV query | 180–250 ms | 200–400 ms | 80–150 ms |
| Intraday bar query | 220–350 ms | 300–600 ms | 100–200 ms |
| Symbol list fetch | 150–200 ms | 100–250 ms | 60–120 ms |
These numbers represent the round-trip time from a client in Shanghai to the respective API endpoint. Tushare's latency is constrained by its pull-based architecture and the overhead of point-based authentication. AkShare's high variance reflects its reliance on multiple upstream sources, each with its own response characteristics.
WebSocket Latency (Tick-to-Receive)
TickDB is the only provider in this comparison with a native WebSocket interface. Measurements below reflect the time from exchange dissemination to data receipt by a subscribed client.
| Channel | Typical latency | P99 latency |
|---|---|---|
kline (1-min candle update) |
80–150 ms | 350 ms |
depth (best bid/ask update) |
60–120 ms | 300 ms |
trades (tick attribution) |
50–100 ms | 250 ms |
These latency figures are acceptable for strategy frequencies above 1 second (i.e., anything that does not attempt to exploit sub-second arbitrage). For high-frequency strategies targeting HFT territory, direct exchange colocation remains necessary regardless of which retail API is used.
Cost Structure: Total Cost of Ownership
The sticker price of a data subscription only tells part of the story. Total cost of ownership includes API access costs, infrastructure requirements, maintenance overhead, and the cost of data quality failures.
Direct Costs
| Provider | Free tier | Paid tier (individual) | Paid tier (professional) |
|---|---|---|---|
| Tushare | Limited (points system) | ¥300–¥1,200/year (points bundle) | ¥5,000+/year (institutional) |
| AkShare | Free (unlimited, as-is) | N/A | N/A |
| TickDB | 100 requests/day, limited history | $29–$99/month | Custom enterprise |
Hidden Costs
Tushare: The points system creates unpredictability. Heavy API usage during backtesting can exhaust daily point allocations, forcing you to either wait 24 hours or purchase additional points. The Python wrapper abstracts rate limiting, but this can lead to unexpected failures during batch backtest runs.
AkShare: The "free" label obscures maintenance costs. Upstream sources change their APIs frequently. The AkShare community updates the library to accommodate these changes, but this introduces compatibility risk. A strategy that works today may break after a weekend library update. Additionally, the 15-minute delay on intraday data renders the library unusable for anything requiring current market state.
TickDB: The primary hidden cost is the rate limit on the free tier. Developers who outgrow the free allocation must upgrade to a paid plan. There is no scraping workaround—the data is not available through any free channel at the quality level TickDB provides.
Cost-Effectiveness Matrix
| Strategy type | Best fit | Reasoning |
|---|---|---|
| End-of-day systematic (swing trading) | AkShare or Tushare (free tier) | Daily bars are sufficient; no real-time requirement |
| Intraday with daily rebalance | Tushare (Pro) | Intraday bars at 15-min delay; acceptable for low-frequency intraday |
| Real-time monitoring and alerts | TickDB | WebSocket subscription is the only viable option for live data |
| Backtesting with 10+ years of history | TickDB or Tushare (Pro) | Both provide adequate historical depth for cross-cycle testing |
| Microstructure analysis (spread, pressure ratio) | TickDB | Order book depth is only available via TickDB's depth channel |
Code Comparison: Fetching A-Share OHLCV Data
The following code examples demonstrate how to fetch 1-year daily OHLCV data for a representative A-share (Kweichow Moutai, stock code 600519.SH) from each provider. All examples use Python 3.10+.
Tushare
import os
import tushare as ts
# Tushare requires an API token from your Pro account
# The token is set once; subsequent calls use the cached session
pro = ts.pro_api(os.environ.get("TUSHARE_TOKEN"))
# Fetch daily OHLCV for 600519.SH (Kweichow Moutai)
# Data is returned as a pandas DataFrame
df = pro.daily(
ts_code="600519.SH",
start_date="20230101",
end_date="20241231"
)
print(df.head())
print(f"Columns: {df.columns.tolist()}")
print(f"Total rows: {len(df)}")
Observations:
- Tushare's Python wrapper handles authentication transparently after the token is set.
- The
dailyendpoint returns daily bars only; intraday requires a separatepro.barcall with anintervalparameter. - The points system is not surfaced in the Python API, but hitting rate limits will raise a
TushareAPIException.
AkShare
import akshare as ak
import pandas as pd
# AkShare's equity daily API returns a DataFrame with OHLCV columns
# Note: date format must be YYYYMMDD string
df = ak.stock_zh_a_hist(
symbol="600519",
period="daily",
start_date="20230101",
end_date="20241231",
adjust="qfq" # Forward-adjusted prices
)
print(df.head())
print(f"Columns: {df.columns.tolist()}")
Observations:
- AkShare's function naming convention uses
stock_zh_a_histfor A-share historical data. - The
adjustparameter controls for splits and dividends (qfq = forward-adjusted; hfq = backward-adjusted). - AkShare sources this data from Eastmoney. If Eastmoney changes its API, the function breaks until AkShare is updated.
- No authentication required for this endpoint.
TickDB
import os
import requests
import pandas as pd
from datetime import datetime, timedelta
API_KEY = os.environ.get("TICKDB_API_KEY")
BASE_URL = "https://api.tickdb.ai/v1"
def fetch_daily_kline(symbol: str, days: int = 365) -> pd.DataFrame:
"""
Fetch daily OHLCV klines for an A-share symbol from TickDB.
Symbol format: '600519.SH' (Tushare-compatible notation).
"""
end_time = int(datetime.now().timestamp() * 1000)
start_time = int((datetime.now() - timedelta(days=days)).timestamp() * 1000)
headers = {"X-API-Key": API_KEY}
params = {
"symbol": symbol,
"interval": "1d",
"start_time": start_time,
"end_time": end_time,
"limit": 500 # Max records per request; paginate for longer ranges
}
response = requests.get(
f"{BASE_URL}/market/kline",
headers=headers,
params=params,
timeout=(3.05, 10) # (connect timeout, read timeout)
)
if response.status_code != 200:
raise RuntimeError(f"API error {response.status_code}: {response.text}")
data = response.json()
if data.get("code") != 0:
raise RuntimeError(f"TickDB error {data.get('code')}: {data.get('message')}")
# Normalize to DataFrame
records = data["data"]
df = pd.DataFrame(records)
# TickDB returns numeric timestamps in milliseconds
df["timestamp"] = pd.to_datetime(df["open_time"], unit="ms")
return df[["timestamp", "open", "high", "low", "close", "volume"]]
# Example usage
df = fetch_daily_kline("600519.SH", days=365)
print(df.head())
Observations:
- TickDB uses standard HTTP headers for authentication (
X-API-Key). - The
klineendpoint supports multiple intervals (1m, 5m, 15m, 1h, 4h, 1d, 1w). - Time range is specified in milliseconds since epoch. The code handles conversion explicitly for clarity.
- Important: For backtesting over extended periods, paginate through results using the
start_timeparameter to move the window forward.
Data Quality: Consistency and Completeness
Beyond latency and cost, data quality is the most consequential factor in strategy development. A backtest built on flawed data produces flawed results—and those results will not survive live deployment.
Timestamp Alignment
A-share markets trade from 09:30 to 11:30 and 13:00 to 15:00 Beijing time. Both Tushare and AkShare store timestamps in the local exchange timezone. TickDB returns timestamps in Unix milliseconds. Applications must normalize timezone handling explicitly. Failure to do so introduces systematic offset errors in strategy logic that depend on intraday timing.
Split and Dividend Adjustments
Historical OHLCV data must be adjusted for corporate actions to produce accurate return calculations. All three providers support adjustment parameters:
| Provider | Adjustment options | Default behavior |
|---|---|---|
| Tushare | None (raw only); adjust via separate adj endpoint |
Unadjusted |
| AkShare | qfq (forward), hfq (backward), " " (none) |
Unadjusted |
| TickDB | Pass adjust parameter: 1 (forward-adjusted), 0 (unadjusted) |
Unadjusted |
Recommendation: Always use forward-adjusted (qfq) prices for strategy backtesting. Unadjusted prices will show artificial gaps at split and dividend dates, distorting return calculations and technical indicators.
Missing Data Handling
AkShare is most susceptible to gaps because it depends on third-party sources. If a data provider goes offline or changes its API, AkShare functions return empty DataFrames without raising an error. Production code should validate row counts and check for date discontinuities:
def validate_ohlcv_continuity(df: pd.DataFrame, expected_freq: str = "1D") -> None:
"""Check for missing trading days in an OHLCV DataFrame."""
if df.empty:
raise ValueError("DataFrame is empty — data fetch failed silently")
# Parse timestamps assuming Unix milliseconds
df = df.copy()
df["date"] = pd.to_datetime(df["open_time"], unit="ms").dt.date
df = df.sort_values("date").reset_index(drop=True)
# Generate expected date range
full_range = pd.bdate_range(start=df["date"].min(), end=df["date"].max())
missing = set(full_range.date) - set(df["date"])
if missing:
print(f"WARNING: {len(missing)} missing trading days detected: {sorted(missing)[:10]}")
else:
print("Date continuity check: PASSED")
Practical Decision Framework
The table below summarizes the decision criteria for selecting a data source based on your development stage and strategy requirements.
| Scenario | Recommended starting point | Rationale |
|---|---|---|
| Learning and prototyping | AkShare (free) | Zero cost; sufficient for validating strategy logic with EOD data |
| Intraday strategy (low-frequency) | Tushare Pro | 1-min and 5-min bars at reasonable cost; delayed but usable for non-HFT strategies |
| Real-time monitoring and live alerts | TickDB | WebSocket subscription is the only option; paid tier required |
| Cross-cycle backtesting (daily) | TickDB or Tushare Pro | Both provide 10+ years of daily OHLCV; TickDB has cleaner data |
| Order book microstructure | TickDB | The depth channel is the only viable option among these three providers |
| Budget constraint (¥0) | AkShare | Free, but with latency and reliability trade-offs |
| Institutional-grade accuracy | TickDB (Professional) | Paid infrastructure with SLA, rate limit guarantees, and cleaner data pipelines |
The Pragmatic Path for Individual Developers
A common pattern among successful individual quant developers is a staged approach:
- Stage 1 (Prototyping): Use AkShare or Tushare free tier to validate strategy logic with daily data.
- Stage 2 (Backtesting): Migrate to TickDB for cleaner historical data with consistent formatting and no points exhaustion.
- Stage 3 (Live deployment): Subscribe to TickDB's paid tier for real-time WebSocket access.
This staged approach avoids premature financial commitment while ensuring that strategy logic is built on data quality that scales to live trading.
Limitations and Honest Disclaimers
No single data provider is optimal for all use cases. The following limitations should inform your selection:
- A-share Level-2 order queue data is not available via any consumer API. Regulatory constraints prevent redistribution of raw order queue data. Any provider claiming to offer Level-2 queue data for A-shares is either redistributing illegally or repackaging delayed data.
- AkShare's reliability is community-dependent. The library has no SLA. Upstream source changes are handled on a best-effort basis by contributors.
- Tushare's points system creates operational unpredictability. Batch backtests may fail mid-run due to point exhaustion, requiring either point purchase or overnight waits.
- TickDB's free tier is intentionally limited. It is suitable for evaluation but not for sustained development or live trading.
- This comparison reflects API behavior as of the article date. Providers update their platforms regularly. Verify current capabilities against each provider's live documentation before making architectural decisions.
Conclusion
The choice between Tushare, AkShare, and TickDB is not a binary verdict. It is a cost-quality-latency tradeoff that depends on your strategy's requirements, your development stage, and your budget.
For individual developers, the most common failure mode is not choosing the wrong provider—it is building on free data that lacks the quality or timeliness required by the strategy, then discovering the flaw only after months of backtesting.
The pragmatic approach is to start with the minimum viable data quality for your current stage, validate your strategy logic, and upgrade to higher-quality data only when the strategy's edge justifies the cost. A strategy that works on AkShare's delayed data will either work better or fail faster on real-time data—either outcome is valuable information.
Next Steps
If you are evaluating data sources for an A-share strategy, visit the respective documentation portals: AkShare on GitHub, Tushare Pro, and TickDB's API documentation. Run the code examples in this article against your own environment to measure actual latency and data quality.
If you need real-time A-share data with WebSocket access, sign up at tickdb.ai for a free API key—no credit card required. The free tier provides 100 requests per day and is sufficient for evaluating the API's response structure and latency.
If you are building a backtesting pipeline and need clean, aligned historical OHLCV, consider TickDB's historical kline endpoint. It provides 10+ years of daily and intraday bars for A-shares with consistent timestamp formatting and forward-adjustment support.
If you use AI coding assistants, search for and install the tickdb-market-data SKILL in your AI tool's marketplace to get context-aware API code generation for market data queries.
This article does not constitute investment advice. Markets involve risk; past performance does not guarantee future results. All API capabilities, pricing, and latency figures reflect documented behavior as of the article date and are subject to change.