Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
rustdx
受 pytdx 启发的 A 股数据获取工具,包含:
- 一个 Rust 通用库 rustdx-complete;
- 一个命令行工具 rustdx-cmd。
📝 最新更新 (v0.5.0+)
🔧 重要修复
1. 修复中文编码显示问题
- ✅ 修复 GBK 编码的中文数据显示为乱码的问题
- ✅ 股票名称、指数名称等中文数据现在能正确显示
- ✅ 使用
encoding_rs库进行 GBK → UTF-8 编码转换
2. 修复服务器连接问题
- ✅ 优化服务器 IP 顺序,将可用的服务器移到前面
- ✅ 默认服务器
115.238.56.198:7709现在能正常返回数据
3. 修复内存安全问题
- ✅ 移除所有
unsafe的get_unchecked操作 - ✅ 添加数据边界检查,防止 panic
- ✅ 所有解析函数现在都能安全处理不完整数据
4. 修复示例代码
- ✅ 更新所有示例代码使用正确的 crate 名称
rustdx_complete - ✅ 所有 10 个示例程序现在都能正常编译和运行
rustdx 库使用
rustdx 是一个功能完整的 A 股数据获取库,完全对标 pytdx 的核心功能。
功能特性
| 功能 | rustdx 模块 | pytdx 对应 | 说明 |
|---|---|---|---|
| 日K线 | Kline |
get_security_bars |
支持多种周期(日/周/月/分钟) |
| 除权数据 | Xdxr |
get_xdxr |
股票除权除息信息 |
| 实时行情 | SecurityQuotes |
get_security_quotes |
股票和指数实时快照 |
| 股票列表 | SecurityList |
get_security_list |
获取所有股票代码 |
| 分时数据 | MinuteTime |
get_minute_time_data |
当日分时成交数据 |
| 逐笔成交 | Transaction |
get_transaction_data |
tick-level 成交数据 |
| 财务信息 | FinanceInfo |
get_finance_info |
32个财务基本面数据 |
| 指数行情 | SecurityQuotes |
get_index_quotes |
上证指数、深证成指等 |
安装
[]
= "0.5.0"
使用示例
获取股票实时行情
use ;
use SecurityQuotes;
获取指数行情
use ;
use SecurityQuotes;
let mut tcp = new?;
// 获取主要指数行情
let mut quotes = new;
quotes.recv_parsed?;
for quote in quotes.result
获取日线数据
use ;
use Kline;
let mut tcp = new?;
let mut kline = new; // 沪市、浦发银行、日线、从0开始获取10条
kline.recv_parsed?;
for bar in kline.result
获取财务信息
use ;
use FinanceInfo;
let mut tcp = new?;
let mut finance = new; // 深市、平安银行
finance.recv_parsed?;
let info = &finance.result;
println!;
println!;
println!;
println!;
获取分时数据
use ;
use MinuteTime;
let mut tcp = new?;
let mut minute = new; // 深市、平安银行、从第0条开始
minute.recv_parsed?;
for data in minute.result.iter.take
获取逐笔成交
use ;
use Transaction;
let mut tcp = new?;
let mut transaction = new; // 深市、平安银行、从第0条开始
transaction.recv_parsed?;
for data in transaction.result.iter.take
市场代码说明
0= 深市(深圳证券交易所)1= 沪市(上海证券交易所)
超时设置
默认 TCP 超时时间为 5 秒。如果网络环境较差,可以调整 src/tcp/mod.rs 中的 TIMEOUT 常量。
完整示例程序
项目 examples/ 目录下提供了完整的使用示例:
test_security_quotes.rs- 股票和指数行情test_kline.rs- K线数据test_finance_info.rs- 财务信息test_minute_time.rs- 分时数据test_transaction.rs- 逐笔成交test_security_list.rs- 股票列表
运行示例:
快速开始
1. 创建新项目
2. 添加依赖
在 Cargo.toml 中添加:
[]
= "0.5"
或使用 cargo add:
3. 编写代码
在 src/main.rs 中:
use ;
use SecurityQuotes;
4. 运行
API 文档
完整的 API 文档请访问:
- docs.rs: https://docs.rs/rustdx-complete
- crates.io: https://crates.io/crates/rustdx-complete
详细使用示例
股票实时行情
获取多只股票的实时快照数据:
use ;
use SecurityQuotes;
let mut tcp = new?;
let mut quotes = new;
quotes.recv_parsed?;
for quote in quotes.result
注意事项:
- 建议一次查询不超过 80 只股票
- 市场代码:0=深市,1=沪市
- 数据为实时快照,包括五档买卖盘
指数行情
获取主要指数的实时行情:
use ;
use SecurityQuotes;
let mut tcp = new?;
// 获取主要指数
let mut quotes = new;
quotes.recv_parsed?;
println!;
for quote in quotes.result
常用指数代码:
- 上证指数:
000001(market=1) - 深证成指:
399001(market=0) - 沪深300:
000300(market=1) - 创业板指:
399006(market=0) - 中证500:
000905(market=1) - 科创50:
000688(market=1)
K线数据
获取日K线、周K线、月K线等:
use ;
use Kline;
let mut tcp = new?;
// Kline参数:market, code, category, start, count
// category: 5=日K, 6=周K, 7=月K, 8=1分钟K, 9=日K(新)
let mut kline = new; // 获取浦发银行最近10天日K线
kline.recv_parsed?;
println!;
for bar in kline.result
K线周期说明:
category = 5: 5分钟K线category = 6: 15分钟K线category = 7: 30分钟K线category = 8: 1小时K线category = 9: 日K线category = 10: 周K线category = 11: 月K线
财务信息
获取股票的财务基本面数据:
use ;
use FinanceInfo;
let mut tcp = new?;
let mut finance = new; // 平安银行
finance.recv_parsed?;
let info = &finance.result;
println!;
println!;
println!;
println!;
println!;
println!;
println!;
println!;
财务字段说明:
zongguben: 总股本(股)liutongguben: 流通股本(股)zongzichan: 总资产(元)jingzichan: 净资产(元)jinglirun: 净利润(元)zhuyingshouru: 主营收入(元)jingyingxianjinliu: 经营现金流(元)
分时数据
获取当日分时成交数据(240个数据点):
use ;
use MinuteTime;
let mut tcp = new?;
let mut minute = new; // 平安银行,从第0条开始
minute.recv_parsed?;
println!;
for in minute.result.iter.take.enumerate
println!;
println!;
数据说明:
- 每个交易日产生 240 条分时数据
- 时间范围:9:30-15:00
- 时间格式:HH:MM
- 成交量单位:手
逐笔成交
获取 tick 级别的逐笔成交数据:
use ;
use Transaction;
let mut tcp = new?;
let mut transaction = new; // 从第0条开始
transaction.recv_parsed?;
println!;
for data in transaction.result.iter.take
println!;
println!;
买卖方向说明:
0: 买入(主动买)1: 卖出(主动卖)8: 中性(未知)
股票列表
获取所有股票代码和名称:
use ;
use SecurityList;
let mut tcp = new?;
// 第一次获取:从0开始,获取1000只股票
let mut list = new; // start参数:0, 1000, 2000...
list.recv_parsed?;
println!;
for in list.result.iter.take.enumerate
println!;
println!;
分页说明:
- 每次最多获取 1000 只股票
start参数:0, 1000, 2000, ...- 自动过滤到
start位置的股票
错误处理
所有 TCP 连接和数据获取都可能失败,建议使用错误处理:
use ;
use SecurityQuotes;
性能优化建议
- 复用 TCP 连接
let mut tcp = new?;
// 获取多种数据
let mut quotes = new;
quotes.recv_parsed?;
let mut kline = new;
kline.recv_parsed?;
- 批量查询
// 一次查询多只股票,而不是多次查询单只股票
let mut quotes = new;
- 使用 release 模式
常见问题
Q: 为什么连接超时?
A: 默认超时时间为 5 秒。如果网络环境较差,可以修改 src/tcp/mod.rs 中的 TIMEOUT 常量。
Q: 数据更新频率?
A: 实时行情数据来自通达信服务器,交易时间内实时更新。
Q: 支持港股和美股吗?
A: 目前仅支持 A 股(沪深两市)。
Q: 如何获取历史数据?
A: 使用 Kline 模块获取历史 K 线数据,或使用 rustdx-cmd 工具解析通达信数据文件。
Q: 数据准确吗?
A: 数据来自通达信官方服务器,经过验证准确可靠。
示例程序
项目 examples/ 目录包含完整的示例程序:
| 示例程序 | 功能描述 |
|---|---|
test_security_quotes.rs |
股票和指数实时行情 |
test_finance_info.rs |
财务信息查询 |
test_transaction.rs |
逐笔成交数据 |
test_minute_time.rs |
分时数据 |
test_security_list.rs |
股票列表 |
test_index_quotes.rs |
指数行情 |
运行示例:
贡献指南
欢迎贡献代码、报告问题或提出建议!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
致谢
- pytdx - Python 版本的通达信接口
- 通达信 - 提供数据服务器
命令行工具(统计数据基于笔者的单核 CPU Ubuntu 系统 release build,以实际速度为准):
- 解析所有最新股票列表的历史 A 股数据(包含复权数据)不到 30s ,解析后的 csv 大小 1G 多;
- 将解析后的 csv 数据插入到 ClickHouse (20s,表 268 M) 或 MongoDB (7 分钟,表超过 700 M);
- 东财日线增量更新(包括复权),2s 更新完。
关于复权:
- 使用涨跌幅复权算法,无需修改(重算)历史复权信息;
- 只计算收盘价前复权,其他价格复权只需基于收盘价和相对价格即可计算出来(这在 ClickHouse 中很快)。
具体文档待补充。
rustdx-cmd
安装
使用以下一种方式即可:
-
cargo install:
cargo install rustdx-cmd
- cargo build:
$ git clone https://github.com/zjp-CN/rustdx.git
$ cd rustdx
$ cargo build -p rustdx-cmd --release # 编译(二进制在 target/release 下)
$ cargo install --path rustdx-cmd # 安装(二进制在全局 .cargo/bin 下)
子命令
- day:解析通达信 day 文件,具体查看帮助
rustdx day --help、rustdx day -h o -h l。 - east:获取东方财富当日 A 股数据,具体查看帮助
rustdx east --help。
完整使用例子
准备好 day 文件、gbbq 文件和 ClickHouse 数据库:
p.s. 请勿使用本项目 assets/ 中的 gbbq 文件,因为那对你来说是过时的。
注意:
此工具的主要目的就是快速补齐历史日线数据,但没有校验交易日数据连续或者清空数据库的功能。
因没有每天记录日线导致日线不完整(或者其他原因导致数据有问题),请重新解析和存储所有历史数据。
重新存储数据之前,使用以下 sql 命令(以 ClickHouse 为例)删除历史数据:
TRUNCATE TABLE rustdx.factor;如果发现历史数据不正确,请提交 issue。
# 解析所有最新股票的历史日线数据,且计算复权数据
$ rustdx day /vdb/tmp/tdx/sh/ /vdb/tmp/tdx/sz/ -l official -g ../assets/gbbq -t rustdx.factor
# 写入 ClickHouse 数据库
$ clickhouse-client --query "INSERT INTO rustdx.factor FORMAT CSVWithNames" < stocks.csv
# 有了历史日线数据之后,每个交易日收盘之后,更新当天数据
$ rustdx east -p factor.csv -t rustdx.factor
# 写入 ClickHouse 数据库
$ clickhouse-client --query "INSERT INTO rustdx.factor FORMAT CSVWithNames" < eastmoney.csv
其中 factor.csv 来自数据库中,前一天的复权数据,ClickHouse 的导出命令:
SELECT
yesterday AS date,
code,
last_value(close) AS close,
last_value(factor) AS factor
FROM rustdx.factor
GROUP BY code
INTO OUTFILE 'factor.csv'
FORMAT CSVWithNames;
或者:
# 解析所有最新股票的历史日线数据,且计算复权数据,写入 ClickHouse 数据库
$ rustdx day /vdb/tmp/tdx/sh/ /vdb/tmp/tdx/sz/ -l official -g ../assets/gbbq -o clickhouse -t rustdx.factor
# 有了历史日线数据之后,每个交易日收盘之后,更新当天数据
$ rustdx east -p clickhouse -o clickhouse -t rustdx.factor
CHANGELOG
使用示例
计算任何周期的涨跌幅
SELECT
code,
toYYYYMM(date) AS m, -- 这里以月周期为例
((LAST_VALUE(factor) / FIRST_VALUE(factor)) * FIRST_VALUE(close)) / FIRST_VALUE(preclose) AS mgrowth
FROM rustdx.factor -- 命令行参数中所写入的表名,假设你按照我上面给的命令行示例运行,那么原始数据在这个表
GROUP BY code, m -- 按照月聚合
ORDER BY code ASC, m DESC;
为什么 mgrowth 是那样计算,见 涨跌幅复权与前复权。
计算前复权价格
注意,上面计算涨幅时没有计算前复权价格,但大部分情况下必须知道前复权价格来计算价格相关的指标。
那么可以每日数据成功入库之后,运行一次以下脚本,注意:
- 这基于最新价来计算所有股票的所有历史前复权价格(在我的单核机器上需要 11 秒)
- 每次运行脚本会把之前的计算结果清空
- 前复权的结果在
rustdx.qfq这个表(只有股票代码和价格)
-- 计算前复权价格
IF EXISTS rustdx.qfq_x; -- 临时表
(
code FixedString(6),
x Float64,
PRIMARY KEY(code)
) ENGINE = MergeTree AS
WITH
qfq AS (
SELECT code, LAST_VALUE(close) / LAST_VALUE(factor) AS qfq_multi
FROM rustdx.factor
GROUP BY code
ORDER BY code
)
SELECT * FROM qfq;
IF EXISTS rustdx.qfq; -- 前复权价格
(
date Date,
code FixedString(6),
close Float64,
open Float64,
high Float64,
low Float64,
PRIMARY KEY(date, code)
) ENGINE = MergeTree AS
WITH
qfq_x AS (SELECT * FROM rustdx.qfq_x),
fct AS (
SELECT date, code, open/close AS open, high/close AS high, low/close AS low, factor
FROM rustdx.factor
),
raw AS (
SELECT *
FROM fct
LEFT JOIN qfq_x ON qfq_x.code = fct.code
)
SELECT date, code, factor*x AS close, open*close AS open, high*close AS high, low*close AS low
FROM raw
ORDER BY date, code