Files
easy_tdx_max/README.md
T
GitHubandClaude Opus 4.7 4820b4a049 feat: v1.1.0 - MAC protocol, CLI tool, extended markets, unified client
- Add MacClient/AsyncMacClient with full MAC protocol support (quotes, kline
  with adjustment, tick charts, transactions, boards, capital flow, auction,
  unusual, symbol info, server info)
- Add MacExClient/AsyncMacExClient for extended markets (HK, US, futures)
- Add UnifiedTdxClient auto-routing between A-share and extended markets
- Add `easy-tdx` CLI tool with JSON default output, Agent-friendly
- Add field bitmap protocol for custom quote field selection
- Fix quote-list missing fields (default to BASIC+VOLUME preset)
- Add config.py with centralized host management and auto-discovery
- Add 50+ examples covering all APIs (01-20)
- Rewrite README with CLI-first, Agent-friendly documentation
- Bump version to 1.1.0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 22:44:45 +08:00

483 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# easy-tdx
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![PyPI](https://img.shields.io/pypi/v/easy-tdx.svg)](https://pypi.org/project/easy-tdx/)
通达信 TCP 行情协议客户端。支持 A 股、港股、美股、期货全市场;内置 `easy-tdx` CLI 工具,默认 JSON 输出,天然适配 Claude Code、OpenClaw、Hermes 等 AI Agent 工具链。提供同步 + asyncio 双接口;strict mypy 通过;每一层编解码都有离线 fixture 测试覆盖。
## 安装
```bash
pip install easy-tdx
```
安装后自动注册 `easy-tdx` CLI 命令:
```bash
easy-tdx --help
```
开发模式:
```bash
pip install -e ".[dev]"
```
## CLI 参考
`easy-tdx` 默认输出 JSON(一行一条记录),`--table` 切换表格,`--output csv` 输出 CSV。
### 基础
```bash
easy-tdx ping # 服务器测速
easy-tdx version # 版本号
```
### 行情
```bash
# K 线
easy-tdx kline SZ 000001 --count 30 --table
easy-tdx kline SH 600519 --period 5MIN --adjust QFQ
# 实时报价
easy-tdx quote "SZ 000001,SH 600519" --table
# 市场分类报价(按涨幅排序)
easy-tdx quote-list A --count 20 --table
easy-tdx quote-list KCB --sort TOTAL_AMOUNT --order ASC
easy-tdx quote-list CYB --count 50
```
### 分时 / 成交
```bash
easy-tdx tick SZ 000001 --table
easy-tdx tick SH 600519 --days 5
easy-tdx tick SZ 000001 --date 20250115
easy-tdx transaction SZ 000001 --count 100 --table
easy-tdx transaction SH 600519 --date 20250115
```
### 板块
```bash
easy-tdx board-list --type GN --table
easy-tdx board-list --type HY --count 200
easy-tdx board-members 881001 --table
easy-tdx belong-board SZ 000001 --table
```
### 资金 / 监控
```bash
easy-tdx capital-flow SH 600519 --table
easy-tdx auction SZ 000001 --table
easy-tdx unusual SH --count 100 --table
easy-tdx market-stat --table
easy-tdx server-info --table
easy-tdx symbol-info SZ 000001 --table
```
### 财务
```bash
easy-tdx f10 SH 600519 # F10 公司信息
easy-tdx fund-flow SH 600519 # 历史资金流向
```
### 扩展市场(港股/美股/期货)
```bash
easy-tdx ex markets # 列出可用市场
easy-tdx ex kline HK_MAIN_BOARD 00700 --count 30 --table # 港股 K 线
easy-tdx ex kline US_STOCK AAPL --table # 美股 K 线
easy-tdx ex quote US_STOCK TSLA --table # 美股报价
easy-tdx ex quote-list HK_MAIN_BOARD --table # 港股商品列表
easy-tdx ex tick HK_MAIN_BOARD 00700 --table # 港股分时
```
## CLI 命令汇总
| 命令 | 说明 |
|------|------|
| `ping` | 服务器延迟测速 |
| `version` | 版本号 |
| `kline` | K 线(日/周/月/分钟,支持复权) |
| `quote` | 实时报价(单只/批量) |
| `quote-list` | 市场分类排序报价(A/SH/SZ/KCB/CYB |
| `tick` | 分时图(单日/多日/历史) |
| `transaction` | 逐笔成交 |
| `board-list` | 板块列表(行业/概念/风格) |
| `board-members` | 板块成分股报价 |
| `belong-board` | 个股所属板块 |
| `capital-flow` | 资金流向 |
| `auction` | 集合竞价 |
| `unusual` | 市场异动 |
| `market-stat` | 全市场涨跌统计 |
| `server-info` | 服务器交易时段 |
| `symbol-info` | 个股特征快照 |
| `f10` | F10 公司信息 |
| `fund-flow` | 历史资金流向 |
| `ex kline` | 扩展市场 K 线 |
| `ex quote` | 扩展市场报价 |
| `ex quote-list` | 扩展市场商品列表 |
| `ex tick` | 扩展市场分时 |
| `ex markets` | 列出可用扩展市场 |
## Python API
### 连接管理
所有客户端支持 `from_best_host()` 自动选最低延迟服务器:
```python
from easy_tdx import MacClient
with MacClient.from_best_host() as c:
df = c.get_stock_kline(...)
```
| 客户端 | 端口 | 覆盖范围 |
|--------|------|----------|
| `MacClient` / `AsyncMacClient` | 7709 | A 股行情(MAC 协议,推荐) |
| `MacExClient` / `AsyncMacExClient` | 7727 | 港股/美股/期货(MAC 协议) |
| `UnifiedTdxClient` / `AsyncUnifiedTdxClient` | 自动 | A 股 + 扩展市场统一入口 |
| `TdxClient` / `AsyncTdxClient` | 7709 | A 股行情(标准协议) |
### MAC 协议(推荐)
#### 报价
```python
from easy_tdx import MacClient, Market, Category, SortType, SortOrder
with MacClient.from_best_host() as c:
# 批量报价(最多 80 只/次)
df = c.get_stock_quotes([(Market.SH, "600519"), (Market.SZ, "000858")])
# 市场分类排序报价
df = c.get_stock_quotes_list(
Category.A, count=20,
sort_type=SortType.CHANGE_PCT,
sort_order=SortOrder.DESC,
)
```
返回列:`market, code, name` + 动态字段(`pre_close, open, high, low, close, vol, amount, turnover, vol_ratio` 等)。
#### K 线(支持复权)
```python
from easy_tdx import MacClient, Market, Period, Adjust
with MacClient.from_best_host() as c:
# 日K前复权
df = c.get_stock_kline(Market.SH, "600519", Period.DAILY, count=10, adjust=Adjust.QFQ)
# 5分钟线
df = c.get_stock_kline(Market.SZ, "000001", Period.MIN_5, count=100)
```
返回列:`datetime, open, close, high, low, vol, amount`
#### 分时
```python
with MacClient.from_best_host() as c:
df = c.get_tick_chart(Market.SH, "600519") # 单日分时
df = c.get_tick_charts(Market.SH, "600519", days=3) # 多日分时(最多5天)
df = c.get_chart_sampling(Market.SH, "600519") # 240点缩略采样
```
#### 逐笔成交
```python
with MacClient.from_best_host() as c:
df = c.get_transactions(Market.SH, "600519", count=100)
df = c.get_transactions(Market.SH, "600519", count=100, date=20250115)
```
#### 板块
```python
from easy_tdx import BoardType
with MacClient.from_best_host() as c:
df = c.get_board_list(BoardType.GN) # 概念板块
df = c.get_board_members("881001", sort_type=SortType.CHANGE_PCT)
df = c.get_belong_board(Market.SZ, "000001") # 个股所属板块
```
#### 资金流向
```python
with MacClient.from_best_host() as c:
df = c.get_capital_flow(Market.SH, "600519")
```
返回列:`date, main_in, main_out, main_net, small_in/out/net, mid_in/out/net, large_in/out/net`
#### 监控
```python
with MacClient.from_best_host() as c:
df = c.get_auction(Market.SH, "600519") # 集合竞价
df = c.get_unusual(Market.SH) # 市场异动
df = c.get_symbol_info(Market.SZ, "000001") # 个股特征快照
df = c.get_server_info() # 服务器交易时段
```
### 扩展市场
```python
from easy_tdx import MacExClient, ExMarket, Period
with MacExClient.from_best_host() as c:
count = c.goods_count(ExMarket.HK_MAIN_BOARD)
df = c.goods_list(ExMarket.HK_MAIN_BOARD, start=0, count=50)
df = c.goods_kline(ExMarket.US_STOCK, "AAPL", Period.DAILY, count=10)
df = c.goods_quotes([(ExMarket.HK_MAIN_BOARD, "00700")])
df = c.goods_tick_chart(ExMarket.HK_MAIN_BOARD, "00700")
df = c.goods_transaction(ExMarket.HK_MAIN_BOARD, "00700", count=100)
```
### 统一客户端
```python
from easy_tdx import UnifiedTdxClient, ExMarket, Market, Period
with UnifiedTdxClient() as client:
# A 股 -- 自动路由到 MacClient
df = client.get_stock_kline(Market.SH, "600519", Period.DAILY, count=5)
df = client.get_stock_quotes([(Market.SH, "600519")])
df = client.get_board_list()
# 扩展市场 -- 自动路由到 MacExClient
df = client.goods_kline(ExMarket.HK_MAIN_BOARD, "00700", Period.DAILY, count=5)
```
### 标准协议
```python
from easy_tdx import TdxClient, Market, KlineCategory
with TdxClient.from_best_host() as c:
count = c.get_security_count(Market.SH)
stocks = c.get_security_list(Market.SH, start=0)
quotes = c.get_security_quotes([(Market.SH, "600000"), (Market.SZ, "000001")])
bars = c.get_security_bars(Market.SZ, "002176", KlineCategory.DAY, 0, 100)
minute = c.get_minute_time_data(Market.SH, "600000")
trades = c.get_transaction_data(Market.SH, "600000", 0, 20)
flow = c.get_fund_flow(Market.SH, "600519")
blocks = c.get_block_info("block_gn.dat")
xdxr = c.get_xdxr_info(Market.SH, "600519")
stat = c.get_market_stat()
```
`AsyncTdxClient` 提供对应的 `async def` 方法,接口一一对应。
### 离线数据读取
无需网络,从本地通达信安装目录直接读取:
```python
from easy_tdx.offline import detect_tdx_home, read_daily_bars, find_daily_bar_file
from easy_tdx import Market
home = detect_tdx_home()
filepath = find_daily_bar_file(Market.SH, "600000")
bars = read_daily_bars(filepath)
```
支持:日线、分钟线、扩展市场日线、板块、股本变迁、历史财务数据。
## 枚举参考
### PeriodK 线周期)
| 值 | 名称 | 说明 |
|----|------|------|
| 7 | `MIN_1` | 1 分钟 |
| 0 | `MIN_5` | 5 分钟 |
| 1 | `MIN_15` | 15 分钟 |
| 2 | `MIN_30` | 30 分钟 |
| 3 | `MIN_60` | 60 分钟 |
| 4 | `DAILY` | 日线 |
| 5 | `WEEKLY` | 周线 |
| 6 | `MONTHLY` | 月线 |
| 10 | `QUARTERLY` | 季线 |
| 11 | `YEARLY` | 年线 |
### Adjust(复权类型)
| 值 | 名称 | 说明 |
|----|------|------|
| 0 | `NONE` | 不复权 |
| 1 | `QFQ` | 前复权 |
| 2 | `HFQ` | 后复权 |
### Category(市场分类)
| 值 | 名称 | 说明 |
|----|------|------|
| 0 | `SH` | 上证 A 股 |
| 2 | `SZ` | 深证 A 股 |
| 6 | `A` | 全部 A 股 |
| 7 | `B` | B 股 |
| 8 | `KCB` | 科创板 |
| 12 | `BJ` | 北证 A 股 |
| 14 | `CYB` | 创业板 |
### BoardType(板块类型)
| 值 | 名称 | 说明 |
|----|------|------|
| 0 | `HY` | 行业一级 |
| 1 | `HY2` | 行业二级 |
| 3 | `GN` | 概念 |
| 4 | `FG` | 风格 |
| 5 | `DQ` | 地区 |
| 255 | `ALL` | 全部 |
### SortType(排序字段)
| 名称 | 说明 |
|------|------|
| `CODE` | 代码 |
| `PRICE` | 现价 |
| `CHANGE_PCT` | 涨幅% |
| `VOLUME` | 成交量 |
| `TOTAL_AMOUNT` | 成交额 |
| `TURNOVER_RATE` | 换手% |
| `MAIN_NET_AMOUNT` | 主力净额 |
### ExMarket(扩展市场)
| 值 | 名称 | 说明 |
|----|------|------|
| 28 | `ZZ_FUTURES` | 郑州商品 |
| 29 | `DL_FUTURES` | 大连商品 |
| 30 | `SH_FUTURES` | 上海期货 |
| 31 | `HK_MAIN_BOARD` | 香港主板 |
| 47 | `CFFEX_FUTURES` | 中金所期货 |
| 48 | `HK_GEM` | 香港创业板 |
| 74 | `US_STOCK` | 美国股票 |
### Market(市场)
| 值 | 名称 | 说明 |
|----|------|------|
| 0 | `SZ` | 深圳 |
| 1 | `SH` | 上海 |
| 2 | `BJ` | 北京 |
## 完整 API 列表
### MacClient / AsyncMacClient
| 方法 | 说明 |
|------|------|
| `get_stock_quotes(stocks, fields)` | 批量实时报价 |
| `get_stock_quotes_list(category, ...)` | 市场分类排序报价 |
| `get_stock_kline(market, code, period, ...)` | K 线(支持复权) |
| `get_tick_chart(market, code, date)` | 单日分时图 |
| `get_tick_charts(market, code, days)` | 多日分时图 |
| `get_chart_sampling(market, code)` | 分时缩略采样 |
| `get_transactions(market, code, ...)` | 逐笔成交 |
| `get_symbol_info(market, code)` | 个股特征快照 |
| `get_board_list(board_type, ...)` | 板块列表 |
| `get_board_members(board_symbol, ...)` | 板块成分股报价 |
| `get_belong_board(market, code)` | 个股所属板块 |
| `get_capital_flow(market, code)` | 资金流向 |
| `get_auction(market, code)` | 集合竞价 |
| `get_unusual(market, ...)` | 市场异动 |
| `get_server_info()` | 服务器交易时段 |
| `get_kline_offset(offset, count)` | K 线偏移信息 |
| `get_goods_list(market, ...)` | 扩展市场商品列表 |
### MacExClient / AsyncMacExClient
| 方法 | 说明 |
|------|------|
| `goods_count(market)` | 商品总数 |
| `goods_list(market, start, count)` | 商品列表 |
| `goods_quotes(stocks, fields)` | 批量报价 |
| `goods_quotes_list(market, ...)` | 市场分类报价列表 |
| `goods_kline(market, code, period, ...)` | K 线(支持复权) |
| `goods_tick_chart(market, code, ...)` | 分时图 |
| `goods_chart_sampling(market, code)` | 分时缩略采样 |
| `goods_transaction(market, code, ...)` | 逐笔成交 |
### TdxClient / AsyncTdxClient
| 方法 | 说明 |
|------|------|
| `get_security_count(market)` | 市场证券总数 |
| `get_security_list(market, start)` | 证券列表(分页) |
| `get_security_list_all()` | 沪深 A 股完整列表(含行业) |
| `get_security_quotes(stocks)` | 批量五档行情 |
| `get_security_bars(market, code, ...)` | 个股 K 线 |
| `get_index_bars(market, code, ...)` | 指数 K 线 |
| `get_minute_time_data(market, code)` | 今日分时 |
| `get_history_minute_time_data(market, code, date)` | 历史分时 |
| `get_transaction_data(market, code, ...)` | 当日逐笔成交 |
| `get_history_transaction_data(...)` | 历史逐笔成交 |
| `get_fund_flow(market, code)` | 当日资金流向 |
| `get_history_fund_flow(market, code, ...)` | 历史资金流向 |
| `get_xdxr_info(market, code)` | 除权除息历史 |
| `get_finance_info(market, code)` | 最新财务数据 |
| `get_company_info_category(market, code)` | 公司信息目录 |
| `get_company_info_content(...)` | 公司信息文本 |
| `get_block_info(filename)` | 板块信息 |
| `get_report_file(filename)` | 下载服务器文件 |
| `get_market_stat()` | 全市场涨跌统计 |
| `get_price_limits(market, code, name, pre_close)` | 涨跌停价 |
## 架构
```
src/easy_tdx/
├── client.py # TdxClient / AsyncTdxClient(标准协议)
├── unified.py # UnifiedTdxClient(统一入口)
├── config.py # 服务器地址、端口、超时配置
├── mac/
│ ├── client.py # MacClient / AsyncMacClientMAC 协议)
│ ├── enums.py # Period, Adjust, Category, ExMarket, SortType, ...
│ ├── models.py # MacBar, MacQuoteField, MacTick, BoardInfo, ...
│ └── commands/ # MAC 命令(build_request + parse_response,无 IO
├── ex/
│ ├── client.py # ExTdxClient / AsyncExTdxClient(标准协议扩展市场)
│ ├── mac_client.py # MacExClient / AsyncMacExClientMAC 协议扩展市场)
│ └── transport/ # ExTdxConnection(端口 7727
├── transport/
│ ├── sync.py # TdxConnection + ping_host / ping_all
│ └── async_.py # AsyncTdxConnectionasyncio
├── commands/ # 标准协议命令(无 IO)
├── codec/ # price / volume / datetime / frame / bitmap 编解码
├── models/ # 纯 dataclass,无业务逻辑
├── offline/ # 离线数据读取模块
└── cli/ # easy-tdx CLIclick
```
commands 层不依赖 transport,可独立单测。
## 开发
```bash
python -m pytest tests/unit/ -v # 单元测试(无需网络)
XMTDX_LIVE=1 python -m pytest tests/integration/ -v # 集成测试
mypy src/ # 类型检查
ruff check src/ tests/ # lint
ruff format --check src/ tests/ # format check
```
## 致谢
- [pytdx](https://github.com/rainx/pytdx) -- 离线数据读取模块借鉴自 pytdx 项目,感谢 rainx 及所有贡献者
- [xmtdx](https://github.com/minionszyw/xmtdx) -- 本项目初始原型
- [mootdx](https://github.com/mootdx/mootdx) -- 工程化封装参考
详见 [NOTICE](NOTICE) 和 [LICENSE](LICENSE)。