ARTICLE DETAIL

资讯详情

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

DolphinDB集成Tushare:一站式搞定金融数据获取与入库

DolphinDB集成Tushare:一站式搞定金融数据获取与入库 1. 整体设计与模块价值拆解做量化或者金融数据分析的人十有八九都经历过同一个痛苦的阶段数据从哪来市面上能拿到中国A股、港股、期货、基金、指数数据的渠道不少但真正用起来总有点隔靴搔痒。要么数据更新不及时要么字段不全要么收费贵得离谱要么需要自己写一堆Python脚本去抓取、清洗、入库还要自己处理限流、重试、断点续传这些杂事。数据本身没拿到多少时间全耗在管道工程上了。Tushare这个数据接口在国内金融数据圈子里算是老牌且口碑不错的方案。它覆盖了股票、基金、期货、期权、宏观、公告、资金流向等大量基本面和高频数据而且是标准化的API接口数据结构干净、字段定义清晰很多量化团队和个人研究者都在用它做底层数据源。DolphinDB这次在Marketplace上线的Tushare金融数据模块解决的正是数据获取入库这条最繁琐的链路。简单说就是不用你再单独跑Python脚本去调Tushare接口然后把数据一条条格式化、写进数据库了。直接在DolphinDB里调用这个模块一条命令就能把Tushare的数据拉下来自动完成限流处理、字段类型映射、增量更新策略直接落到DolphinDB的分布式表里后续直接做因子计算、回测、实时监控都顺手多了。这个模块适合谁我觉得分三类人。第一类是在DolphinDB里做策略研究和回测的量化研究员以前要手动维护数据管道现在数据源直接接进库省掉大量脏活累活。第二类是用DolphinDB做金融数据分析、风控监控的工程师需要定期刷新全市场数据模块的增量更新机制可以直接用。第三类是刚入门量化、还在折腾数据源的个人投资者与其从零搭建数据抓取框架不如直接站在这个现成模块的肩上先把精力放在策略逻辑上。它的核心价值不在于多个接口这么简单而在于把数据链路中的脏活、累活、坑活全部用工程化的方式处理掉了。2. 核心功能与数据范围解析2.1 数据覆盖面从行情到基本面一站式补齐这个模块说白了就是把Tushare的Pro版接口能力搬到了DolphinDB里数据覆盖范围相当广。我按自己的使用经验大概梳理了一下主要分这几大类数据类别具体内容典型场景股票行情日线行情、周线/月线、分钟线、复权因子K线绘制、技术指标计算、回测数据准备基础信息股票列表、交易日历、上市公司基本信息、高管信息股票池筛选、交易日对齐、基本面初筛财务数据资产负债表、利润表、现金流量表、财务指标、业绩预告基本面选股、财务因子构建、暴雷排查资金与交易每日资金流向、龙虎榜、融资融券、大宗交易资金面分析、事件驱动策略指数与板块指数基本信息、指数成分股、申万行业分类、概念板块风格分析、行业轮动、基准对比基金与期货基金净值、基金持仓、期货合约信息、期货日线资产配置、跨品种分析、基差研究另类与宏观宏观经济数据、利率、汇率、新闻舆情宏观因子建模、事件驱动预警这些数据在Tushare里都分别对应不同的Pro接口比如daily、income、balancesheet、cashflow、moneyflow等等。DolphinDB这个模块等于把这一堆接口做了统一封装你不需要记住每个接口的参数和返回格式模块内部已经把它们映射成了DolphinDB的表结构。2.2 模块设计逻辑为什么说它懂量化开发者的痛点我专门去翻了这个模块的文档它的设计思路确实是按实战场景来做的而不是简单套一层API转发。有几个点值得展开说说。第一是内置了自动限流策略。用Tushare的人都清楚pro接口有积分限制不同积分配额的调用频率上限完全不一样。如果你写脚本拉数据时没做限流控制高频调用很快就触发抱歉您每分钟最多访问该接口X次这种错误前功尽弃。这个模块在内部已经把限流重试逻辑处理好了你只需要专注业务数据不用操心API频率的问题。第二是字段类型自动映射。Tushare接口返回的往往是字符串和数值混杂的JSON直接入库容易产生类型不一致的问题。比如日期字段有时候是20240101这种int格式有时候又带-分隔符。模块在落地时会自动把日期转成DolphinDB的DATE类型把数值字段转成合适的DOUBLE或INT避免了你手动做数据清洗的功夫。第三是增量更新机制。金融数据的特点是历史数据量大、新增数据量小每次做全量拉取既浪费配额又浪费时间。模块默认支持按交易日增量更新你可以设置定时任务每天收盘后自动拉取当天的新增数据无缝追加到分布式表里。2.3 与DolphinDB原生态的整合程度这个模块不是孤立的数据导入工具它和DolphinDB的查询引擎、计算引擎是打通的。数据落库之后你可以直接用SQL语法做复杂查询也可以配合DolphinDB内置的tsma、mavg、winsorize等函数做面板数据处理甚至直接把数据喂给DolphinDB的机器学习框架。举个例子以前你可能需要把Tushare数据先导到本地CSV再用Python的pandas读进来算因子最后再导回DolphinDB做回测。现在这一步直接省了数据从接口到可计算状态中间没有任何搬运动作。这一点在策略迭代频繁的场景下尤其重要省的不只是时间还有来回搬运过程中容易踩的坑。3. 实操过程从安装到数据入库全流程3.1 环境准备与模块安装先说一下环境。DolphinDB的Marketplace是插件化的分发机制模块安装有几种方式最简单的当然是在Marketplace界面里直接搜索Tushare点击安装。但我实际操作中发现有些内网环境的服务器访问不了外部的插件仓库这时候就需要手动下载插件包解压到DolphinDB的plugins目录下然后通过loadPlugin命令加载。我当时是在一台CentOS服务器上操作的DolphinDB版本是2.00.x。先看一眼插件目录结构# DolphinDB 安装目录下的 server/plugins 目录 plugins/ └── tushare/ ├── tushare.cpp ├── tushare.so └── tushare.txt启动DolphinDB后在控制台执行loadPlugin(tushare);如果看到输出里提示加载成功说明插件与当前DolphinDB版本兼容。这里有个小经验DolphinDB版本升级后旧插件二进制可能失效需要去Marketplace重新拉取对应版本的插件包不要混用。3.2 配置Tushare Token与首次数据拉取要用Tushare接口首先得有一个Tushare的Token。这个Token相当于你的API钥匙在Tushare官网注册并实名认证后个人主页的接口TOKEN页面可以复制到。注意Token要保管好泄漏了别人就能消耗你的API配额。在DolphinDB中模块提供了配置Token的函数通常是tushare::setToken(你的token字符串);配置完之后测试一下连通性。以拉取平安银行的日线行情为例它的股票代码是000001.SZ。看下模块的调用方式// 拉取单只股票的日线数据前复权 dailyData tushare::daily(000001.SZ, startDate2023.01.01, endDate2023.12.31, adjTypeqfq);执行完你会发现返回的dailyData直接是一个DolphinDB表对象字段已经按DolphinDB的标准数据结构组织好了。打印前几行看看select top 10 * from dailyData;正常的话能看到日期、开盘价、收盘价、最高价、最低价、成交量、成交额、涨跌幅等字段日期已经是标准的DATE类型。3.3 全量历史数据入库分布式表设计与二级分区单只股票拿下来很简单但实际使用中我们往往需要全市场五千多只股票的历史日线这就得考虑怎么设计存储表了。金融数据入库DolphinDB最常用的方式就是创建分布式表。分布式表的存储路径类似数据库的表空间分区键通常选TradeDate和SecurityID的组合做二级分区。这样设计的好处是查询某一天全市场数据时只需要扫描那一个日期的分区速度极快查询某只股票的历史序列时也能通过SecurityID快速定位。实操时我一般这样建表login(admin, 123456); dbName dfs://tushareDB; tableName daily; // 如果库不存在先建库 if (!existsDatabase(dbName)) { db database(dbName, VALUE, 2020.01.01..2024.12.31); } // 建表日期按值分区股票代码按哈希分区 schema table( TradeDate : DATE, SecurityID : SYMBOL, Open : DOUBLE, High : DOUBLE, Low : DOUBLE, Close : DOUBLE, Volume : INT, Amount : DOUBLE, ChangePct : DOUBLE ); db database(dbName); if (!existsTable(db, tableName)) { db.createTable(schema, tableName, [TradeDate, SecurityID]); }表建好之后就是全量拉取历史数据了。这里建议不要一次性把几千只股票全拉完Tushare侧有接口限制建议按股票代码分批执行每批之间加一点延迟也可以让模块内部的限流机制自动处理。我当时写了一个循环脚本按行业板块分批拉取拉完一批写一批中途断了也不怕因为后续可以做增量补拉。3.4 增量更新调度每天收盘后自动刷新数据库建好、历史数据填充完成只是第一步真正省心的是增量更新机制。金融数据的日常更新频率不高交易日收盘后跑一次基本就够。DolphinDB的调度任务scheduleJob就能干这个事。举个实际配置的例子。每天的16:30A股收盘后清算基本完成自动拉取当天的全市场日线数据追加到dfs://tushareDB/daily表里def appendDailyData() { login(admin, 123456); // 获取当前日期 today today(); // 调用模块函数拉取当天全市场数据 // 这里的接口是按日期维度拉取 res tushare::daily(datetoday); // 追加到分布式表 loadTable(dfs://tushareDB, daily).append!(res); } // 注册定时任务周一到周五 16:30 执行 scheduleJob(jobIddaily_update, jobDescDaily Tushare Data Update, jobFuncappendDailyData, scheduleTime16:30, startDate2024.01.01, endDate2024.12.31, frequencyD);这里有几个注意点。scheduleJob的frequency参数我习惯用字节形式表示比如D代表每天执行。另外如果某天是节假日非交易日Tushare接口可能返回空表或者只有空数据所以我在appendDailyData函数里加了判断如果res的行数大于0再去执行append!操作避免往表里写空数据。还可以配合DolphinDB的交易日历表在非交易日直接跳过调度任务。3.5 字段对齐与数据质量校验数据入库只是开始最怕的是入库后才发现字段对不齐、数据有空值。这个模块虽然已经做了字段映射但由于Tushare接口更新的原因偶尔会冒出新字段或者字段类型变化所以我在入库后加了一道质量校验的工序。常用的校验手段有几种。第一是查行数。比如某交易日全市场股票数量大约是五千只如果当天拉回来的数据只有一百行那肯定有问题。第二是查空值率重点看Close、Volume这些核心交易字段是否为空dailyTbl loadTable(dfs://tushareDB, daily); select count(*) as totalRows, sum(isNull(Close)) as closeNullCnt, sum(isNull(Volume)) as volumeNullCnt from dailyTbl where TradeDate 2024.01.15;第三是和Tushare网页端或其它数据源做抽样对比。拉任一股票的某日收盘价对比一下是否一致。这种校验习惯一定要养成数据质量问题往往不是拉取时报错而是拉回来是坏的但表面上看着还挺正常。4. 常见问题与排查技巧实录4.1 模块加载失败或版本不兼容我实际遇到过的第一个坑就是插件加载失败。当时DolphinDB从2.00.6升到了2.00.9旧版Tushare插件的.so二进制文件就在新版本上加载不了了报错提示libtushare.so无法解析。这种情况别去折腾旧插件直接去Marketplace拉最新版插件重装。另外如果你的服务器是ARM架构比如鲲鹏、飞腾环境要确认插件包是ARM版本的。DolphinDB的Marketplace插件一般区分了x86和ARM两种构建版本选错了一样加载失败。4.2 Tushare积分与API限流Tushare的积分体系是核心限制。2000积分以上才能调用部分接口120积分可能只能访问基础行情。模块虽然做了限流策略但如果你的Token权限本身不够接口还是会报权限错误。我当时遇到过权限不足的报错排查下来发现是Token绑定的账号还没达到对应接口的积分门槛。这个模块本身解决不了这个问题只能你去Tushare那边通过贡献数据或者付费提高积分。建议先在Tushare官方文档看接口的积分要求再规划拉取策略。还有一点Tushare对单次调用返回的行数也有限制比如daily接口单次最多返回一定数量的记录。如果一次拉全市场某天的数据可能超出行数限制导致返回不全。模块内部一般会自动分页处理但我建议拉大范围数据时尽量按日期逐天拉而不是按时间段批量拉这样即使触发限制影响范围也可控。4.3 日期字段格式不一致Tushare不同接口返回的日期格式偶尔不一样有些是20240101有些是2024-01-01。模块虽然做了统一处理但如果你直接调底层的API函数而不是模块封装好的函数就可能拿到原始格式的字符串日期入库时就容易出现类型不匹配错误。解决办法是入库前统一做一次日期转换。DolphinDB准备了temporalParse和date函数可以灵活处理// 假设原始日期列 dateStr 是 20240101 字符串 convertedDate date(temporalParse(dateStr, yyyyMMdd));建议在写数据管道时把日期清洗放在最前面不管模块内部怎么处理你最终落库的数据类型必须是DATE类型否则后续按日期做分区查询时会出大问题。4.4 数据延迟和缺失Tushare的数据大部分在交易日当晚更新但不同接口的腾挪时间不一样。比如日线行情一般当天晚上八九点就全了但财务数据往往要延迟几天甚至几周。如果你调度任务设置得太早拉到的可能是昨天的数据容易造成好像更新了但实际上是旧数据的错觉。我个人的经验是行情类的定时任务设在当天晚上10点之后财务类数据的定时任务设在每月固定日期批量补拉。同时建议在表里加一个UpdateTime字段记录每次数据落库的时间戳排查数据新鲜度问题时一眼就能发现问题。4.5 中文编码问题Tushare接口返回的基本面数据里有大量中文内容比如公司名称、行业分类、公告标题。如果DolphinDB服务端默认字符集不是UTF-8导入的中文可能变成乱码。我碰到过在Windows服务器上部署DolphinDB时出现这种情况后来在启动配置里明确指定了UTF-8编码问题才消失。排查思路很简单拉一条包含中文的数据直接print看一下乱码就调编码设置。另外DolphinDB的字符串类型需要注意STRING和SYMBOL的区别中文数据建议用STRING类型存储因为SYMBOL类型做序列化时对中文处理有时候会有坑。4.6 常见问题速查表问题现象可能原因解决方案插件加载失败版本不兼容或架构不对重新下载匹配版本的插件包接口返回权限不足Token积分不够提升Tushare积分或换接口数据只有部分返回单次调用行数超限按日期逐天拉取或启用分页日期字段入库报错字符串日期未转DATE类型用temporalParse统一转换中文乱码服务端字符集不是UTF-8调整启动配置指定UTF-8编码定时任务没执行scheduleJob时间设置错误检查scheduleTime和frequency参数5. 扩展应用与实际心得5.1 结合DolphinDB的因子计算与回测数据进库只是万里长征第一步真正体现价值的是后续的计算环节。DolphinDB最强的就是向量化计算和复杂时序函数。数据落库后我可以直接在DolphinDB里写SQL做因子计算不需要来回导数据。举个简单的动量因子例子。以前我在Python里做这件事要先从数据库把数据读出来再用pandas的groupby和rolling计算。现在在DolphinDB里一条SQL就能搞定dailyTbl loadTable(dfs://tushareDB, daily); // 计算每只股票过去20日的收益率动量因子 factorTbl select SecurityID, TradeDate, close / prev(close, 20) - 1 as Mom20 from dailyTbl where TradeDate 2023.01.01 context by SecurityID;这个计算在五千只股票、两百万条数据上执行几乎秒出结果。同时配合DolphinDB内置的回测框架可以直接把因子值转成持仓信号做回测整个链路无比顺畅。5.2 多源数据对账不止Tushare一个数据源虽然Tushare覆盖面很广但我个人在实际生产环境中不会只依赖单一数据源。数据源之间相互校验这个习惯帮我排掉了很多肉眼发现不了的坑。具体做法是再引入另一个数据源比如某些券商的免费接口或者自己手工维护的小样本数据对关键字段做每日对账。比如每天拉完Tushare数据后随机抽十只股票和另一数据源的收盘价做对比。如果差值超过0.1%就触发告警人工排查是哪边数据出了问题。这种对账机制在DolphinDB里也可以用定时任务实现一旦发现异常就发送告警提醒整个数据链路的稳定性会高一个量级。5.3 我对这个模块的几个体会这个模块上线以来我最大的感受是少踩了很多隐形的坑。以前自己写数据管道时要处理拼接URL、解析JSON、处理嵌套结构、对齐时间戳、处理断线重连这些工作非常琐碎而且每换一个数据接口就要重新来一遍。现在模块把这些东西都封装好了我可以把精力放在真正需要动脑的策略研究上。有一点需要提醒大家模块虽好但不要完全当黑盒用。我建议你至少花半天时间读一遍模块的源代码DolphinDB插件的源码在Marketplace上都能看到搞清楚它内部是怎么处理字段映射的、是怎么做分页的。这样后续如果遇到数据异常排查思路会清晰很多。另外初期使用建议先在测试环境跑一遍完整流程安装、配Token、拉一天数据、建表、入库、刷新查询。确认数据没问题后再上生产环境的定时任务。不要一上来就直接上全量历史数据万一字段映射有偏差回头看几千只股票的数据全错了清洗工作量大到你怀疑人生。最后分享一个我常用的组合技巧。Tushare模块负责把数据拉进DolphinDBDolphinDB负责计算因子和回测然后我把回测产生的交易信号通过API推送到自己的模拟盘环境。这一套链路里Tushare模块是地基数据地基打得稳上面的量化研究和交易执行才能少出幺蛾子。地基不稳的话策略逻辑再优秀也可能是建在流沙上的高楼随时可能塌。
返回列表