🔗 开源项目地址:https://github.com/zer0quant/zer0share

欢迎 Star / Issue / PR,后续模块会陆续合并进去。


这几个月,OpenClaw 小龙虾很火,我也看到不少人用它去网上抓行情数据。

但抓别人家的行情数据,其实有几个很现实的问题:

  • 不稳定:别人家的服务不是专门给你做数据底座的,接口随时可能变,抓取逻辑也可能随时失效;
  • 容易打扰别人的服务器:你抓得越频繁,对方压力越大;
  • 可持续性差:很多这类方案前期看起来能用,后面往往就是不断修修补补,代码改了一遍又一遍;token 还会在不知不觉中被消耗掉。

所以,想真正把数据这件事做好,最稳妥的方式还是自己搭一套本地数据系统

这篇文章,我就以日线行情模块为例,讲讲我是怎么用 Tushare + Claude Code,手搓一套开箱即用的小型数据同步系统的。


一、先别急着写代码,先把数据源想清楚

搭建数据系统,第一件事永远不是写代码,而是先想清楚数据源

这次我选的是 Tushare。

原因很简单:对个人开发者来说,它的性价比非常高。捐赠 200 元,拿到 2000 积分,就能拥有一套相对稳定、质量也不低的日线行情数据源。拿它来搭一个个人版的小型本地数据库,其实非常合适。

如果只是做个人研究、做因子、做回测、做一些轻量级策略验证,Tushare 已经够用了。


二、我的目标,不是"拉到数据",而是"搭成系统"

很多人做数据,目标其实只是"把数据拉下来"。

但我这次想做的不是一次性脚本,而是一套能长期用的本地数据同步系统

也就是说,它至少要满足这几个要求:

  1. 数据源清晰
  2. 存储结构清晰
  3. 支持全量同步
  4. 支持增量更新
  5. 有统一的交互方式
  6. 后续方便继续扩展别的数据模块
  7. 最好还能让 AI 比较容易接管

所以从一开始,我就不是按"写几个脚本"去做的,而是按"搭一个最小可用的数据底座"去设计的。


三、开发方式上,我选择让 AI 参与,但不放弃工程流程

这次我主要用的是 Claude Code,并且装了 superpowers skill

这个 skill 对我来说最大的帮助,不是"写代码更快",而是让整个开发流程更规范了。它比较适合做这样一类事情:

先头脑风暴,收敛需求 → 再把需求写清楚,形成架构文档 → 然后继续往下拆任务 → 最后一步步实现

也就是说,AI 在这里不是单纯的代码生成器,而更像一个参与工程流程的助手。

这点我觉得很重要。因为如果你只是把一句模糊需求直接扔给 AI,让它开始生成,最后大概率会得到一堆"看起来能跑,但不好维护"的东西。

但如果你先把系统边界、模块分工、存储结构、交互方式都想清楚,再让 AI 进入实现阶段,产出的质量会高很多。


四、先做整体架构,再做存储分区

确定好数据源后,我先做了整体架构设计。

整体架构

核心思路并不复杂,本质上就是把整个系统拆成几个部分:

  • 数据源层:负责和 Tushare API 交互
  • 同步层:负责全量拉取、增量更新、调度执行
  • 存储层:负责本地数据落盘
  • 交互层:负责让人和系统沟通
  • 文档与测试层:保证系统后续可维护、可验证

这个技术栈我最后选得比较克制,整体追求的是简洁和通用,不是堆很多花里胡哨的东西。因为对个人数据系统来说,最重要的不是"架构看起来高级",而是"稳定、透明、好维护"。

接着我又设计了存储的分区结构。

存储分区结构

这一步也很关键,因为如果你一开始不把数据怎么存想清楚,后面同步逻辑、查询逻辑、更新逻辑全都会乱掉。

我的理解是:一个小型本地数据系统,不需要一上来就搞得特别重,但一定要先把目录结构、表结构或者分区逻辑设计清楚。否则后面每加一个模块,系统都会越来越难维护。


五、交互方式上,我最后选择了 CLI

在交互方式上,我最后选的是 CLI。

CLI 命令示例

原因有两个。

第一,CLI 足够轻。 对于这种本地同步系统来说,很多操作本来就是命令式的,比如初始化、全量同步、增量更新、查看状态、跑测试。CLI 反而是最自然的形态。

第二,后续更方便 AI 接管。 因为命令行本身就是标准化的输入输出接口。你把能力做成命令,后面不管是 Claude Code、Codex,还是别的 agent,要接入都更容易。

也就是说,我一开始就在往"未来能被 AI 自动调度"的方向设计,而不是只考虑手动点几下能不能跑。


六、第一版功能做完后,我发现真正的坑来了

整体功能初版做完之后,我 review 了一遍代码。

从表面上看,这套代码已经比较完整了,结构也比较简洁,测试样例也有。但仔细往下看,我很快发现还是有坑

于是我换了另外一个工具 Codex 来继续填坑。

然后就发现了一个非常关键的问题:系统里没有保留所有基础信息

stock_basic 字段缺失

再往下看,我意识到,最核心的缺失其实是——交易日历

交易日历驱动同步

这个问题看起来小,但其实非常关键。

因为不管是历史数据全量同步,还是后续增量更新,本质上都不应该"盲目拉数据",而应该从交易日历开始

换句话说,交易日历不是一个可有可无的附属功能,而应该是整个数据同步系统的起点

这是这次开发里我觉得最有价值的一个修正点。

很多人做行情同步,会直接按股票代码、按日期区间、按接口一把拉。但如果没有交易日历这个基础模块,很多事情都会变得不够严谨:

  • 你不知道哪些天本来就不开盘
  • 你不知道增量更新应该从哪个有效交易日开始
  • 你也很难把同步逻辑真正标准化

所以后面我又把交易日历功能补上了。


七、补上交易日历之后,系统才真正像一个"系统"

把交易日历补进去之后,这套系统的逻辑就顺了很多。

因为这时候,全量同步和增量更新终于有了统一起点:

先更新交易日历 → 再基于交易日历判断需要同步哪些交易日 → 然后再去同步对应的日线行情数据

这样整个链路就从"按接口拉数据"变成了"按交易日驱动的数据同步系统"。

这个变化其实非常重要。因为一旦同步逻辑是围绕交易日历组织的,后续你再扩展别的数据模块,比如复权因子、财务数据、指数数据、ETF 数据,整体的思路都会更统一。


八、后面做的事情,其实都是工程化细节的完善

核心链路打通之后,我后面做的工作主要有三块。

第一块,是继续补稳定性。 我根据日线行情文档,把一些细节再完善了一遍,让同步过程更稳一些。

稳定性建议配置

第二块,是补文档。 这个步骤我觉得很多人容易忽视,但实际上非常重要。因为代码只是系统的一部分,文档才是后续自己复盘、扩展、交给 AI 继续接管时的上下文基础

SYNC_GUIDE 文档结构


九、最后测试下来,结果还不错

最后实际测试跑了一下,交易日历和日线模块都能正常完成。

先看交易日历同步——8 个交易所的日历几秒钟就拉完了:

trade_cal 同步结果

接着是 stock_basic 基础信息:

basic 同步结果

最后是日线行情。全量同步大概需要 1 个小时左右,跑完之后用 status 命令一看,三张表的更新时间都对得上:

daily_kline 同步与 status

对于一个个人本地数据系统来说,这个速度我是能接受的。因为它至少说明了三件事:

  1. 这套链路已经能跑通
  2. 这不是一个只停留在设计图上的系统
  3. 它已经具备了继续扩展的基础

到这里,这个 Tushare 数据同步系统,算是完成了第一个可用版本。


十、这次最大的收获,不是代码,而是系统思维

回过头看,这次开发我最大的收获,其实不只是"写出了一套同步代码"。

更重要的是,我把自己对"小型本地数据系统"的一些想法,真正落地了一遍。

比如:

  • 数据系统一定要先从数据源和边界开始想
  • 不要一上来就写脚本,要先做架构和存储设计
  • CLI 是一种很适合本地数据系统的交互形态
  • AI 可以参与开发,但前提是工程流程不能丢
  • 交易日历应该是整个行情同步系统的起点,而不是附属模块

这些东西,单独看都不复杂。但只有你真正把系统从 0 到 1 搭起来,踩过坑,再补回来,才会对这些点有真正的体感。


十一、写在最后

这篇文章讲的,其实只是整个数据系统的第一步。

目前我完成的是:

  • 基于 Tushare 的本地数据同步系统雏形
  • 包含交易日历和日线行情模块
  • 支持从工程化流程出发进行设计、实现、测试和补坑

下一步,我会继续整理一下前后复权数据的合成逻辑。因为只有把复权这部分也补齐,这套数据底座才算更适合后面的因子研究、回测和策略开发。

下篇继续讲,怎么合成前复权和后复权数据。


如果这篇文章对你有帮助

  • ⭐ Star 一下项目:https://github.com/zer0quant/zer0share
  • 关注公众号,下篇更新第一时间通知
  • 有想法、有 bug、有功能建议,欢迎在 GitHub 提 Issue 或直接 PR

我们下篇见。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐