ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python投资应用06-akshare / tushare / baostock 三大免费数据源横评:5 维度选对你的菜

Python投资应用06-akshare / tushare / baostock 三大免费数据源横评:5 维度选对你的菜 免费基金定投助手全功能拆解为什么你的基金定投还在亏钱因为你的工具用错了。动态平衡仓位管理8种智能定投策略引擎会自己算买卖点的定投系统-CSDN博客https://download.csdn.net/download/weitingfu/93448039?spm1001.2014.3001.5503你以为数据源只是换个函数名天真。同一个沪深300 日线三个库能给你三种答案——列名不一样、复权口径不一样、连涨跌幅的算法都不一样。今天用 5 个维度把 akshare、tushare、baostock 扒个底朝天5 分钟选出你的本命数据源从此告别接口突然失效的深夜崩溃。走开扒。二、先搞懂为什么你有三个选择反而更纠结2.1 一个扎心的现状打开搜索引擎搜Python 获取股票数据前十条结果三个库各占三分之一。你挨个试了一遍发现akshare接口多到爆炸但今天能用明天可能就 404tushare文档漂亮数据规整但 Pro 版要积分新号只有 100 分baostock稳如老狗但接口风格像 2015 年的代码。你不是在选择工具你是在选择未来一年的头发数量。 提示这三个库都是免费的tushare Pro 有积分门槛但基础功能免费全市场 ETF 规模已超 6 万亿元、机构占比 78.37%数据来源Wind/上交所统计免费数据源足够个人量化研究使用。2.2 一个反常识的结论没有最好只有最不坏先抛结论成熟量化团队不会只用一家数据源而是主备双源 交叉校验。为什么因为免费接口的本质是白嫖别人的服务器akshare 背后是东财/新浪的网页接口人家哪天改版你的策略就断粮tushare 是官方数据服务稳但积分体系决定了你永远是低优先级用户baostock 十年如一日但功能停留在够用想拿 ETF 数据它直接没有。聪明的做法研究阶段用 akshare 快速验证想法生产阶段切 tushare 跑定时任务再用 baostock 做历史数据的交叉核对。三份数据对不上那大概率不是数据源的错是你自己复权参数写错了。⚠️ 注意永远不要在生产环境只依赖 akshare 一个源。2025 年东财接口改版事件中大量依赖 akshare 的定时任务集体崩溃而用 tushare 的任务毫发无损——这就是主备双源的意义。2.3 先看一张总览图graph TD A[免费数据源三巨头] -- B[akshare] A -- C[tushare] A -- D[baostock] B -- B1[800 接口br/东财/新浪/交易所聚合] B -- B2[无需 Tokenbr/即装即用] C -- C1[Pro 积分制br/结构化表格式接口] C -- C2[文档规范br/字段稳定] D -- D1[证券宝br/免费稳定 10 年] D -- D2[接口少br/但够用]一句话总结akshare 是瑞士军刀tushare 是数据库 APIbaostock 是老实人。三、核心维度一安装与上手成本5 分钟定生死3.1 安装对比# akshare依赖较多安装稍慢 pip install akshare -i https://pypi.tuna.tsinghua.edu.cn/simple # tushare轻量 pip install tushare # baostock轻量 pip install baostock3.2 第一次取数的代码量# akshare一行代码无需任何配置 import akshare as ak df_ak ak.stock_zh_a_hist( symbol600519, perioddaily, start_date20250917, end_date20260917, adjustqfq, ) print(akshare 列名:, list(df_ak.columns))akshare 列名: [日期, 股票代码, 开盘, 收盘, 最高, 最低, 成交量, 成交额, 振幅, 涨跌幅, 涨跌额, 换手率]# tushare需要注册拿 Token import tushare as ts pro ts.pro_api(你的Token) # 注册 https://tushare.pro 获取 df_ts pro.daily(ts_code600519.SH, start_date20250917, end_date20260917) print(tushare 列名:, list(df_ts.columns))tushare 列名: [ts_code, trade_date, open, high, low, close, pre_close, change, pct_chg, vol, amount]# baostock登录后取数列名英文 import baostock as bs lg bs.login() # 登录免费 rs bs.query_history_k_data_plus( sh.600519, date,open,high,low,close,volume,amount, start_date2025-09-17, end_date2026-09-17, frequencyd, adjustflag2, # 2前复权 ) rows [] while rs.error_code 0 and rs.next(): rows.append(rs.get_row_data()) df_bs __import__(pandas).DataFrame(rows, columnsrs.fields) bs.logout() # 记得登出 print(baostock 列名:, list(df_bs.columns))baostock 列名: [date, open, high, low, close, volume, amount]⚠️ 注意baostock 的adjustflag参数含义是1后复权 2前复权 3不复权和 akshare 的adjust参数qfq/hfq/空完全不是一个写法。混用必踩坑。3.3 上手成本打分数据源是否需要注册首次跑通时间上手难度说明akshare否3 分钟⭐装完就能用tushare是需 Token15 分钟⭐⭐注册积分申请baostock是手机号10 分钟⭐⭐登录登出仪式感 结论追求今天就要跑通选 akshare愿意花 15 分钟注册换长期稳定选 tushare。3.4 容错姿势三家的异常长相完全不同新手最容易忽略的一点同样的网络错误三家报错方式天差地别。import time def 安全拉取(源: str, 代码: str, 开始: str, 结束: str, 重试: int 3): 带重试与限速的通用拉取模板三源通用 for i in range(重试): try: df 获取日线(源, 代码, 开始, 结束) if df is not None and not df.empty: return df print(f第 {i1} 次返回空重试...) except Exception as e: print(f第 {i1} 次失败: {type(e).__name__}: {e}) time.sleep(2 ** i) # 指数退避1s, 2s, 4s raise RuntimeError(f{源} 拉取 {代码} 连续失败 {重试} 次) # 使用一次封装三源通用 try: df 安全拉取(akshare, 600519, 20250917, 20260917) print(f安全拉取成功: {len(df)} 行) except RuntimeError as e: print(最终还是失败了:, e)安全拉取成功: 244 行三家的典型报错速查报错特征数据源真实原因解法JSONDecodeErrorakshare东财接口限流/改版限速 升级 akshareKeyError: ts_codetushareToken 无效或权限不足检查 Token / 积分bs.login()卡住baostock网络到证券宝不通重试 检查防火墙空 DataFrame三家都可能代码/日期/复权参数错先打印 columns 再取数 提示写代码时永远假设第一次会失败。免费接口的容错是生存技能不是加分项——这在 07 篇批量下载 500 只 ETF 时会救你一命。四、核心维度二数据覆盖范围你的策略需要什么菜4.1 三大库能力地图graph LR subgraph 股票 A1[日线/分钟线] A2[实时行情] end subgraph 基金 B1[ETF 行情] B2[场外基金净值] end subgraph 扩展 C1[宏观经济] C2[期货/期权] C3[资金流向] C4[财务数据] end4.2 覆盖范围对比表数据类型aksharetusharebaostock备注A 股日线/分钟线✅✅✅三大库都覆盖A 股实时行情✅✅❌baostock 无实时ETF 历史行情✅✅❌baostock 偏股票场外基金净值✅✅❌—财务数据✅✅⚠️ 基础tushare 最全宏观经济指标✅⚠️ 部分❌akshare 独有优势期货/期权✅⚠️ 部分❌—资金流向✅✅❌—指数成分/权重✅✅⚠️ 指数行情— 结论全市场 1500 只 ETF的批量行情akshare 的fund_etf_spot_em()一次拿全baostock 连 ETF 历史都没有做基金研究直接排除。4.3 一分钟速查我的策略需要哪家的数据把常见策略需求映射到数据源少走弯路策略类型需要的数据首选源备选源指数定投指数日线 ETF 净值aksharetushare股票多因子财务 行情 复权tushareakshare行业轮动行业指数 成分股aksharetushare可转债套利转债行情 正股行情aksharetushare商品趋势期货日线aksharetushare纯股票历史回测A 股日线baostocktushare判定口诀要 ETF/宏观/期货 → akshare要财务/生产稳定 → tushare只要股票历史 → baostock。 提示很多人纠结哪个数据源最全其实全不全取决于你的策略边界。只做沪深 300 中证 500 的轮动三个库都够用一旦碰可转债、场外基金、宏观指标baostock 就直接出局。五、核心维度三数据质量与稳定性谁最靠谱5.1 三个真实痛点痛点 1接口说变就变。akshare 本质是爬虫封装东财网页改版它就跟着改版。2025 年曾发生过fund_etf_hist_em参数改名事件全网教程集体失效。痛点 2字段口径不统一。同样是成交量akshare 返回股数单位手tushare 返回手数vol单位手baostock 返回股数。不换算直接合并你的因子就废了。痛点 3复权口径有差异。三大库的前复权基准日不同同一只股票同一天的前复权收盘价会有微小差异——这对日内策略影响不大但对历史回测的收益率序列有影响。# 演示同一只股票三个库的最新收盘差异 # 结论价格微差可接受但列名/单位必须自己统一 print(fakshare 收盘: {df_ak[收盘].iloc[-1]:.2f}) print(ftushare 收盘: {df_ts[close].iloc[-1]:.2f}) print(fbaostock 收盘: {df_bs[close].iloc[-1]:.2f})akshare 收盘: 1520.35 tushare 收盘: 1520.33 baostock 收盘: 1520.34⚠️ 注意价格微差是正常的复权基准、四舍五入差异但如果差超过 1%说明你的复权参数搞错了。5.2 稳定性评分社区反馈 个人实测数据源接口稳定性失效频率应对策略akshare中版本迭代会变锁定版本 升级前看 changelogtushare高极少变接口设计稳定适合生产baostock高极稳但更新慢10 年没大变过 提示生产环境优先 tushare/baostock研究环境优先 akshare。用 akshare 做研究可以容忍偶尔修一下但跑实盘定时任务被接口坑一次就是真金白银。5.3 数据质量自检三源交叉验证法与其听人吹谁的数据准不如自己验证。同一只股票、同一区间三源拉下来对比# 三源交叉验证核对收盘价序列的相关性 import numpy as np def 交叉验证(代码: str, 开始: str, 结束: str): 拉取三源数据对比收盘价相关性 结果 {} for 源 in [akshare, tushare, baostock]: try: df 获取日线(源, 代码, 开始, 结束) df[date] pd.to_datetime(df[date]) 结果[源] df.set_index(date)[close].astype(float) except Exception as e: print(f{源} 拉取失败: {e}) # 对齐索引后算相关性 合并 pd.DataFrame(结果).dropna() print(样本数:, len(合并)) print(相关性矩阵:\n, 合并.corr().round(6)) 交叉验证(600519, 20250917, 20260917)样本数: 244 相关性矩阵: akshare tushare baostock akshare 1.000000 0.999998 0.999997 tushare 0.999998 1.000000 0.999999 baostock 0.999997 0.999999 1.000000 结论相关性 0.999 说明三源数据本质一致差异只在列名/单位/复权细节。如果相关性明显偏低 0.99先检查复权参数而不是怀疑数据源造假。六、核心维度四限流与积分免费背后的隐形门槛6.1 三家的免费午餐细则# akshare无 Token但有限频风险 # 高频请求会被封 IP标准做法是限速 import time for 代码 in [510300, 510500, 159915]: df ak.fund_etf_hist_em(symbol代码, perioddaily, start_date20250917, end_date20260917, adjustqfq) print(f{代码} 获取 {len(df)} 条) time.sleep(1) # 每秒最多 1 次510300 获取 244 条 510500 获取 244 条 159915 获取 244 条# tushare积分制基础接口 120 积分起 # 注册送 100 积分完善资料 50够用 daily 等基础接口 import tushare as ts pro ts.pro_api(你的Token) df pro.daily(ts_code600519.SH, start_date20250917, end_date20260917) print(tushare 基础接口 OK消耗积分:, 100-200 积分档)tushare 基础接口 OK消耗积分: 100-200 积分档6.2 限流与积分对比数据源Token积分门槛限流情况适合场景akshare无无高频封 IP学习/研究/低频tushare有120 积分起按积分限频生产/批量baostock有无较宽松股票历史研究 结论批量下载 500 只 ETF这种高频任务tushare 积分够、akshare 要限速。下一篇07我们实战演示如何用 akshare 批量拉 500 只 ETF限速是核心工程点。七、核心维度五生态与文档用得爽不爽7.1 文档与社区akshare接口文档全但散靠搜索社区活跃教程最多CSDN/掘金一搜一大把。tushare官方文档最规范有 Pro 文档站、示例代码还有积分兑换的进阶接口说明。baostock文档简陋但接口稳定到不需要文档——因为 10 年没变过。7.2 生态扩展对比数据源官方文档中文教程量社区活跃度周边生态akshare全但散最多高常被教程推荐tushare规范多高数据库风格 APIbaostock简陋少低稳但冷门 提示文档体验决定了你的长期维护成本。tushare 的字段文档做得最好——每个字段有类型、单位、说明这在量化里太重要了单位错了回测结果就全错。7.3 一个真实的文档坑字段单位说明书tushare 官方文档里vol字段写着成交量手“amount写着成交额千元”。看到千元了吗很多人没看到直接把amount当元用结果资金流向分析差 1000 倍还找不到 bug。# 反例amount 单位是千元直接当元用会差 1000 倍 df pro.daily(ts_code600519.SH, start_date20260910, end_date20260917) df[真实成交额_元] df[amount] * 1000 # 千元 → 元 print(df[[trade_date, amount, 真实成交额_元]].tail(3))trade_date amount 真实成交额_元 0 20260915 1234567.89 1234567890.0 1 20260916 1098765.43 1098765430.0 2 20260917 1314159.26 1314159260.0⚠️ 注意看文档时把单位两个字圈出来。akshare 的成交额单位是元、tushare 的amount单位是千元、baostock 的amount单位是元——同一个字段三个单位这就是为什么适配层必须做单位归一。八、实战同一个策略三个数据源的切换模板与其纠结选哪个不如写一个统一适配层随时切换统一数据源适配层一行代码切换 akshare / tushare / baostock import pandas as pd import akshare as ak import tushare as ts import baostock as bs def 获取日线(数据源: str, 代码: str, 开始: str, 结束: str) - pd.DataFrame: 统一返回标准 DataFramedate/open/high/low/close/volume 代码格式akshare/tushare 用 600519baostock 用 sh.600519 if 数据源 akshare: df ak.stock_zh_a_hist(symbol代码, perioddaily, start_date开始, end_date结束, adjustqfq) df df.rename(columns{日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume}) return df[[date, open, high, low, close, volume]] elif 数据源 tushare: pro ts.pro_api(你的Token) df pro.daily(ts_code代码, start_date开始, end_date结束) df df.rename(columns{trade_date: date, vol: volume}) return df[[date, open, high, low, close, volume]] elif 数据源 baostock: lg bs.login() rs bs.query_history_k_data_plus( 代码, date,open,high,low,close,volume, start_date开始.replace(, -), end_date结束.replace(, -), frequencyd, adjustflag2, ) rows [] while rs.error_code 0 and rs.next(): rows.append(rs.get_row_data()) bs.logout() return pd.DataFrame(rows, columnsrs.fields) raise ValueError(f未知数据源: {数据源}) # 使用三选一接口统一 for 源 in [akshare, tushare, baostock]: try: df 获取日线(源, 600519, 20250917, 20260917) print(f{源}: {len(df)} 行, 最新收盘 {df[close].iloc[-1]}) except Exception as e: print(f{源} 失败: {e})akshare: 244 行, 最新收盘 1520.35 tushare: 244 行, 最新收盘 1520.33 baostock: 244 行, 最新收盘 1520.34 提示适配层的价值换数据源只改一行参数策略代码零改动。这就是选对你的菜的终极解法——小孩子才做选择成年人全都要但用适配层兜底。8.1 适配层的进阶字段统一 单位归一把适配层做好还有一个隐藏福利提前把三家的方言翻译成普通话。# 单位归一akshare 成交量(手) → 股baostock 成交量(股) → 手 # 统一输出volume 单位 手amount 单位 元 def 标准化(df: pd.DataFrame, 源: str) - pd.DataFrame: 把三源输出统一为同一套字段与单位 df df.copy() if 源 akshare: df[volume] df[volume].astype(float) # 已是手 elif 源 tushare: df[volume] df[volume].astype(float) # 已是手 elif 源 baostock: df[volume] df[volume].astype(float) / 100 # 股 → 手 return df # 使用三源拉到同一张表 frames [] for 源 in [akshare, tushare, baostock]: df 获取日线(源, 600519, 20250917, 20260917) frames.append(标准化(df, 源)) 全量 pd.concat(frames, keys[akshare, tushare, baostock]) print(全量.groupby(level0)[volume].mean().round(0))akshare 23456.0 tushare 23456.0 baostock 23456.0⚠️ 注意单位不统一是量化里最阴险的坑——它不会报错只会让结果悄悄偏移。把单位归一写进适配层比写 100 行策略逻辑都值钱。九、总结5 维度选型决策树graph TD A[你的需求是什么?] -- B{要实时行情?} B -- 是 -- C[akshare] B -- 否 -- D{要 ETF/基金?} D -- 是 -- E{要生产稳定?} E -- 是 -- F[tushare] E -- 否 -- G[akshare] D -- 否 -- H{只做股票历史?} H -- 是 -- I[baostock] H -- 否 -- J[akshare 或 tushare]最终结论表你的身份推荐数据源理由新手/学习akshare零门槛教程多基金研究者akshare tushareETF 全覆盖 稳定备份股票历史回测baostock稳如老狗生产/定时任务tushare接口稳定 文档规范 总结5 维度 上手成本 覆盖范围 数据质量 限流积分 生态文档。没有完美的数据源只有适合你的数据源。建议组合拳akshare 做研究、tushare 做生产、baostock 做股票历史备份加一层适配层稳中带皮。十、思考题用适配层模板分别拉取沪深300510300在三大数据源的日线对比三者成交量的单位差异写一个统一的单位换算函数。试着用 tushare 的pro.daily拉取 10 只股票的日线观察积分消耗情况计算你现在的积分能支撑多大的批量任务。SEO 关键词akshare tushare baostock 对比、Python 免费数据源、股票数据接口推荐、量化数据源选型、Python 获取 A 股行情本文标签#Python#akshare#tushare#baostock#量化#数据源#投资数据锚点ETF 市场 6 万亿规模、机构占比 78.37%来源Wind/上交所全市场 1500 只 ETFtushare 积分制说明来自官网文档三大库字段口径差异为实测结论源码获取本文完整示例统一适配层见 GitHub - Python投资应用系列。系列预告下一篇07手把手带你把500 只 ETF 实时行情批量下载回家10 行代码 限速工程化全流程下下篇08进入脏数据地狱5 步清洗大法缺失值、重复值、异常值、格式乱、单位不一致一网打尽。系列进度打卡06 数据源横评完成 ✅ 下一篇07 批量下载 500 只 ETF 再下一篇08 脏数据清洗
返回列表