Essential Data Sources for A-Share Investors: Comparing Three Options — Which Is Best for Real-Time Quotes and Backtesting?
TickDB Research ·
Essential Data Sources for A-Share Investors: Comparing Three Options — Which Is Best for Real-Time Quotes and Backtesting?

Building a watchlist dashboard and backtesting a multi-year strategy both require "stock data," yet the actual problems they solve are quite different.
A watchlist cares about when the latest price arrives and whether it can recover after a connection drop. Backtesting cares about whether historical data is complete, whether adjustment methods are consistent, and what information was actually available at the time. Comparing only "whether it has real-time quotes" or "whether it can download K-lines" can easily lead to selecting an interface that runs examples well but doesn't suit your actual task.
This article compares three access solutions: AKShare, Tushare Pro, and TickDB. The comparison scope is limited to A-share quotes and price-strategy backtesting. These are not the same type of product: AKShare is a data interface library, while Tushare Pro and TickDB provide data services. The "three major" here refers only to the three options selected for this comparison, not to market share or industry rankings.
Here's the guidance to start with: for learning data collection and validating small-scale prototypes, begin with AKShare; if your focus is bulk historical data ingestion and backtesting, prioritize evaluating Tushare Pro; if you clearly need WebSocket continuous quote streaming, focus on validating TickDB. These are trial-connect suggestions based on interface type — final selection still requires data coverage and operational testing.
1. Break Down "Real-Time" to Make Fair Comparisons
"Being able to query a price right now" and "continuously receiving price changes" correspond to different data consumption patterns.
Snapshot queries are initiated by the client, and the server returns the current state. When timing refreshes are needed, the program schedules the next request. Continuous push means that after establishing a connection and subscribing, the server sends messages incrementally, and the client is responsible for processing messages, monitoring the connection, and recovering subscriptions.
There's a third type of data that causes confusion: K-lines that are still forming. The highest price and trading volume queried during the morning only describe the state before the query time, not the final result for the day.
Therefore, real-time selection should ask "how do updates reach the application," while backtesting selection should ask "was this record already determined when the strategy made its decision." REST or WebSocket only describes the access method and cannot directly prove quote latency, completeness, or trade executability.

Figure 1: Real-time observation and historical backtesting require different data processing paths. This diagram is a recommended design illustration, not the system architecture of any particular vendor.
2. Three Solutions — Where Each Is Best Suited to Start
AKShare: Best for Getting Your Collection and Analysis Pipeline Running First
Using the Eastmoney interface as an example, stock_zh_a_spot_em retrieves snapshot quotes for all A-shares (Shanghai, Shenzhen, and Beijing), while stock_zh_a_hist provides daily historical quotes with adjustment options. When minute-level data is needed, verify the interface scope separately: the 1-minute data from stock_zh_a_hist_min_em only covers the most recent 5 trading days and does not include adjustments. This is a limitation of this specific interface and should not be extrapolated to AKShare's overall historical depth. AKShare Stock Interface Documentation
For beginner projects, I recommend first completing a closed loop of "read, save, plot, rerun" with a small number of stocks. What's truly worth validating is: whether the program can still run the next day, whether you can locate issues after interface changes, and whether already-saved data remains usable.
When using a library as your data entry point, also preserve the specific upstream source and interface name. Two DataFrames returned by the same library may not share the same units, time meaning, or update cadence.
Tushare Pro: Best for Building a Research Database Around Well-Defined Data Interfaces
Tushare's daily provides unadjusted daily bars; the official documentation states these are loaded after market close on trading days and no records are provided during suspension periods. adj_factor provides adjustment factors, and the two can be saved separately, making it easy to verify the adjustment process during research. Daily Bar Documentation, Adjustment Factor Documentation
If your task involves multi-year minute-level backtesting, stk_mins deserves priority verification: the documentation lists 1, 5, 15, 30, and 60-minute periods, noting that over 10 years of historical minute data can be provided, but requires separate permission. This description doesn't mean every stock has a complete ten-year record; listing date, target time range, and actual returned coverage still need to be verified individually. Historical Minute Documentation
Similarly, don't oversimplify Tushare as "only having after-hours data." rt_k already provides real-time daily bars with the day's latest status, though it also requires separate permission. Whether it suits your intraday watchlist depends on the actual update and calling conditions of this interface. Real-Time Daily Bar Documentation
This entry point suits splitting research needs into well-defined data tables and arranging incremental updates. Before selecting, list the required interfaces and permissions to avoid discovering after getting daily bars that minute-level or other supporting data requires separate activation.
TickDB: When You Need Continuous Push, Focus on Subscription and Recovery Verification
TickDB's A-share full-market quote documentation clearly provides WebSocket subscription: snapshots are sent in batches first, then updates to quotes are pushed. This capability requires full A-share or enterprise license permissions and requires successful negotiation of permessage-deflate compression during handshake — you cannot infer "can subscribe to the full market" simply from "can connect to WebSocket." A-Share Full-Market Quote Documentation
On the history side, K-line queries support A-shares with no adjustment, forward adjustment, and backward adjustment. However, the documentation also warns: the last bar may still be forming; the free version cannot query by specified start/end times. Therefore, being able to return recent K-lines doesn't mean it already meets the requirements for backtesting by specified interval. K-Line Query Documentation
For real-time applications, the value of the push entry lies in message-driven updates. The engineering cost is also concrete: after reconnection, subscriptions must be restored, snapshots must correctly overwrite local state, and during recovery the application must know that data hasn't caught up yet. Official best practices also require subscription restoration after reconnection. WebSocket Connection Management
3. Write Selection Results as "Conditions," Not a Ranked Scorecard
| Your Primary Task | Recommended Solution to Verify First | Conditions for Adoption |
|---|---|---|
| Learning collection, small-stock prototype | AKShare | Selected interfaces cover target range; rerun and exception handling are acceptable |
| Historical daily-bar research, multi-year minute backtesting | Tushare Pro | Corresponding permissions in place; historical coverage, units, and adjustment method acceptance confirmed |
| Continuous quote dashboard, message-driven alerts | TickDB | Subscription permissions match scale; update timeliness and disconnection recovery meet requirements |
This table provides starting points for trial connections. It doesn't mean AKShare can't do backtesting, Tushare can't do real-time, or TickDB is inherently better for historical data. This comparison did not conduct same-condition latency testing across all three vendors, nor does it have sufficient evidence to rank them as "fastest," "most stable," or "lowest cost."
Cost should also be calculated based on total investment to complete the task: required interface permissions, call and subscription capacity, initial historical backfill, and ongoing maintenance all affect the final choice. Comparing only a single package price easily misses the most time-consuming parts.
4. Before Backtesting, Block Three Common Data Errors First
1. Same Field Names Don't Mean Same Units
A practical example is the interface differences within Tushare itself: daily reports volume in lots (hand) and turnover in thousands of yuan; the corresponding units for rt_k and stk_mins are shares and yuan. Adaptation rules must be tied to specific interfaces, not just written as a generic "Tushare conversion function." Daily Bar Fields, Real-Time Daily Bar Fields, Minute Bar Fields
Below is simulated data demonstrating turnover normalization — no online services are called:
from decimal import Decimal
def amount_yuan(value, unit):
scales = {"元": Decimal("1"), "千元": Decimal("1000")}
if unit not in scales:
raise ValueError("成交额单位未确认")
amount = Decimal(str(value))
if not amount.is_finite() or amount < 0:
raise ValueError("成交额必须是有限非负数")
return amount * scales[unit]
# Two simulated records describing the same turnover, not actual vendor results.
assert amount_yuan("1234.5", "千元") == amount_yuan("1234500", "元")
If you directly concatenate the two raw amount fields, the same trade size will differ by a factor of 1,000. Turnover filters and liquidity thresholds in your strategy will be altered by unit errors. Price precision, volume, and timezone should also follow the same explicit rules before database ingestion.
2. Adjusted Prices on Charts Should Not Be Used Directly as Trade Prices
Adjusted series help handle price discontinuities caused by corporate actions, but the adjustment method, calculation basis, and retrieval time must be preserved. TickDB documentation explicitly warns that adjusted history may change with corporate actions or data updates and provides a separate adjustment factor interface. K-Line Notes, Adjustment Factor Notes
A more reproducible organization approach is: save raw prices, preserve factor versions, then generate the adjusted series needed for research. Prices used for indicator calculation must be distinguished from prices and events used for simulating order execution, handling cash dividends, and tracking position changes.
Whether future information exists also needs to be checked based on how the strategy uses this data — it cannot be determined solely by "used forward adjustment." In particular, for absolute price thresholds, historical financial screening, and index constituent screening, confirm that the information used was already available at that time.
3. "Having a K-Line" Doesn't Mean "This K-Line Is Usable"
Taking the example of querying a 10:00–10:05 K-line at 10:03, it will continue to change. If you use the highest price or closing price that was determined later to decide on a trade at 10:03, the backtest has peeked into the future.
Don't simply "delete the last row each time" when handling this. After market close, the last row may already be complete. Determine whether a record can be used for current decisions based on market trading hours, whether the timestamp corresponds to the start or end of the period, and the data source's update status.
It's recommended to preserve data source, original code, market time, receipt time, period, unit, and adjustment method for each database record. Distinguish between missing values and confirmed zeros; when a day is missing, first differentiate between market holiday, suspension, not yet listed, and collection failure, then decide whether to fill.

Figure 2: First unify conventions and save versions, then proceed to strategy replay. This diagram illustrates data preparation methods and does not represent backtesting returns or vendor quality conclusions.
5. Turn "Suitability" into Verifiable Conclusions with a Small Sample
Before formal integration, apply the same acceptance task to all three candidate solutions: select one actively traded stock, one with suspension periods, and one covering ex-rights and ex-dividend events. For quote projects, add intraday continuous observation; for backtesting projects, cover normal trading days and periods before and after events.
Acceptance isn't just about "request successful" — also keep records that can be reviewed later:
- Historical Coverage: List the difference between expected trading dates and actual dates, and explain gaps; don't substitute date verification with "row counts are the same between two datasets."
- Field Consistency: First unify units, adjustments, and time ranges, then compare price and volume/turnover differences; differences between different conventions cannot be directly judged as data errors.
- Real-Time Status: Record both source time and local receipt time simultaneously. Only when source time semantics are identical and machine clocks are synchronized does the difference between them have comparative meaning; otherwise, only the update interval observed locally can be reported.
- Recovery Capability: Actively disconnect or pause collection, observe whether the application-required state can be filled after recovery; restoring only the latest snapshot doesn't mean lost tick events have been recovered.
- Repeatability: Rerun using saved raw data, conversion rules, and version information to confirm differences can be traced to input or processing steps.
If you currently just want to run one research idea, start with the easiest entry point whose scope meets requirements. If you're building long-term backtesting, prioritize historical coverage and reproducibility. If you're building a continuously running intraday system, prioritize update semantics and failure recovery.
Real-time quotes answer "what's happening now," while backtesting data must also answer "what was knowable at the time." All three solutions should be verified against these two questions. First determine the task, then verify specific interfaces — this is usually more reliable than first finding an "omniscient data source."
Official Documentation Reference
Interface functionality, data units, historical scope, and permission conditions mentioned in this article reference the following publicly available official documentation; documentation corresponding to each explanation is listed below.
- AKShare Stock Data Documentation: Real-Time and Historical Quote Interfaces. Covers query scope and adjustment limitations for Eastmoney quote snapshots, historical daily bars, and 1-minute data.
- Tushare Pro Daily and Adjustment Documentation: A-Share Daily Quotes, Adjustment Factors. Covers daily bar ingestion, suspension records, volume and turnover units, and how to obtain adjustment factors.
- Tushare Pro Minute and Real-Time Documentation: Stock Historical Minute Quotes, A-Share Real-Time Daily Bars. Covers minute periods, historical coverage descriptions, separate permissions, and real-time field units.
- TickDB Quote Subscription Documentation: A-Share Full-Market Quotes, WebSocket Connection Management. Covers snapshots and incremental push, full-market permissions, compression negotiation, and reconnection subscriptions.
- TickDB K-Line and Adjustment Documentation: K-Line Queries, Adjustment Factors. Covers query conditions, adjustment methods, last-bar status, and adjustment factor calculation descriptions.