BaoStock
Overview
BaoStock is a free, open-source securities data platform for China A-shares. It provides historical quotes, financial indicators, macroeconomic data, and industry classification through a unified Python API, returning pandas DataFrames.
Key advantages: Free, stable, long history (since 1990), no rate limits or credits required.
Quick Start
Installation
pip install baostock
Basic Usage Pattern
import baostock as bs
import pandas as pd
# 1. Login (required)
lg = bs.login()
# 2. Query data
rs = bs.query_history_k_data_plus(
"sh.600000",
"date,code,open,high,low,close,volume,amount",
start_date="2024-01-01",
end_date="2024-12-31",
frequency="d",
adjustflag="3",
)
# 3. Collect results (pandas 2.0+ compatible)
rows = []
while (rs.error_code == "0") and rs.next():
rows.append(rs.get_row_data())
df = pd.DataFrame(rows, columns=rs.fields)
# 4. Logout
bs.logout()
Stock Code Format
BaoStock uses exchange.code format (note the dot separator):
| Exchange | Prefix | Example |
|---|---|---|
| Shanghai (SSE) | sh. | sh.600000 (SPDB) |
| Shenzhen (SZSE) | sz. | sz.000001 (Ping An Bank) |
Parameter Conventions
- Date:
YYYY-MM-DD(e.g.,2024-12-31) - Stock code:
sh.600000,sz.000001 - Return format: Iterate via
rs.next()+rs.get_row_data(), assemble into DataFrame - All return values are strings: Must manually
pd.to_numeric()for numeric columns
Complete API Reference
I. Market Data
1. Historical K-line: query_history_k_data_plus()
The most important API — supports daily/weekly/monthly/minute bars with adjustment.
rs = bs.query_history_k_data_plus(
code="sh.600000", # Stock code
fields="date,code,...", # Return fields (comma-separated)
start_date="2024-01-01",# Start date, default 2015-01-01
end_date="2024-12-31", # End date, default latest trading day
frequency="d", # Frequency
adjustflag="3", # Adjustment type
)
frequency values:
| Value | Frequency | Notes |
|---|---|---|
"d" | Daily | Default |
"w" | Weekly | |
"m" | Monthly | |
"5" | 5-minute | Index does not support minute bars |
"15" | 15-minute | |
"30" | 30-minute | |
"60" | 60-minute |
adjustflag values:
| Value | Meaning | Method |
|---|---|---|
"3" | Unadjusted | Default |
"1" | Backward adjusted | Percentage change method |
"2" | Forward adjusted | Percentage change method |
Note: BaoStock uses the "percentage change adjustment method", which differs from other platforms (e.g., Tongdaxin).
Daily/Weekly/Monthly fields:
| Field | Description | Type |
|---|---|---|
date | Trading date | str |
code | Stock code | str |
open | Open price | str→float |
high | High price | str→float |
low | Low price | str→float |
close | Close price | str→float |
preclose | Previous close | str→float |
volume | Volume (shares) | str→float |
amount | Amount (CNY) | str→float |
adjustflag | Adjustment flag | str |
turn | Turnover rate (%) | str→float, empty string when suspended |
tradestatus | Trading status | str, "1"=normal, "0"=suspended |
pctChg | Price change (%) | str→float |
peTTM | PE ratio (TTM) | str→float |
pbMRQ | PB ratio (MRQ) | str→float |
psTTM | PS ratio (TTM) | str→float |
pcfNcfTTM | PCF ratio (TTM) | str→float |
isST | Is ST stock | str, "1"=yes, "0"=no |
Minute bar fields:
| Field | Description |
|---|---|
date | Date |
time | Time (format YYYYMMDDHHmmssSSS) |
code | Stock code |
open | Open price |
high | High price |
low | Low price |
close | Close price |
volume | Volume |
amount | Amount |
adjustflag | Adjustment flag |
Minute bars do not include index data or valuation metrics (peTTM, etc.).
2. Index K-line
Uses the same query_history_k_data_plus() API with index codes:
| Index | Code |
|---|---|
| SSE Composite | sh.000001 |
| SZSE Component | sz.399001 |
| CSI 300 | sh.000300 |
| CSI 500 | sh.000905 |
| ChiNext Index | sz.399006 |
Index does not support minute bars, only daily/weekly/monthly.
3. All Securities on Date: query_all_stock()
rs = bs.query_all_stock(day="2024-12-31")
# Returns: code, tradeStatus columns
II. Basic Information
4. Stock Basic Info: query_stock_basic()
rs = bs.query_stock_basic(code="sh.600000") # Single stock
rs = bs.query_stock_basic() # All stocks
Returns: code, code_name, ipoDate, outDate, type (1=stock, 2=index, 3=other, 4=convertible bond, 5=ETF), status (1=listed, 0=delisted)
5. Industry Classification: query_stock_industry()
rs = bs.query_stock_industry(date="2024-12-31") # Specific date
rs = bs.query_stock_industry() # Latest
Returns: updateDate, code, code_name, industry, industryClassification
Uses CSRC industry classification standard.
6. SSE 50 Constituents: query_sz50_stocks()
rs = bs.query_sz50_stocks(date="2024-12-31")
Returns: updateDate, code, code_name
7. CSI 300 Constituents: query_hs300_stocks()
rs = bs.query_hs300_stocks(date="2024-12-31")
8. CSI 500 Constituents: query_zz500_stocks()
rs = bs.query_zz500_stocks(date="2024-12-31")
III. Dividends & Adjustment
9. Dividend Information: query_dividend_data()
rs = bs.query_dividend_data(
code="sh.600000",
year="2024",
yearType="report", # "report"=announcement year, "operate"=ex-dividend year
)
Returns:
| Field | Description |
|---|---|
dividPreNoticeDate | Pre-notice date |
dividAgmPumDate | AGM announcement date |
dividPlanAnnounceDate | Plan announcement date |
dividPlanDate | Implementation announcement date |
dividRegistDate | Record date |
dividOperateDate | Ex-dividend date |
dividPayDate | Payment date |
dividStockMarketDate | Stock listing date |
dividCashPsBeforeTax | Cash dividend per share (before tax) |
dividCashPsAfterTax | Cash dividend per share (after tax) |
dividStocksPs | Stock dividend per share |
dividCashStock | Dividend & transfer info |
dividReserveToStockPs | Reserve to stock per share |
10. Adjustment Factor: query_adjust_factor()
rs = bs.query_adjust_factor(
code="sh.600000",
start_date="2015-01-01",
end_date="2024-12-31",
)
Returns: code, dividOperateDate, foreAdjustFactor, backAdjustFactor, adjustFactor
IV. Quarterly Financial Data
All quarterly APIs share the same parameters:
rs = bs.query_xxx_data(code="sh.600000", year=2024, quarter=2)
code: Stock codeyear: Fiscal year (int)quarter: Quarter (1/2/3/4)
11. Profitability: query_profit_data()
Returns:
| Field | Description |
|---|---|
code | Stock code |
pubDate | Publication date |
statDate | Statistics end date |
roeAvg | ROE (average, %) |
npMargin | Net profit margin (%) |
gpMargin | Gross profit margin (%) |
netProfit | Net profit (CNY) |
epsTTM | Earnings per share |
MBRevenue | Main business revenue (CNY) |
totalShare | Total shares |
liqaShare | Tradable shares |
12. Operating Efficiency: query_operation_data()
Returns: NRTurnRatio (receivables turnover), NRTurnDays, INVTurnRatio (inventory turnover), INVTurnDays, CATurnRatio (current asset turnover), AssetTurnRatio (total asset turnover)
13. Growth: query_growth_data()
Returns: YOYEquity (equity YoY), YOYAsset (asset YoY), YOYNI (net income YoY), YOYEPSBasic (basic EPS YoY), YOYPNI (net income attributable to pare