1. 引言
在量化投资与数据分析中,获取准确的行情数据是第一步。Baostock 是一个免费、无需注册的 Python 证券数据接口库,覆盖股票、指数、ETF 等历史数据,非常适合个人投资者和研究者使用。本文将带你从零开始,用 Baostock 拉取沪深300ETF 的日线数据,并完成简单的可视化。
2. 环境准备
2.1 安装 Baostock
在上一篇文章中有详细讲解。七天量化回测入门(一)Windows 64 位系统下安装 Conda 虚拟环境完整教程
2.2 导入依赖
进入虚拟环境quant_env。
importbaostockasbsimportpandasaspdimportmatplotlib.pyplotasplt3. 登录与获取数据
3.1 登录 Baostock
# 登录 Baostocklg=bs.login()print('login respond error_code:'+lg.error_code)print('login respond error_msg:'+lg.error_msg)3.2 拉取沪深300ETF 日线数据
沪深300ETF 的证券代码为sh.510300。以下代码拉取 2026 年 1 月 1 日至 2026 年 9 月 30 日的日线数据:
# 获取沪深300ETF 日线数据rs=bs.query_history_k_data_plus("sh.510300","date,code,open,high,low,close,volume,amount",start_date='2026-01-01',end_date='2026-09-30',frequency="d",adjustflag="2"# 前复权)print('query respond error_code:'+rs.error_code)print('query respond error_msg:'+rs.error_msg)# 将结果转为 DataFramedata_list=[]while(rs.error_code=='0')&rs.next():data_list.append(rs.get_row_data())df=pd.DataFrame(data_list,columns=rs.fields)print(df.head())3.3 数据清洗
Baostock 返回的数据中,缺失值以空字符串表示,需要转换为 NaN 并处理:
# 将空字符串转为 NaN,并转换数据类型df=df.replace('',pd.NA)df['date']=pd.to_datetime(df['date'])df['close']=pd.to_numeric(df['close'])df['volume']=pd.to_numeric(df['volume'])# 按日期排序df=df.sort_values('date').reset_index(drop=True)print(df.tail())4. 数据可视化
拉取数据后,我们可以绘制收盘价走势图:
# 设置中文字体 (Windows常用'SimHei'黑体, macOS常用'Arial Unicode MS'或'PingFang HK')plt.rcParams['font.sans-serif']=['SimHei']# 解决负号'-'显示为方块的问题plt.rcParams['axes.unicode_minus']=Falseplt.figure(figsize=(12,6))plt.plot(df['date'],df['close'],label='沪深300ETF 收盘价',color='steelblue')plt.title('沪深300ETF 日线收盘价(2026年)')plt.xlabel('日期')plt.ylabel('收盘价(元)')plt.legend()plt.grid(True)plt.show()5. 登出
使用完毕后,记得登出以释放连接:
bs.logout()6. 完整示例代码
将以上步骤整合,得到完整可运行的脚本:
importbaostockasbsimportpandasaspdimportmatplotlib.pyplotasplt# 登录print(">>>1.准备登录",flush=True)lg=bs.login()print(f">>>2.登录返回:{lg.error_code}{lg.error_msg}",flush=True)# 拉取数据print(">>>3.开始查询",flush=True)rs=bs.query_history_k_data_plus("sz.002471","date,code,open,high,low,close,volume,amount",start_date='2026-01-01',end_date='2026-09-30',frequency="d",adjustflag="2")print(">>>4.查询返回",flush=True)# 转 DataFramedata_list=[]while(rs.error_code=='0')&rs.next():data_list.append(rs.get_row_data())print(f">>>5.拿到{len(data_list)}",flush=True)df=pd.DataFrame(data_list,columns=rs.fields)# 清洗# 将空字符串转为 NaN,并转换数据类型df=df.replace('',pd.NA)df['date']=pd.to_datetime(df['date'])df['close']=pd.to_numeric(df['close'])df['volume']=pd.to_numeric(df['volume'])# 按日期排序df=df.sort_values('date').reset_index(drop=True)print(df.tail())# 绘图# 设置中文字体 (Windows常用'SimHei'黑体, macOS常用'Arial Unicode MS'或'PingFang HK')plt.rcParams['font.sans-serif']=['SimHei']# 解决负号'-'显示为方块的问题plt.rcParams['axes.unicode_minus']=Falseplt.figure(figsize=(12,6))plt.plot(df['date'],df['close'],label='沪深300ETF 收盘价',color='steelblue')plt.title('沪深300ETF 日线收盘价(2026年)')plt.xlabel('日期')plt.ylabel('收盘价(元)')plt.legend()plt.grid(True)plt.show()# 登出bs.logout()7. 输出结果
8. 常见问题
8.1 数据为空怎么办?
- 检查证券代码是否正确,沪深300ETF 为
sh.510300。 - 确认起止日期是否在交易日范围内。
- 检查
adjustflag参数:1后复权、2前复权、3不复权。
8.2 如何获取实时行情?
Baostock 主要提供历史数据,实时行情建议使用其他接口(如 Tushare Pro 或券商 API)。
9. 总结
本文演示了使用 Baostock 拉取沪深300ETF 日线数据的完整流程,包括登录、查询、清洗和可视化。Baostock 免费且无需注册,是入门量化分析的理想选择。你可以在此基础上扩展均线计算、收益率分析等更多功能。