
Python量化实战:用AKShare搭建自己的日线数据库,手把手完整教程
文 | 程飞 | 2026年5月7日
量化研究的第一件事,不是选策略,不是回测,是数据。没有干净、完整、可靠的历史数据,一切都是空中楼阁。我见过太多人,策略写得非常漂亮,回测曲线很漂亮,一实盘就亏成狗——根因往往不是策略本身,而是数据质量不行。这篇文章,我把手把手教你怎么用AKShare搭建一套完整的A股日线数据库,包括数据获取、存储、清洗、更新,全套跑通。
01 环境准备:Anaconda + Jupyter Lab
第一步是搭建Python环境。不建议用系统自带的Python,建议用Anaconda管理环境,这样可以避免不同项目之间的库冲突。具体步骤:去Anaconda官网下载安装包,安装的时候把"Add Anaconda to PATH"这个选项勾选上(虽然官方不建议,但这样方便后续命令行调用)。安装完成后,在开始菜单找到Anaconda Prompt,打开之后创建一个新的虚拟环境:conda create -n quant python=3.9。然后激活环境:conda activate quant。接下来安装Jupyter Lab:pip install jupyterlab。最后在命令行输入jupyter lab,就可以在浏览器里打开Jupyter的编程界面了。
为什么要用Jupyter Lab而不是普通的Python脚本?因为量化研究需要反复修改参数、反复查看中间结果,Jupyter的单元格执行模式比"写完脚本再运行"效率高得多。你可以先跑一行代码看结果,再决定下一步怎么做,非常适合策略研究的迭代过程。
依赖库的安装顺序:先装akshare(数据获取),再装pandas(数据处理),再装sqlalchemy(数据库ORM),再装pymysql或者sqlite3(数据库连接)。具体命令是:pip install akshare pandas sqlalchemy pymysql。一个一个装,遇到报错就把错误信息复制到搜索引擎里查,大多数问题Stack Overflow上都有答案。
02 数据库设计:为什么要用数据库而不是Excel
很多人存股票数据用Excel,这是新手最容易踩的坑。Excel的问题在于:第一,数据量大了之后卡死,A 股四千多只股票,五六年的日线数据,Excel根本打不开;第二,不好做增量更新,全量重新下载浪费时间;第三,不好和其他工具配合,数据库可以用SQL查询,Python可以随时读,Excel只能手动操作。
我推荐用SQLite作为本地数据库,它是最轻量的SQL数据库,不需要安装数据库服务,直接就是一个文件,用Python的sqlite3库就能直接操作,数据量在几十G以内完全够用,而且迁移到MySQL或者PostgreSQL也非常简单——改一个连接字符串就行。如果你有一定基础,也可以直接用MySQL,Windows下装一个MySQL Installer就能一键安装。
数据库的表结构怎么设计?日线数据一张表就够了,字段包括:股票代码、交易日期、开盘价、收盘价、最高价、最低价、成交量、成交额、涨跌幅度、换手率。注意字段类型:股票代码用 VARCHAR(10),交易日期用 DATE,开盘价等价格数据用 DECIMAL(10,3)(保留三位小数,足够A股精度),成交量用 BIGINT。建表SQL是这样的:CREATE TABLE IF NOT EXISTS daily_bar (code VARCHAR(10), trade_date DATE, open DECIMAL(10,3), close DECIMAL(10,3), high DECIMAL(10,3), low DECIMAL(10,3), volume BIGINT, amount DECIMAL(20,3), PRIMARY KEY(code, trade_date));
03 数据获取:用AKShare拉全市场日线数据
AKShare是A股量化最好用的免费数据源,没有之一。它对Python新手极度友好,接口设计简洁,文档详细,社区活跃。获取单只股票日线数据的代码只有三行:import akshare as ak,df = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="20240101", end_date="20260507", adjust="qfq"),然后df就是包含日期、开盘、收盘、最高、最低、成交量、成交额、振幅、涨跌幅、涨跌额、换手率等字段的DataFrame,可以直接用pandas处理。
获取全市场股票列表用akshare.stock_info_a_code_name_df(),返回一个包含所有A股股票代码和名称的DataFrame,遍历这个列表,逐个调用stock_zh_a_hist就能拉出全市场数据。但注意,不要一股脑地高频调用API,AKShare的数据来源是公开网站的爬虫接口,请求太快会被临时封IP,每次调用之间加0.5到1秒的sleep,平均一小时能拉完全市场数据。
增量更新逻辑:如果你的数据库里已经有了历史数据,每天收盘后只需要更新最近一个月的交易日数据,而不是全量重新下载。具体实现:查询数据库里最近一条记录的日期,然后从当天开始往前推一个工作日,用这个日期作为增量更新的起始日期。代码逻辑是:last_date = pd.read_sql("SELECT MAX(trade_date) FROM daily_bar", conn).iloc[0,0],然后用last_date的下一天作为start_date去拉新数据。
04 数据清洗:剔除停牌日期、处理复权
原始数据往往不能直接用,需要做清洗。第一个要处理的是停牌日期:AKShare的日线数据包含停牌日(成交量为0的日期),在计算收益率、均线等指标时,这些日期会产生错误的信号。比如一只股票停牌了一个月,你计算月收益率的时候如果包含了停牌日,就会出现0%收益率的错误数据。正确的做法是在清洗阶段直接剔除成交量为0的日期。
第二个要处理的是复权方式。AKShare接口里的adjust参数控制复权方式:"qfq"是前复权,"hfq"是后复权,""是不复权。我强烈建议用前复权(qfq),因为A股有除权除息,前复权把历史价格按照除权因子调整到最新价格水平,使得K线图上看起来是连续的价格,方便计算收益率。后复权和不复权在A股几乎没有实际用途。
第三个要处理的是数据对齐:不同股票的数据日期不完全一致,有些股票在某一天停牌了,有些股票在某个时间段刚上市没有数据。做策略的时候,需要把所有股票对齐到同一个交易日索引,这个操作叫"时间序列对齐"。用pandas的merge_asof函数可以实现,具体是:按交易日排序之后,用pd.merge_asof(left, right, by='trade_date', direction='backward'),这样能确保每只股票只取其历史上存在的最近一个交易日的价格。
05 数据验证:建立完整性检查机制
数据清洗完之后,必须做验证,而不是直接开始跑策略。我见过太多"看起来正常"的数据库,实际上存在各种隐蔽的错误,导致策略结果完全不可信。数据验证应该包括以下几个方面:
第一,缺失值检查。用pandas的isnull().sum()检查每个字段的缺失值数量,特别关注收盘价和成交量,缺失值超过总数据的1%就要排查原因。第二,价格连续性检查:日内最高价应该大于等于开盘价和收盘价,最低价应该小于等于开盘价和收盘价,这个条件如果不满足,说明数据有错误。第三,涨跌幅检查:用当天收盘价和前一天收盘价计算的涨跌幅,应该和你获取的涨跌幅字段一致,如果不一致说明复权处理有问题。第四,交易日完整性检查:用已知的所有交易日列表,检查每只股票是否有完整的交易日记录,连续缺失超过5个交易日要排查是否股票被停牌处理错了。
验证完了之后,用一份简单的双均线策略做一次全市场回测,验证整个数据管道是否正常工作。如果双均线策略在全市场的表现符合预期(在牛市能赚钱,在熊市能控制回撤),说明数据管道基本没问题。如果表现异常离谱(比如胜率超过70%),那大概率是数据还有问题没发现。
06 定时更新:让数据库每天自动刷新
数据库搭建好了,最重要的就是持续更新。很多人的数据库能建,但每天手动更新太麻烦,两周之后就废弃了。我建议用Windows的任务计划程序(Task Scheduler)设置每天下午五点半自动运行数据更新脚本,这样每天收盘后数据会自动更新,你只需要确保电脑开着就行。
更新脚本的逻辑很简单:第一步连接数据库,第二步查询最新的数据日期,第三步从该日期往前推两个工作日作为起始日期,第四步循环获取全市场日线数据,第五步用INSERT OR REPLACE INTO语句写入数据库(这样自动处理增量更新,已有的记录会覆盖,不会有重复)。脚本写好之后,在Anaconda Prompt里用python your_script.py命令测试运行,确保没有报错,再配置到任务计划里。
数据库是量化系统的根,数据质量决定策略上限。把数据管道跑通,你就完成了量化系统80%的基础工作,剩下的才是策略研发。