读取本地通达信(TDX)股票数据,增量同步到 PostgreSQL/MySQL/SQLite
Project description
tdx2db
Import TDX (通达信) local A-share market data into PostgreSQL / MySQL / SQLite.
读取本地通达信股票数据(日线 + 5/15/30/60 分钟线),增量同步到数据库。适合想用 SQL / pandas 做 A 股量化分析、又不想依赖收费行情 API 的人。
定位与同类项目
tdx2db 做一件事:把通达信本地数据变成你自己的 SQL 数据库资产。差异化在管道可靠性:
- 增量幂等、断点自愈:起点按股票、按表分别计算,中断重跑不丢数据不重复;衍生分钟表缺口增量重跑自动补齐
- 状态可观测:
tdx2db status一眼确认每表行数/覆盖/日期范围,"退出码 0 ≠ 数据进去了"有官方验证手段 - 无幸存者偏差:数据来自本地 vipdoc 文件,已退市股票的历史仍在
- AI agent 就绪:
AGENTS.md+ Claude Code skill 提供显式的 agent 使用契约
与同类开源项目的分工(事实性对比,各有侧重):
| 项目 | 数据来源 | 产出形态 | 状态* |
|---|---|---|---|
| tdx2db | 本地 vipdoc 文件 | PostgreSQL / MySQL / SQLite(增量同步) | 活跃 |
| easy_tdx | 通达信协议在线直连 | DataFrame / JSON / REST(含指标、回测) | 活跃 |
| tdx-api | 通达信协议在线直连 | Docker 部署的 REST 实时接口 | 活跃 |
| rustdx | 本地 .day + 东方财富 | CSV / ClickHouse / MongoDB(含复权因子) | 低频维护 |
| mootdx / pytdx | 本地文件 + 在线协议 | DataFrame 读取库 | 已停更 |
* 状态为 2026-07 快照。需要实时行情选在线直连类项目;需要可 SQL 查询、可增量维护的历史数据资产,选 tdx2db。
安装
# Python >= 3.9。默认安装即支持 SQLite(零配置开箱即用)
pip install tdx2db
# 使用 PostgreSQL / MySQL 时安装对应驱动
pip install 'tdx2db[postgres]' # PostgreSQL
pip install 'tdx2db[mysql]' # MySQL
pip install 'tdx2db[all]' # 两者都装
# 国内网络可选用镜像加速:pip install tdx2db -i https://mirrors.aliyun.com/pypi/simple/
PostgreSQL / MySQL 需要先建数据库(表结构会在首次运行时自动创建,数据库本身需要先建好):
createdb tdx_data # PostgreSQL
# mysql -u root -p -e 'CREATE DATABASE tdx_data' # MySQL
# SQLite 无需此步骤
配置(.env)
在运行命令的目录下创建 .env 文件(.env 从当前工作目录读取;也可以直接用环境变量或命令行参数):
# 通达信安装目录。判断标准:该目录下应存在 vipdoc/sz/lday/*.day 文件
# Windows 下装在常见默认路径(C:/D:/E: 盘的 new_tdx / zd_zsone / tdx / new_jyplug)时
# 可以不配置——程序会自动探测;显式配置永远优先
TDX_PATH=C:\new_tdx # Windows
# TDX_PATH=/Volumes/share/new_tdx # macOS(SMB 挂载 Windows 共享)
# TDX_PATH=/mnt/share/new_tdx # Linux(CIFS 挂载)
DB_TYPE=postgresql # postgresql / mysql / sqlite
DB_HOST=localhost
DB_PORT=5432
DB_NAME=tdx_data # sqlite 时为文件名(生成 tdx_data.db)
DB_USER=postgres
DB_PASSWORD=your_password # 密码只从 .env 读取,不提供命令行参数
可选项:DB_BATCH_SIZE(批量写入大小)、CSV_OUTPUT_PATH(CSV 导出目录)、USE_TQDM(进度条开关)。
最小化尝鲜(不写 .env,SQLite 落盘为当前目录 tdx_data.db):
tdx2db --tdx-path /path/to/new_tdx --db-type sqlite --db-name tdx_data sync
首次使用
-
打开通达信 → 选项 → 盘后数据下载 → 下载日线和分钟线数据(TDX 默认只缓存看过的股票,必须先做这一步)
-
同步股票列表:
tdx2db stock-list --db-only
- 一键同步所有行情数据:
tdx2db sync
每日更新
tdx2db sync
程序按股票逐只检测数据库最新日期,只同步新数据。
查看数据状态
tdx2db status # 每表行数 / 覆盖股票数 / 日期范围
tdx2db status --json # 机器可读输出,适合脚本 / LLM agent 消费
只读命令,不需要配置 TDX_PATH。sync 之后跑一下即可确认数据真的入库了(退出码 0 不代表数据写入成功);若衍生分钟表(15/30/60)覆盖股票数少于 5 分钟表,会输出警告及修复命令。
增量同步与唯一约束
增量同步(自动跳过重复数据)依赖 (code, date/datetime) 唯一约束。
新用户:无需任何操作——表结构由程序自动创建,已内建唯一约束。
老用户(v0.2.0 之前建的表没有约束)需执行一次迁移脚本,否则 PostgreSQL 下增量写入会全部失败、MySQL/SQLite 下会静默累积重复数据。不确定的话可先自检:
-- PostgreSQL:有输出说明约束已存在,无需迁移
SELECT conname FROM pg_constraint WHERE conname LIKE 'uq_%';
-- MySQL
SELECT CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = DATABASE() AND CONSTRAINT_NAME LIKE 'uq_%';
迁移脚本:
# PostgreSQL
psql -U your_user -d your_database -f scripts/add_constraints.sql
# MySQL
mysql -u your_user -p your_database < scripts/add_constraints_mysql.sql
脚本会先清理已有重复数据再加约束,执行前请备份。
其他命令
单独同步日线/分钟线
# 日线增量同步(逐股票精确增量)
tdx2db daily --db-only --auto-start --incremental
# 分钟线增量同步
tdx2db minutes --db-only --auto-start --incremental
指定日期范围
tdx2db daily --db-only --start_date 2025-01-01 --end_date 2025-01-31
tdx2db minutes --db-only --start_date 2025-01-01
导出到 CSV
tdx2db daily --csv-only
tdx2db minutes --csv-only
数据表结构
| 表名 | 唯一约束 | 内容 |
|---|---|---|
daily_data |
(code, date) | 日线 OHLCV + 均线 |
minute5_data / minute15_data / minute30_data / minute60_data |
(code, datetime) | 分钟线 OHLCV + 均线(15/30/60 由 5 分钟重采样) |
stock_info |
code | 股票列表:真实名称 + 总股本/流通A股(万股)+ 股本更新日/上市日期 |
block_stock_relation |
(block_type, block_name, code) | 板块-个股关系(行业/概念/指数/地区/风格/特殊),全量快照 |
板块数据:来自通达信本地板块文件(T0002/hq_cache/),随 sync 自动更新,也可单独 tdx2db blocks --db-only。行业为 881 研究行业(一/二/三级各一行);中证500/1000 等跨市场指数成分完整;每次同步为全量替换快照(无历史版本)。老用户需执行一次 scripts/migrate_block_relation.sql(表结构变更,原表从未有写入路径)。
均线列:ma5 / ma10 / ma60 / ma250 为常规窗口,ma13 / ma21 / ma34 / ma55 / ma89 / ma144 / ma233 为斐波那契窗口(服务缠论类分析,不需要可忽略)。上市不足对应窗口天数的行为 NULL。
⚠️ code 格式差异(跨表查询必读):stock_info.code 带市场前缀(sz000001 / sh600000),而 daily_data / minute*_data 的 code 是 6 位纯数字(000001)。跨表 JOIN 需要 RIGHT(stock_info.code, 6) 或等价处理——这是最容易踩的坑。
已知限制:
stock_info.name为真实股票名称(来自通达信本地 infoharbor_ex.code,缺失时回退占位符)- 收录范围:深市
000 / 001 / 002 / 300 / 301,沪市60xxxx / 688xxx;北交所、ETF、指数暂未纳入
FAQ
Q: 报"无法找到股票列表文件"或读到 0 只股票
A: TDX_PATH 指向错误,或通达信还没下载数据。确认该目录下存在 vipdoc/sz/lday/*.day,并先在通达信里执行"盘后数据下载"。
Q: 报 database "tdx_data" does not exist
A: 表结构会自动建,但数据库本身要先创建,见"安装"一节的 createdb。
Q: PostgreSQL 报 no unique or exclusion constraint,或 MySQL 数据越导越多
A: 老库缺唯一约束,见"增量同步与唯一约束"一节的自检和迁移脚本。
Q: 为什么没有北交所 / ETF / 指数数据?
A: 当前 A 股筛选规则只收深市 000/001/002/300/301 和沪市 60/688。北交所(vipdoc/bj/)等扩展欢迎提 PR(见 CONTRIBUTING.md)。
Q: 如何计算换手率?
A: stock_info 存有流通A股 ltag(万股,来自通达信本地 base.dbf,随盘后更新),单位换算后公式恰为:
SELECT d.date, d.volume / s.ltag AS turnover_pct
FROM daily_data d JOIN stock_info s ON RIGHT(s.code, 6) = d.code
WHERE d.code = '000001' ORDER BY d.date DESC LIMIT 20;
注意:股本是当前快照,股本变动点(配股/增发等)之前的历史换手率会失真;精确历史换手率需自行结合 gbbq 股本变迁数据。list_date 上市日期也在 stock_info 中,可用于次新股过滤。老库需执行一次 scripts/migrate_stock_info_capital.sql 后重跑 tdx2db stock-list --db-only。
Q: 数据是否复权? A: 不复权,且默认口径不会改变(设计决策,见 issue #2)。复权请在消费端处理。
开发与贡献
四层管道,单向数据流:
CLI (cli.py) → Reader (reader.py) → Processor (processor.py) → Storage (storage.py)
argparse pytdx 读取本地 校验 + 重采样 + 均线 SQLAlchemy 批量写库
命令分发 + .day/.lc5 文件 (OHLCV 校验, resample, 增量 ON CONFLICT +
同步编排 MA 计算) 表名白名单
git clone https://github.com/xbfighting/tdx2db.git && cd tdx2db
pip install -e '.[all]'
pytest tests/ # 单元测试(不需要真实 TDX 数据和数据库)
从源码运行时 python main.py <子命令> 与 tdx2db <子命令> 等价(老用户习惯保留)。
贡献前请读 CONTRIBUTING.md——特别是"不接受的改动"一节(数据契约)。
使用 AI 辅助开发的贡献者:仓库带 CLAUDE.md,包含架构细节与历史坑(code 格式差异、增量逻辑),能让 AI 产出符合数据契约的 PR。
用 AI agent 查询数据:仓库带 AGENTS.md(schema、典型查询、陷阱清单,跨工具通用)和 Claude Code skill(.claude/skills/tdx2db-query/)。在本仓库目录下工作的 agent 可直接正确使用数据库,无需人工解释。
许可证
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tdx2db-0.5.0.tar.gz.
File metadata
- Download URL: tdx2db-0.5.0.tar.gz
- Upload date:
- Size: 36.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
221df5cd1486a11976a6affb5e3f7511030f1ae701d8b8bb9646243e6ec0606f
|
|
| MD5 |
a1579ad068ad156a0d5ccbf6d76d283d
|
|
| BLAKE2b-256 |
68f71d4d1d52891857b6982ca1815cbee33bda9d53dc27331459b35eabe50938
|
File details
Details for the file tdx2db-0.5.0-py3-none-any.whl.
File metadata
- Download URL: tdx2db-0.5.0-py3-none-any.whl
- Upload date:
- Size: 36.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9d9aa24868241fe11e207884805e481f4fc7221740de328e651e6bb03466342
|
|
| MD5 |
ad4d9b56766133ec6e7b3c7d5896cc76
|
|
| BLAKE2b-256 |
f3eef76c3989ad1ff4ac8633d4a14c8680fdbafa5676dd23dc4a3783fb172980
|