Best Data Sources for Systematic Trading Research: yfinance vs AkShare vs TuShare
yfinance delivers free global equity data without authentication, while AkShare provides comprehensive Chinese macro and fundamental data via web scraping, and TuShare offers authenticated API access to high-quality Chinese tick data with stricter rate limits.
The awesome-systematic-trading repository catalogs these three libraries in its Data Sources section as the primary Python connectors for quantitative research. Each serves distinct geographic markets and data granularity requirements, making the choice dependent on whether your systematic strategy targets global equities or focuses on Chinese mainland securities.
Market Coverage and Data Granularity
Understanding the primary jurisdiction of each library determines its fit for your backtesting pipeline.
yfinance sources data from Yahoo! Finance, providing daily OHLCV and intraday minute-level bars for global equities, ETFs, options, and futures. It includes corporate actions like dividends and splits, though coverage for non-U.S. fundamentals remains limited. According to the repository's README.md (lines 218‑221), this is the recommended starting point for international strategies.
AkShare specializes in Chinese mainland markets, offering daily and tick-level data for stocks, bonds, and futures alongside extensive macro-economic indicators (GDP, CPI, etc.). It scrapes public websites and APIs, delivering richer fundamental data (profit margins, balance sheets) than global alternatives for A-share securities.
TuShare focuses exclusively on Chinese equities through a formal JSON API, providing daily, weekly, and monthly bars plus concept-stock mappings and industry classifications. While its macro coverage is narrower than AkShare, it delivers cleaner tick-level historical data when accessed with a valid token.
Authentication Requirements and Rate Limiting
Your infrastructure setup varies significantly between these sources.
yfinance requires no API key, functioning as a thin Python wrapper over pandas_datareader. It is rate-limited by Yahoo!'s servers but imposes no hard caps on requests per minute.
AkShare operates without authentication for most endpoints, though optional tokens unlock premium services. Its web-scraping architecture means it can slow down when source websites change HTML structures or throttle heavy traffic.
TuShare mandates a free API token obtained from tushare.pro for all calls. The service enforces approximately 100 requests per minute and occasionally exhibits data gaps during Chinese market holidays, requiring robust error handling in production workflows.
Implementation: Fetching Unified Price Data
All three libraries return pandas.DataFrame objects compatible with the repository's strategy scripts in static/strategies/*.py. Below are standardized fetchers that align schemas across providers.
Global Equities with yfinance
Use yf.download() for U.S. and international tickers, selecting adjusted close prices to handle splits and dividends.
import yfinance as yf
def fetch_yfinance(ticker: str, start: str, end: str):
"""Fetch daily OHLCV from Yahoo Finance."""
df = yf.download(ticker, start=start, end=end, progress=False)
df = df[['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume']]
df.columns = [c.lower().replace(' ', '_') for c in df.columns]
df['source'] = 'yfinance'
return df
# Example: Apple Inc.
df_aapl = fetch_yfinance("AAPL", "2022-01-01", "2022-12-31")
Chinese Markets with AkShare
Leverage ak.stock_zh_a_hist() for A-share data, specifying adjust="hfq" for fully-adjusted historical prices.
import akshare as ak
import pandas as pd
def fetch_akshare(ticker: str, start: str, end: str):
"""Fetch Chinese equity data via AkShare."""
df = ak.stock_zh_a_hist(
symbol=ticker,
period="daily",
start_date=start,
end_date=end,
adjust="hfq"
)
df = df.rename(columns={
"date": "date",
"open": "open",
"high": "high",
"low": "low",
"close": "close",
"volume": "volume"
})[['date', 'open', 'high', 'low', 'close', 'volume']]
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
df['source'] = 'akshare'
return df
# Example: Kweichow Moutai (600519.SH)
df_moutai = fetch_akshare("600519", "2022-01-01", "2022-12-31")
Chinese Markets with TuShare
Access TuShare Pro via pro.daily(), converting date formats from YYYYMMDD strings to datetime indexes.
import tushare as ts
import os
import pandas as pd
def fetch_tushare(ticker: str, start: str, end: str):
"""Fetch Chinese equity data via TuShare Pro API."""
token = os.getenv("TUSHARE_TOKEN")
ts.set_token(token)
pro = ts.pro_api()
df = pro.daily(
ts_code=ticker,
start_date=start.replace('-', ''),
end_date=end.replace('-', '')
)
df = df.rename(columns={
"trade_date": "date",
"open": "open",
"high": "high",
"low": "low",
"close": "close",
"vol": "volume"
})[['date', 'open', 'high', 'low', 'close', 'volume']]
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
df['source'] = 'tushare'
return df
# Example: Requires TUSHARE_TOKEN environment variable
df_moutai_ts = fetch_tushare("600519.SH", "2022-01-01", "2022-12-31")
Unified Data Interface
Create a provider-agnostic fetcher to swap sources without modifying strategy logic, as implemented in the repository's example scripts like static/strategies/asset-growth-effect.py.
def fetch_price(ticker, start, end, provider="yfinance"):
"""Unified fetcher supporting multiple data sources."""
if provider == "yfinance":
return fetch_yfinance(ticker, start, end)
if provider == "akshare":
return fetch_akshare(ticker, start, end)
if provider == "tushare":
return fetch_tushare(ticker, start, end)
raise ValueError(f"Unsupported provider: {provider}")
Integration with Backtesting Workflows
When integrating these sources into the awesome-systematic-trading ecosystem, observe three architectural constraints from the source code analysis.
Caching Layer: Implement local caching using joblib or pickle after initial downloads. While yfinance provides built-in caching via its download wrapper, AkShare and TuShare require explicit wrappers to check local storage before issuing HTTP requests, preventing redundant calls during strategy iteration.
Timezone Alignment: Combine global equities (yfinance, typically UTC or ET) with Chinese data (AkShare/TuShare, Asia/Shanghai) by normalizing all timestamps to UTC. Explicitly handle divergent holiday calendars when merging datasets for cross-regional arbitrage strategies.
Error Resilience: Wrap all fetchers in try-except blocks catching requests.exceptions and urllib.error exceptions. Strategy scripts should fall back to the most recent cached snapshot when network failures occur, ensuring reproducibility of backtests as recommended in the repository's QuantConnect-style implementations.
Summary
- yfinance serves as the optimal choice for global equity research requiring no authentication, offering daily and intraday OHLCV data through
yf.download(). - AkShare provides the most comprehensive Chinese fundamental and macro data via web scraping, accessed through
ak.stock_zh_a_hist()without API keys. - TuShare delivers authenticated, high-quality Chinese tick data via
pro.daily()when you require cleaner institutional-grade feeds and can manage token-based rate limits. - All three libraries output
pandas.DataFrameobjects compatible with the repository's strategy scripts instatic/strategies/, enabling plug-and-play data source substitution. - Implement caching and timezone normalization when combining yfinance's global coverage with AkShare or TuShare's Chinese market data.
Frequently Asked Questions
Which data source is best for backtesting U.S. equity strategies?
yfinance is the recommended choice for U.S. strategies because it provides free, unauthenticated access to daily and minute-level OHLCV data, dividends, and splits through Yahoo! Finance. Its yf.download() function returns DataFrames that integrate directly with the repository's strategy templates, though you should implement caching to avoid hitting rate limits during extensive backtests.
Do I need an API token to access Chinese stock data?
Only TuShare requires a mandatory API token from tushare.pro; AkShare operates without authentication for most endpoints. However, TuShare's token-based system enforces stricter data quality controls and provides approximately 100 requests per minute, whereas AkShare relies on web scraping that may break if source websites update their HTML structure.
Can I use these data sources for live trading or just research?
These libraries are primarily designed for research and backtesting. While yfinance, AkShare, and TuShare can technically feed live trading systems, they lack the low-latency execution guarantees required for high-frequency strategies. According to the awesome-systematic-trading repository's architecture, use these connectors for strategy development in static/strategies/*.py, then migrate to broker-specific APIs (like QuantConnect's live trading interface) for production deployment.
How do I handle different column schemas when switching between yfinance and Chinese data providers?
Standardize column names immediately after fetching. yfinance returns capitalized column names (Open, High, Low, Close, Adj Close) while AkShare and TuShare use lowercase or Chinese-specific fields. The unified fetcher pattern shown in the code examples above demonstrates renaming columns to a consistent schema (open, high, low, close, volume) and adding a source column for provenance tracking, ensuring your backtesting logic remains agnostic to the data provider.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →