如果需要多数据源可以关注新项目 AxData:AxData 基于 eltdx 迭代开发,除通达信体系外,AxData 还通过插件机制整理接入交易所、巨潮、腾讯财经、新浪财经、东方财富、财联社、开盘红等公开源接口,并扩展了自由流通市值、开盘换手、开盘量比、开盘抢筹、竞价昨比、连板天梯、题材强度等更适合本地量化研究和短线数据分析的指标能力,但如果是用单一源的话,仍推荐eltdx,受制于架构axdata性能不如裸协议路径的eltdx。
通达信行情与数据 Python 库。支持 A 股行情、分时、成交明细、K 线、竞价、公司信息和题材信息;提供扩展行情(EX)、MAC / MAC-EX、基金与外盘相关接口,以及本地行情文件和专业财务数据读取能力。7709 协议核心由 Rust 实现,支持 MCP 工具和 HTTP 网关。各行情接口的数据覆盖以服务器实际支持为准。
- 本项目仅供个人学习、数据接口与格式研究及非商业用途使用。
- 禁止将本项目、衍生作品或通过本项目获取的数据用于商业活动、付费服务、生产服务、转售、营利性数据服务、自动化交易服务,或违反适用法律法规、交易所规则、第三方服务协议及他人权益的用途。
- 对第三方服务器或服务的访问,用户需自行遵守相关法律法规及服务协议。
- 使用者对第三方服务、通过本项目获取的数据及由此产生的法律、监管、财务和运营后果自行负责。
- 请勿将本项目用于侵犯他人权益、违反监管规定或滥用第三方服务的行为。
感谢 injoyai/tdx 及 rainx/pytdx 的启发。
功能地图
eltdx 默认按“想拿什么数据”组织入口。普通调用优先使用模块化 API 和 Helpers;需要核对底层字段时,再对照 7709 命令或 7615 Entry。下表的代表调用均来自当前接口文档,点击方法名可直接查看参数、返回字段和同类方法。
完整接口目录见 GitHub Pages。调用方法和返回字段看 METHOD_REFERENCE.md,常用问题入口看 docs/helpers/README.md,完整 API 看 API_REFERENCE.md,字段总表看 FIELD_REFERENCE.md,F10 资料看 F10_7615.md,MCP 工具看 MCP.md。
安装
pip install eltdx
为 CPython 3.10-3.14 提供 Windows x64、manylinux x64/ARM64、macOS x64/ARM64 五个 cp310-abi3 wheel。匹配 wheel 时不需要安装 Rust。没有匹配 wheel 的平台会尝试从 sdist 编译,需要 Rust 1.89 工具链;不提供纯 Python 7709 fallback。PyPy、free-threaded CPython、musllinux 和其他未列出的组合不在当前支持范围。
如果需要启动 MCP stdio 工具服务,安装可选依赖:
pip install "eltdx[mcp]"
Java、Go、C#、Node.js 等语言需要通过 HTTP 或 WebSocket 调用时,再安装网关依赖:
pip install "eltdx[http]"
eltdx-http
默认 pip install eltdx 不会安装 FastAPI 或 Uvicorn,也不会启动额外服务。网关用法见 跨语言 HTTP / WebSocket 网关。
源码目录安装:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
pip install -e ".[dev,mcp]"
源码安装会编译私有扩展 eltdx._native。Python 文件与 native 二进制的 ABI 不一致时,导入会立即失败,不会静默切换到旧实现。
源码开发时建议始终先安装到当前虚拟环境;否则本机如果已有旧版 eltdx,python -m eltdx... 可能导入 site-packages 里的旧包。
安装后可以先看命令帮助:
eltdx-smoke --help
eltdx-f10-smoke --help
MCP 工具服务启动后会占用当前终端作为 stdio 服务:
eltdx-mcp
源码开发自测:
python -m pytest
源码仓库里的 scripts/ 目录用于开发和排查;通过 pip install eltdx 安装后,优先使用上面的命令行入口。
快速开始
查行情走 TdxClient
from eltdx import TdxClient
with TdxClient(timeout=3) as client:
quote = client.quotes.get_snapshots(["sz000001", "sh600000"])
bars = client.bars.get("sz000001", period="day", count=30)
minute = client.minutes.today("sz000001")
ticks = client.trades.all_history("sz000001", "2026-05-20")
# 可选批量数据返回;code 也可传代码列表,旧入口保持不变。
bulk = client.trades.all_history_batch("sz000001", "2026-05-20")
print(quote[0])
print(bars.bars[-1])
查 F10 / 资料数据走 client.f10
from eltdx import TdxClient
client = TdxClient(timeout=3)
profile = client.f10.company_profile("000034")
topics = client.f10.hot_topics("000034")
notices = client.f10.announcements("000034")
print(profile.rows[0])
print(topics.rows[:3])
print(notices.rows[:3])
如果只查 F10,也可以直接用轻量 HTTP 客户端:
from eltdx import F10Client
f10 = F10Client(timeout=3)
print(f10.company_profile("000034").rows[0])
行情接口
| 功能 | 调用方法 | 底层接口 | 返回内容 / 用途 | 文档 |
|---|
| 握手 | client.session.handshake() | 0x000d | 返回服务端日期时间、交易时段、主站名、产品标识;通常连接后自动使用 | 文档 |
| 心跳 | client.session.heartbeat() | 0x0004 | 返回服务端心跳响应;长连接默认后台 30 秒保活,也可手动调用 | 文档 |
| 市场代码数量 | client.codes.count(market) / client.codes.a_share_count(market) | 0x044e / 0x044d | 分别返回整个市场代码表条数或仅 A 股数量;前者不限证券品种 | 文档 |
| 代码表 | client.codes.all(market, ...) / client.codes.all_a_shares() / client.codes.list(market, ...) | 0x044d | 推荐自动翻页取全量;也可直接取 A 股、ETF、指数,或手动控制单页 | 文档 |
| 批量行情快照 | client.quotes.get_snapshots() | |
7709 命令和 API 对照见 COMMANDS_7709.md,完整调用参数见 API_REFERENCE.md。
K 线周期和复权
K 线是最常用的接口之一,周期和复权参数可以直接这样传:
client.bars.get("sz000001", period="day", count=200)
client.bars.get("sz000001", period="week", count=100)
client.bars.get("sz000001", period="year", count=20)
client.bars.get("sz000001", period="1m", count=240)
client.bars.get("sz000001", period="day", adjust="qfq", count=200)
client.bars.get("sz000001", period="day", adjust="hfq", count=200)
client.bars.get("sz000001", period="day", adjust="fixed_qfq", anchor_date="2024-06-03")
client.bars.get("sz000001", period="day", all_pages=True, page_size=800)
| 参数 | 可选值 | 含义 |
|---|
period | 1m, 5m, 15m, 30m, 60m | 分钟 K 线 |
period | day, week, month, quarter, year | 日 K、周 K、月 K、季 K、年 K |
period | 10m, 2d, 5s 这类形式 | 协议层支持自定义分钟、N 日、N 秒周期;实际返回以服务端支持为准 |
adjust | None / none | 不复权 |
adjust | qfq / front | 前复权 |
adjust | hfq / back | 后复权 |
adjust | fixed_qfq / fixed_hfq | 定点前复权 / 定点后复权,需要配合 anchor_date |
anchor_date | YYYY-MM-DD、YYYYMMDD、date | 定点复权基准日期,仅定点复权时需要 |
直接查询前复权和后复权 K 线,使用 client.bars.get(..., adjust="qfq" / "hfq")。已有不复权 K 线、需要本地计算或审计时,使用 client.corporate.adjustment_factors();本地计算与服务端复权价格可能存在差异。
将本地系数应用到一段完整不复权 K 线时,必须把第一根 K 线日期传给 start_date,并建议把最后一根 K 线日期传给 anchor_date。start_date=None 会使用全部有日期的权息事件,可能累计早于服务端第一根可用 K 线的记录,直接用于后复权会产生错误基准。即使日期范围正确,本地 0x000f 计算与服务端 0x052d 的累计精度和舍入顺序仍可能带来约 0.01~0.02 元差异;需要服务端口径时请直接使用 bars.get(adjust=...)。
F10 资料接口
| 功能 | 调用方法 | 底层 Entry | 返回内容 / 用途 | 文档 |
|---|
| 高级调用(需手动指定 Entry 和参数) | client.f10.call(entry, body/params) | 7615/TQLEX | 用户主动指定 Entry 和参数;用于调试或调用 SDK 尚未封装的 Entry,不会自动执行 | 文档 |
| 股票基础信息 | client.f10.stock_info() | CWServ.tdxf10_gg_comreq | 返回股票名称、代码、市场;也用于主营构成报告期、题材 ID 等辅助查询 | 文档 |
| 涨跌停列表 | client.f10.limit_up_down_list() | CWServ.cfg_fx_lbtt | 返回指定日期 / 日期范围的逐股涨停、连板、涨停原因和封单明细;可选市场概况 | 文档 |
| 公司概况 | client.f10.company_profile() | CWServ.tdxf10_gg_gsgk | 返回发行上市信息,如上市日期、发行方式、发行价、募资额、承销商等 | 文档 |
| 主营构成 | client.f10.business_composition() | |
常规 F10 返回 F10Response;client.f10.limit_board_ladder() 返回 LimitBoardLadder。常用结果分别在 response.rows 或模型的 rows,完整说明见 F10_7615.md。
连接、并发和缓存
默认 TdxClient() 使用真实 7709 行情主站,并以单个连接、关闭自动测速的保守配置启动。需要多节点或并发请求时,可以显式设置连接池和并发参数。
核心关系: 服务器数 × 每台 TCP 连接数 = Slot 总数。默认只有 1 个 Slot;需要并行处理多个请求时,由调用方显式配置服务器数和连接数。
服务器测速与排名
- 不传
host / hosts 时,客户端使用默认候选主站配置;显式配置会覆盖普通行情节点。
probe_hosts=False 默认关闭自动测速。需要测量并缓存候选主站延迟时,显式设置 probe_hosts=True,或调用 refresh_server_ranking()。
- 测速只打开并关闭临时探测连接,不创建业务 Engine、不做协议握手。进入
with 或显式 connect() 连接普通池;集合竞价与资金流向的独立池仍在首次请求时按需建连、握手,后续复用连接。
- 同一客户端生命周期内复用内存排名,不重复测速;内存和自定义非池化 transport 不触发测速。
- 测速检查的是 TCP connect 延迟,用来快速排除连不上或延迟高的主站;它不等于完整业务请求质量测试。
- 排名会原子写入当前用户数据目录的
tdx_server_ranking.json。下次启动先使用上次排名,然后重新测速刷新;升级 eltdx 不会覆盖这份用户排名。
也可以手动重测候选主站并持久化结果:
from eltdx.hosts import refresh_server_ranking
ranking = refresh_server_ranking(timeout=1.2)
for item in ranking[:10]:
print(item)
如果不想自动选站,可以直接指定一台主站:
from eltdx import TdxClient
with TdxClient(host="HOST:PORT", timeout=3) as client:
print(client.helpers.full_quotes("sz000001"))
服务器、Slot 和线程怎么设
| 场景 | 配置 | 实际含义 |
|---|
| 默认,适合普通查询 | TdxClient() | 1 台 × 1 TCP = 1 Slot;不自动测速 |
| 显式并发 | TdxClient(server_count=2, connections_per_server=4) | 由调用方选择主站数和连接数 |
| 手动限制建连并发 | TdxClient(pool_size=8, connect_concurrency=2) | 建立连接时最多同时进行 2 个握手 |
| 手动限制 CPU 线程 | TdxClient(server_count=4, connections_per_server=8, runtime_workers=8) | 仍为 32 Slot,只让 Rust Runtime 用 8 个 worker 驱动 |
| 兼容旧配置 | TdxClient(pool_size=16) | pool_size 仅表示 TCP/Slot 总数,在选中主站之间尽量平均分配 |
runtime_workers 默认为 min(pool_size, 当前进程可用的逻辑处理器数),会识别 Windows、Linux 和 macOS,也会尽量遵守容器或 CPU affinity 对进程的限制。自动值适合大多数情况;手动值必须在 1..=pool_size 内。更多 worker 只是提高同时解析/调度的 CPU 能力,不会凭空增加 TCP 连接。
| 参数 | 默认 | 控制什么 |
|---|
server_count | 1 | 使用的服务器数量 |
connections_per_server | 1 | 每台选中服务器建立的 TCP 连接数 |
pool_size | 1 | TCP/Slot 总数;显式同时传三者时,乘积必须一致 |
runtime_workers | 按 Slot 和逻辑 CPU 自动 | Rust Tokio Runtime 工作线程数 |
max_connections_per_host | 按初始分布自动 | 单台服务器的活动连接硬上限,重连时也遵守 |
connect_concurrency | 1 | 建立和握手 TCP 连接时的同时任务数;需要并发时显式提高 |
connect_concurrency_per_host | 1 | 单台服务器建立 TCP 连接时的同时任务数 |
probe_hosts | False | 是否显式测速并缓存候选主站排名 |
heartbeat_interval | 30.0 | 后台心跳秒数;None 表示关闭 |
max_pending_requests | 256 | Slot 全忙时允许等待的请求数;满后抛 PoolBusyError |
push_queue_size / push_queue_bytes | 1024 帧 / 64 MiB | 用户可见 push 缓冲的帧数和字节上限 |
global_raw_bytes / global_decoded_bytes | 随 Slot 自动增长 | Engine 全局内存预算,分别最高 256 MiB / 2 GiB,防止异常流量无限增长 |
连接建立默认按顺序进行;显式设置 connect_concurrency 后才会提高建连阶段的同时任务数。连接建立完成后,已配置的多个 Slot 可以并行处理请求;runtime_workers 只控制 Rust Runtime 的工作线程数。所有连接共享 Engine 级 raw、decoded 和 push 内存预算。
运行时可通过 diagnostics 查看真实线程数、已连主站和内存占用:
with TdxClient(server_count=4, connections_per_server=8, timeout=3) as client:
snapshot = client.transport.diagnostics
print(snapshot.runtime_workers, snapshot.server_count)
print(client.transport.connected_hosts)
print(snapshot.raw_bytes, snapshot.decoded_bytes)
每个 Engine 使用一个单所有者 Supervisor 统一管理请求生命周期;每个 Slot task 独占自己的 socket、decoder 和 TCP generation。某条连接超时或返回异常时,只废弃当前 Slot 的连接代次,避免迟到响应污染后续请求。
建议始终使用 with TdxClient(...) as client:。退出 with 时会停止接收新请求、清理 pin/push、关闭 socket 并等待 Runtime 结束。手动创建客户端时,需要在 finally 中调用 client.close()。
真实 socket 默认每 30 秒自动心跳保活。关闭后台心跳:
client = TdxClient(heartbeat_interval=None)
Helpers 会缓存 stock_profile_table() 内部使用的财务批次、证券表和已验证的短线统计资源。代码数量、代码表、股本变迁、直接财务查询、实时行情、分时、成交明细和 K 线不缓存。
client.helpers.shortline_indicators("sz000001", refresh_stats=True)
client.clear_cache()
调试和导出
部分接口支持 include_raw=True,用于保留原始 payload 或单条记录 hex,方便排查字段解析问题。
gbbq = client.corporate.capital_changes("sz000001", include_raw=True)
bars = client.bars.get("sz000001", period="day", include_raw=True)
ticks = client.trades.history("sz000001", "2026-05-20", include_raw=True)
返回模型可以直接转 JSON:
from eltdx import to_json, to_jsonable
data = to_jsonable(client.helpers.full_quotes("sz000001"))
text = to_json(data, indent=2)
真实环境 smoke:
eltdx-smoke --timeout 6 --no-heartbeat
eltdx-f10-smoke --code 000034 --timeout 8
源码仓库可运行更多开发脚本,例如批量导出某段日期的 09:25 竞价成交快照:
python scripts/smoke/export_auction_925_daily.py --code sz000001 --start 2026-04-01 --end 2026-04-30
文档
不用按文件名翻目录,按要解决的问题进入即可:
常用问题
常用组合调用示例:
from eltdx import TdxClient
with TdxClient(timeout=3) as client:
table = client.helpers.stock_profile_table(["sz000001", "sh600000"])
shortline = client.helpers.shortline_indicators(["sz000001", "sh600000"])
topics = client.helpers.stock_topics("000034")
stocks = client.helpers.topic_stocks("000034", topic_name="存储芯片")
auction = client.helpers.auction_data("sz000001", "2026-05-20")
print(table.rows[0])
print(shortline.rows[0])
print(topics.topics[:3])
print(stocks.rows[:10])
print(auction.open_price, auction.open_change_pct, auction.open_amount)
完整入口见 docs/helpers/README.md。
联系
许可证
本项目仅供个人学习、数据接口与格式研究及非商业用途使用。禁止将本项目、衍生作品或通过本项目获取的数据用于商业活动、付费服务、生产服务、转售、营利性数据服务、自动化交易服务,或违反适用法律法规、交易所规则、第三方服务协议及他人权益的用途。完整条款以 LICENSE 为准。