tdxquant 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tdxquant-0.1.0/.gitignore +211 -0
- tdxquant-0.1.0/CLAUDE.md +92 -0
- tdxquant-0.1.0/PKG-INFO +117 -0
- tdxquant-0.1.0/README.md +107 -0
- tdxquant-0.1.0/docs/api_reference.md +139 -0
- tdxquant-0.1.0/docs/field_lineage.md +188 -0
- tdxquant-0.1.0/docs/superpowers/specs/2026-06-13-tdx-quant-sdk-design.md +232 -0
- tdxquant-0.1.0/main.py +85 -0
- tdxquant-0.1.0/pyproject.toml +34 -0
- tdxquant-0.1.0/tdx_api/__init__.py +57 -0
- tdxquant-0.1.0/tdx_api/api/__init__.py +16 -0
- tdxquant-0.1.0/tdx_api/api/calendar.py +53 -0
- tdxquant-0.1.0/tdx_api/api/financial.py +206 -0
- tdxquant-0.1.0/tdx_api/api/instrument.py +60 -0
- tdxquant-0.1.0/tdx_api/api/market.py +168 -0
- tdxquant-0.1.0/tdx_api/api/sector.py +130 -0
- tdxquant-0.1.0/tdx_api/client.py +186 -0
- tdxquant-0.1.0/tdx_api/enums.py +124 -0
- tdxquant-0.1.0/tdx_api/exceptions.py +16 -0
- tdxquant-0.1.0/tdx_api/schema.py +168 -0
- tdxquant-0.1.0/tests/conftest.py +21 -0
- tdxquant-0.1.0/tests/run_k.py +5 -0
- tdxquant-0.1.0/tests/test_client_unit.py +106 -0
- tdxquant-0.1.0/tests/test_enums.py +67 -0
- tdxquant-0.1.0/tests/test_integration.py +70 -0
- tdxquant-0.1.0/tests/test_schema.py +97 -0
- tdxquant-0.1.0/uv.lock +326 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
.idea
|
|
3
|
+
|
|
4
|
+
# 敏感配置文件
|
|
5
|
+
qdata-core/config.yaml
|
|
6
|
+
*.db
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[codz]
|
|
9
|
+
*$py.class
|
|
10
|
+
.tmp*
|
|
11
|
+
# C extensions
|
|
12
|
+
*.so
|
|
13
|
+
.venv/
|
|
14
|
+
data
|
|
15
|
+
# Distribution / packaging
|
|
16
|
+
.Python
|
|
17
|
+
build/
|
|
18
|
+
develop-eggs/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
var/
|
|
28
|
+
wheels/
|
|
29
|
+
share/python-wheels/
|
|
30
|
+
*.egg-info/
|
|
31
|
+
.installed.cfg
|
|
32
|
+
*.egg
|
|
33
|
+
MANIFEST
|
|
34
|
+
|
|
35
|
+
# PyInstaller
|
|
36
|
+
# Usually these files are written by a python script from a template
|
|
37
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
38
|
+
*.manifest
|
|
39
|
+
*.spec
|
|
40
|
+
|
|
41
|
+
# Installer logs
|
|
42
|
+
pip-log.txt
|
|
43
|
+
pip-delete-this-directory.txt
|
|
44
|
+
|
|
45
|
+
# Unit test / coverage reports
|
|
46
|
+
htmlcov/
|
|
47
|
+
.tox/
|
|
48
|
+
.nox/
|
|
49
|
+
.coverage
|
|
50
|
+
.coverage.*
|
|
51
|
+
.cache
|
|
52
|
+
nosetests.xml
|
|
53
|
+
coverage.xml
|
|
54
|
+
*.cover
|
|
55
|
+
*.py.cover
|
|
56
|
+
.hypothesis/
|
|
57
|
+
.pytest_cache/
|
|
58
|
+
cover/
|
|
59
|
+
|
|
60
|
+
# Translations
|
|
61
|
+
*.mo
|
|
62
|
+
*.pot
|
|
63
|
+
|
|
64
|
+
# Django stuff:
|
|
65
|
+
*.log
|
|
66
|
+
local_settings.py
|
|
67
|
+
db.sqlite3
|
|
68
|
+
db.sqlite3-journal
|
|
69
|
+
|
|
70
|
+
# Flask stuff:
|
|
71
|
+
instance/
|
|
72
|
+
.webassets-cache
|
|
73
|
+
|
|
74
|
+
# Scrapy stuff:
|
|
75
|
+
.scrapy
|
|
76
|
+
|
|
77
|
+
# Sphinx documentation
|
|
78
|
+
docs/_build/
|
|
79
|
+
|
|
80
|
+
# PyBuilder
|
|
81
|
+
.pybuilder/
|
|
82
|
+
target/
|
|
83
|
+
|
|
84
|
+
# Jupyter Notebook
|
|
85
|
+
.ipynb_checkpoints
|
|
86
|
+
|
|
87
|
+
# IPython
|
|
88
|
+
profile_default/
|
|
89
|
+
ipython_config.py
|
|
90
|
+
|
|
91
|
+
# pyenv
|
|
92
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
93
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
94
|
+
# .python-version
|
|
95
|
+
|
|
96
|
+
# pipenv
|
|
97
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
98
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
99
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
100
|
+
# install all needed dependencies.
|
|
101
|
+
#Pipfile.lock
|
|
102
|
+
|
|
103
|
+
# UV
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
#uv.lock
|
|
108
|
+
|
|
109
|
+
# poetry
|
|
110
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
111
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
112
|
+
# commonly ignored for libraries.
|
|
113
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
114
|
+
#poetry.lock
|
|
115
|
+
#poetry.toml
|
|
116
|
+
|
|
117
|
+
# pdm
|
|
118
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
119
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
120
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
121
|
+
#pdm.lock
|
|
122
|
+
#pdm.toml
|
|
123
|
+
.pdm-python
|
|
124
|
+
.pdm-build/
|
|
125
|
+
|
|
126
|
+
# pixi
|
|
127
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
128
|
+
#pixi.lock
|
|
129
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
130
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
131
|
+
.pixi
|
|
132
|
+
|
|
133
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
134
|
+
__pypackages__/
|
|
135
|
+
|
|
136
|
+
# Celery stuff
|
|
137
|
+
celerybeat-schedule
|
|
138
|
+
celerybeat.pid
|
|
139
|
+
|
|
140
|
+
# SageMath parsed files
|
|
141
|
+
*.sage.py
|
|
142
|
+
|
|
143
|
+
# Environments
|
|
144
|
+
.env
|
|
145
|
+
.envrc
|
|
146
|
+
.venv
|
|
147
|
+
env/
|
|
148
|
+
venv/
|
|
149
|
+
ENV/
|
|
150
|
+
env.bak/
|
|
151
|
+
venv.bak/
|
|
152
|
+
|
|
153
|
+
# Spyder project settings
|
|
154
|
+
.spyderproject
|
|
155
|
+
.spyproject
|
|
156
|
+
|
|
157
|
+
# Rope project settings
|
|
158
|
+
.ropeproject
|
|
159
|
+
|
|
160
|
+
# mkdocs documentation
|
|
161
|
+
/site
|
|
162
|
+
|
|
163
|
+
# mypy
|
|
164
|
+
.mypy_cache/
|
|
165
|
+
.dmypy.json
|
|
166
|
+
dmypy.json
|
|
167
|
+
|
|
168
|
+
# Pyre type checker
|
|
169
|
+
.pyre/
|
|
170
|
+
|
|
171
|
+
# pytype static type analyzer
|
|
172
|
+
.pytype/
|
|
173
|
+
|
|
174
|
+
# Cython debug symbols
|
|
175
|
+
cython_debug/
|
|
176
|
+
|
|
177
|
+
# PyCharm
|
|
178
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
179
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
180
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
181
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
182
|
+
#.idea/
|
|
183
|
+
|
|
184
|
+
# Abstra
|
|
185
|
+
# Abstra is an AI-powered process automation framework.
|
|
186
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
187
|
+
# Learn more at https://abstra.io/docs
|
|
188
|
+
.abstra/
|
|
189
|
+
|
|
190
|
+
# Visual Studio Code
|
|
191
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
192
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
193
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
194
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
195
|
+
# .vscode/
|
|
196
|
+
|
|
197
|
+
# Ruff stuff:
|
|
198
|
+
.ruff_cache/
|
|
199
|
+
|
|
200
|
+
# PyPI configuration file
|
|
201
|
+
.pypirc
|
|
202
|
+
|
|
203
|
+
# Marimo
|
|
204
|
+
marimo/_static/
|
|
205
|
+
marimo/_lsp/
|
|
206
|
+
__marimo__/
|
|
207
|
+
|
|
208
|
+
# Streamlit
|
|
209
|
+
.streamlit/secrets.toml
|
|
210
|
+
settings.local.json
|
|
211
|
+
.db/
|
tdxquant-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## 项目概述
|
|
6
|
+
|
|
7
|
+
`tdx-api`(包名 `tdx_api`,主类 `TdxAPI`)是通达信量化(TdxQuant)的 HTTP SDK。**不经过任何中间网关、DLL 或 tqcenter.py**——直接 `POST http://127.0.0.1:17709/`(通达信客户端原生监听端口),由 SDK 内部完成字段重命名与 `pandas.DataFrame` 封装。
|
|
8
|
+
|
|
9
|
+
> 历史上项目曾采用"FastAPI 网关 + tqcenter DLL"双层架构,已删除。`docs/superpowers/specs/2026-06-13-tdx-quant-sdk-design.md` 第三节的网关描述是历史设计,**现状以本文件与 `README.md` 为准**。
|
|
10
|
+
|
|
11
|
+
## 依赖文档
|
|
12
|
+
通达信量化相关文档位置 : ../../docs/TdxQuant_doc
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## 常用命令
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv sync # 安装依赖(用 .venv,禁止直接动全局 Python)
|
|
20
|
+
uv run pytest # 单元测试(字段血缘契约 + DataFrame 拼装,不依赖网络)
|
|
21
|
+
uv run pytest --runintegration # 集成测试(需通达信客户端在线监听 17709)
|
|
22
|
+
uv run pytest tests/test_schema.py::test_kline_lineage # 跑单个测试
|
|
23
|
+
uv run pytest -k snapshot # 按关键字筛选
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
集成测试默认跳过,必须显式加 `--runintegration` 才运行(见 `tests/conftest.py`)。
|
|
27
|
+
|
|
28
|
+
## 架构要点(big picture)
|
|
29
|
+
|
|
30
|
+
### 1. HTTP 协议约定
|
|
31
|
+
|
|
32
|
+
- 请求体:`{"id": 1, "method": "<tqcenter 方法名>", "params": {...}}`,响应体:`{"id": 1, "result": {...}}`。
|
|
33
|
+
- `method` 是 tqcenter 的底层函数名(如 `get_market_data` / `get_market_snapshot`),**不是** SDK 的方法名。
|
|
34
|
+
- `result.ErrorId != "0"` 时抛 `TdxQuantError(message, error_id)`;网络层错误抛 `TdxQuantConnectionError`。
|
|
35
|
+
- 客户端强制 `trust_env=False`,绕过系统代理(Clash/V2Ray 会劫持 localhost 导致 502)。
|
|
36
|
+
|
|
37
|
+
### 2. 组合式 mixin 架构
|
|
38
|
+
|
|
39
|
+
`TdxAPI` 通过多继承组合 5 个 mixin + `_ClientBase`(顺序见 `tdx_api/__init__.py`):
|
|
40
|
+
- `_ClientBase`(`client.py`)——HTTP 调用 + DataFrame 拼装工具,是唯一持有 HTTP 状态的基类。
|
|
41
|
+
- `MarketMixin` / `FinancialMixin` / `SectorMixin` / `InstrumentMixin` / `CalendarMixin`——纯业务接口,只调用 `self._call(...)` 和 `self._<拼装工具>(...)`。
|
|
42
|
+
|
|
43
|
+
新增数据接口的做法:在对应 mixin 加方法,调用 `_call` + 已有的拼装工具;若返回结构特殊,在 `_ClientBase` 加一个 `_xxx_to_df` 解析器。
|
|
44
|
+
|
|
45
|
+
### 3. 字段血缘:schema.py 是唯一真实来源
|
|
46
|
+
|
|
47
|
+
`tdx_api/schema.py` 中的 `*_FIELD_MAP`(`KLINE_FIELD_MAP` / `SNAPSHOT_FIELD_MAP` / `STOCK_INFO_FIELD_MAP` / `DIVIDEND_FIELD_MAP` / `CB_FIELD_MAP` / `ETF_FIELD_MAP` / `IPO_FIELD_MAP`)定义了 tqcenter 原字段 → SDK 规范字段(snake_case)的映射。
|
|
48
|
+
|
|
49
|
+
- **改映射必须三处同步**:`schema.py` 的 map → `tests/test_schema.py` 的血缘断言 → `docs/field_lineage.md` 的文档表。`test_schema.py` 是契约测试,锁住字段血缘不漂移,所有新字段断言为合法 snake_case。
|
|
50
|
+
- 未命中映射的原字段:**转小写保留**(不丢弃、不报错)。
|
|
51
|
+
- 专业财务/交易数据编码字段(`FNxxx` / `GPx` / `BKx` / `SCx` / `GOx`)无通用金融命名,一律转小写保留(`Fn193` → `fn193`)。
|
|
52
|
+
|
|
53
|
+
### 4. 日期与枚举归一化(enums.py)
|
|
54
|
+
|
|
55
|
+
- 所有对外日期参数经 `validate_date` 校验,严格 `YYYYMMDD`(分钟线 `YYYYMMDDHHMMSS`);空串/None 视为"不限制"。
|
|
56
|
+
- `Freq` / `Adjust` 用 SDK 友好写法(`daily` / `qfq`),内部经 `freq_to_period` / `adjust_to_dividend` 转成 tqcenter 的 `period`(`1d`)/ `dividend_type`(`front`)。
|
|
57
|
+
|
|
58
|
+
### 5. 底层参数名陷阱
|
|
59
|
+
|
|
60
|
+
不同业务接口的"字段筛选"参数名不同,SDK 对外统一叫 `fields`,但传给 `_call` 时要换成底层名:
|
|
61
|
+
- 行情类(`get_market_data` / `get_market_snapshot` / `get_stock_info`)→ `field_list`
|
|
62
|
+
- **财务/交易数据类**(`get_financial_data` / `get_gpjy_value` / `get_bkjy_value` / `get_scjy_value` / `get_gp_one_data`)→ `table_list`
|
|
63
|
+
|
|
64
|
+
`get_financial` 的底层 `end_time` 必填,`end_date` 留空时 SDK 自动取当天。
|
|
65
|
+
|
|
66
|
+
### 6. DataFrame 拼装工具(_ClientBase)
|
|
67
|
+
|
|
68
|
+
结果形态决定用哪个解析器:
|
|
69
|
+
- `_build_kline`:`result.Value.{stock}.{field:[list]}` → OHLCV 长表(行=时间×证券,列含 `datetime, code, open...`)。
|
|
70
|
+
- `_stock_value_to_df`:`result.Value.{stock:{field:[list]}}` → 财务长表,编码字段转小写。
|
|
71
|
+
- `_flat_value_to_df`:`result.Value` 为扁平 dict / `{field:[list]}` / list。
|
|
72
|
+
- `_dict_to_row` + `_rows_to_df`:单证券 dict → 一行(自动转数值、过滤 `ErrorId`/`Error`/`run_id` 元字段)。
|
|
73
|
+
- `_list_to_df`:str 列表→单列 code;dict 列表→自动成表。
|
|
74
|
+
|
|
75
|
+
`_maybe_numeric` 会尝试转数值类型,但**保留 list/dict 单元格**(五档盘口 bid_prices 等不能被压平)。
|
|
76
|
+
|
|
77
|
+
### 7. get_snapshot 并发
|
|
78
|
+
|
|
79
|
+
`get_snapshot` 传入多个代码时用 `ThreadPoolExecutor` 并发(默认 `max_workers=16`),httpx.Client 线程安全复用。**通达信服务端并行上限约 12~16**,超过 ~20 会因排队变慢,不要盲目调大并发。
|
|
80
|
+
|
|
81
|
+
## 测试约定
|
|
82
|
+
|
|
83
|
+
- 单元测试(`test_client_unit.py`)用 `TdxAPI.__new__(TdxAPI)` 跳过 HTTP 初始化,只测纯数据拼装方法——新增拼装工具时按此模式补测。
|
|
84
|
+
- 集成测试(`test_integration.py`)顶部 `pytestmark = pytest.mark.integration`,整个模块默认跳过。
|
|
85
|
+
|
|
86
|
+
## 约定与注意事项
|
|
87
|
+
|
|
88
|
+
- 所有代码注释、docstring、commit message 使用**中文**;对外对话也用中文。
|
|
89
|
+
- 不要创建未经声明的英文文件名(专业术语如 API/SDK/HTTP 除外)。
|
|
90
|
+
- 数据接口统一返回 `DataFrame`;缓存/下载类(`refresh_cache` / `refresh_kline` / `download_file`)返回 dict。
|
|
91
|
+
- Python ≥ 3.13;依赖走清华 PyPI 镜像(`pyproject.toml` 的 `[[tool.uv.index]]`)。
|
|
92
|
+
- 证券代码格式:6 位 + 市场后缀(`000001.SZ` / `600519.SH` / `.BJ` / `.JJ`)。
|
tdxquant-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tdxquant
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 通达信量化(TdxQuant) HTTP SDK —— 统一返回 DataFrame,字段金融规范化(snake_case)
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
|
+
Requires-Dist: httpx>=0.27
|
|
7
|
+
Requires-Dist: orjson>=3.11.9
|
|
8
|
+
Requires-Dist: pandas>=2.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# tdx-api
|
|
12
|
+
|
|
13
|
+
通达信量化(TdxQuant)**HTTP SDK** —— 直接调用通达信客户端官方 HTTP 接口(`POST http://127.0.0.1:17709/`),统一返回 `pandas.DataFrame`,字段重命名为金融行业规范的 **snake_case**。
|
|
14
|
+
|
|
15
|
+
## 工作方式
|
|
16
|
+
|
|
17
|
+
通达信量化客户端原生提供 HTTP 调用方式(无需 tqcenter / DLL / 自建网关):
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
你的代码(SDK) ──HTTP/JSON──► 通达信客户端(127.0.0.1:17709)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
1. 启动支持 TQ 的通达信客户端(它会监听 `127.0.0.1:17709`)
|
|
24
|
+
2. SDK 直接 POST 调用,字段重命名 + DataFrame 封装在 SDK 内完成
|
|
25
|
+
|
|
26
|
+
> 请求格式:`{"id":1, "method":"<tqcenter方法名>", "params":{...}}`,`method` 为 tqcenter 函数名,`params` 为底层参数名。
|
|
27
|
+
|
|
28
|
+
## 安装
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv sync # 本地开发
|
|
32
|
+
# 或 pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> 需要 Python ≥ 3.13、通达信金融终端(量化模拟版 / 专业研究版等支持 TQ 策略的版本)。
|
|
36
|
+
|
|
37
|
+
## 快速开始
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from tdx_api import TdxAPI
|
|
41
|
+
|
|
42
|
+
api = TdxAPI() # 默认 http://127.0.0.1:17709,需通达信客户端在线
|
|
43
|
+
|
|
44
|
+
# K线(OHLCV 长表)
|
|
45
|
+
df = api.get_kline("000001.SZ", freq="daily", adjust="qfq", start_date="20260101")
|
|
46
|
+
# 实时快照
|
|
47
|
+
snap = api.get_snapshot("000001.SZ")
|
|
48
|
+
# 股票 / 板块 / ETF
|
|
49
|
+
api.get_stock_list() # 所有分类合并(带 market/category 列)
|
|
50
|
+
api.get_sector_list()
|
|
51
|
+
api.get_track_etf("000300.SH")
|
|
52
|
+
# 财务
|
|
53
|
+
api.get_financial("600519.SH", fields=["Fn193","Fn194"], start_date="20240101")
|
|
54
|
+
# 交易日历
|
|
55
|
+
api.get_trading_calendar("20260101", "20260613")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
从别的机器调用:`TdxAPI(base_url="http://通达信机器IP:17709")`。
|
|
59
|
+
|
|
60
|
+
## 接口总览
|
|
61
|
+
|
|
62
|
+
| 类别 | 方法 | 说明 |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| 行情 | `get_kline` | K线(OHLCV 长表) |
|
|
65
|
+
| | `get_snapshot` | 实时快照(五档) |
|
|
66
|
+
| | `get_instrument_info` / `get_more_info` | 基本信息 |
|
|
67
|
+
| | `get_dividend_factors` | 分红送配 |
|
|
68
|
+
| 财务 | `get_financial` / `get_financial_by_date` | 专业财务(FNxxx) |
|
|
69
|
+
| | `get_stock_trade_data(_by_date)` | 股票交易(GPx) |
|
|
70
|
+
| | `get_sector_trade_data(_by_date)` | 板块交易(BKx) |
|
|
71
|
+
| | `get_market_trade_data(_by_date)` | 市场交易(SCx) |
|
|
72
|
+
| | `get_stock_single_data` | 单点数据(GOx) |
|
|
73
|
+
| | `get_share_capital(_by_date)` | 股本数据 |
|
|
74
|
+
| 板块 | `get_stock_list` | 分类成分股(market 不传返回全部,带 market/category 列) |
|
|
75
|
+
| | `get_sector_list` / `get_user_sectors` | 板块列表 |
|
|
76
|
+
| | `get_sector_stocks` | 板块成分股 |
|
|
77
|
+
| 证券 | `get_convertible_bond` | 可转债 |
|
|
78
|
+
| | `get_ipo_info` | 新股/新债申购 |
|
|
79
|
+
| | `get_track_etf` | 跟踪指数的 ETF |
|
|
80
|
+
| 日历 | `get_trading_dates` / `get_trading_calendar` | 交易日 |
|
|
81
|
+
|
|
82
|
+
> 交易类(`order_stock`)按需求不做。完整参数与字段说明见 [`docs/api_reference.md`](docs/api_reference.md)。
|
|
83
|
+
|
|
84
|
+
## 字段命名规范
|
|
85
|
+
|
|
86
|
+
- 全部 **snake_case 小写**,采用金融行业惯例(OHLCV / bid-ask / nav / pct_chg)。
|
|
87
|
+
- 原字段 → 新字段完整血缘见 [`docs/field_lineage.md`](docs/field_lineage.md)。
|
|
88
|
+
- 通达信专业编码字段(`FNxxx`/`GPx` 等)保留转小写,需对照通达信字段手册。
|
|
89
|
+
|
|
90
|
+
代码格式:`000001.SZ` / `600519.SH`(6 位 + 市场后缀);频率 `daily/5min/...`;
|
|
91
|
+
复权 `none/qfq/hfq`;日期严格 `YYYYMMDD`(区间用 `start_date`/`end_date`,按日期点用 `date`)。
|
|
92
|
+
|
|
93
|
+
## 测试
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
uv run pytest # 单元测试(字段血缘契约 + 拼装逻辑)
|
|
97
|
+
uv run pytest --runintegration # 集成测试(需通达信客户端在线)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 项目结构
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
tdx_api/
|
|
104
|
+
├── client.py # HTTP 客户端(POST 17709)+ DataFrame 拼装
|
|
105
|
+
├── schema.py # 字段血缘映射表(唯一真实来源)
|
|
106
|
+
├── enums.py # Freq / Adjust 枚举 + validate_date 日期校验
|
|
107
|
+
├── exceptions.py # 异常
|
|
108
|
+
└── api/ # 各业务接口(mixin)
|
|
109
|
+
├── market.py financial.py sector.py instrument.py calendar.py
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 常见问题
|
|
113
|
+
|
|
114
|
+
- **`server return none` / 连接失败**:确认通达信客户端已启动并登录行情;SDK 默认连 `127.0.0.1:17709`。
|
|
115
|
+
- **`502 Bad Gateway`**:本机代理(Clash/V2Ray)劫持 localhost 请求。SDK 已默认 `trust_env=False` 直连,若仍异常请关闭代理。
|
|
116
|
+
- **财务/专业数据为空**:需先在通达信客户端下载对应盘后/专业财务数据。
|
|
117
|
+
- **`get_financial` 报 end_time 缺失**:底层要求结束日期,`end_date` 留空时 SDK 自动取当天。
|
tdxquant-0.1.0/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# tdx-api
|
|
2
|
+
|
|
3
|
+
通达信量化(TdxQuant)**HTTP SDK** —— 直接调用通达信客户端官方 HTTP 接口(`POST http://127.0.0.1:17709/`),统一返回 `pandas.DataFrame`,字段重命名为金融行业规范的 **snake_case**。
|
|
4
|
+
|
|
5
|
+
## 工作方式
|
|
6
|
+
|
|
7
|
+
通达信量化客户端原生提供 HTTP 调用方式(无需 tqcenter / DLL / 自建网关):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
你的代码(SDK) ──HTTP/JSON──► 通达信客户端(127.0.0.1:17709)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
1. 启动支持 TQ 的通达信客户端(它会监听 `127.0.0.1:17709`)
|
|
14
|
+
2. SDK 直接 POST 调用,字段重命名 + DataFrame 封装在 SDK 内完成
|
|
15
|
+
|
|
16
|
+
> 请求格式:`{"id":1, "method":"<tqcenter方法名>", "params":{...}}`,`method` 为 tqcenter 函数名,`params` 为底层参数名。
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv sync # 本地开发
|
|
22
|
+
# 或 pip install -e .
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> 需要 Python ≥ 3.13、通达信金融终端(量化模拟版 / 专业研究版等支持 TQ 策略的版本)。
|
|
26
|
+
|
|
27
|
+
## 快速开始
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from tdx_api import TdxAPI
|
|
31
|
+
|
|
32
|
+
api = TdxAPI() # 默认 http://127.0.0.1:17709,需通达信客户端在线
|
|
33
|
+
|
|
34
|
+
# K线(OHLCV 长表)
|
|
35
|
+
df = api.get_kline("000001.SZ", freq="daily", adjust="qfq", start_date="20260101")
|
|
36
|
+
# 实时快照
|
|
37
|
+
snap = api.get_snapshot("000001.SZ")
|
|
38
|
+
# 股票 / 板块 / ETF
|
|
39
|
+
api.get_stock_list() # 所有分类合并(带 market/category 列)
|
|
40
|
+
api.get_sector_list()
|
|
41
|
+
api.get_track_etf("000300.SH")
|
|
42
|
+
# 财务
|
|
43
|
+
api.get_financial("600519.SH", fields=["Fn193","Fn194"], start_date="20240101")
|
|
44
|
+
# 交易日历
|
|
45
|
+
api.get_trading_calendar("20260101", "20260613")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
从别的机器调用:`TdxAPI(base_url="http://通达信机器IP:17709")`。
|
|
49
|
+
|
|
50
|
+
## 接口总览
|
|
51
|
+
|
|
52
|
+
| 类别 | 方法 | 说明 |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| 行情 | `get_kline` | K线(OHLCV 长表) |
|
|
55
|
+
| | `get_snapshot` | 实时快照(五档) |
|
|
56
|
+
| | `get_instrument_info` / `get_more_info` | 基本信息 |
|
|
57
|
+
| | `get_dividend_factors` | 分红送配 |
|
|
58
|
+
| 财务 | `get_financial` / `get_financial_by_date` | 专业财务(FNxxx) |
|
|
59
|
+
| | `get_stock_trade_data(_by_date)` | 股票交易(GPx) |
|
|
60
|
+
| | `get_sector_trade_data(_by_date)` | 板块交易(BKx) |
|
|
61
|
+
| | `get_market_trade_data(_by_date)` | 市场交易(SCx) |
|
|
62
|
+
| | `get_stock_single_data` | 单点数据(GOx) |
|
|
63
|
+
| | `get_share_capital(_by_date)` | 股本数据 |
|
|
64
|
+
| 板块 | `get_stock_list` | 分类成分股(market 不传返回全部,带 market/category 列) |
|
|
65
|
+
| | `get_sector_list` / `get_user_sectors` | 板块列表 |
|
|
66
|
+
| | `get_sector_stocks` | 板块成分股 |
|
|
67
|
+
| 证券 | `get_convertible_bond` | 可转债 |
|
|
68
|
+
| | `get_ipo_info` | 新股/新债申购 |
|
|
69
|
+
| | `get_track_etf` | 跟踪指数的 ETF |
|
|
70
|
+
| 日历 | `get_trading_dates` / `get_trading_calendar` | 交易日 |
|
|
71
|
+
|
|
72
|
+
> 交易类(`order_stock`)按需求不做。完整参数与字段说明见 [`docs/api_reference.md`](docs/api_reference.md)。
|
|
73
|
+
|
|
74
|
+
## 字段命名规范
|
|
75
|
+
|
|
76
|
+
- 全部 **snake_case 小写**,采用金融行业惯例(OHLCV / bid-ask / nav / pct_chg)。
|
|
77
|
+
- 原字段 → 新字段完整血缘见 [`docs/field_lineage.md`](docs/field_lineage.md)。
|
|
78
|
+
- 通达信专业编码字段(`FNxxx`/`GPx` 等)保留转小写,需对照通达信字段手册。
|
|
79
|
+
|
|
80
|
+
代码格式:`000001.SZ` / `600519.SH`(6 位 + 市场后缀);频率 `daily/5min/...`;
|
|
81
|
+
复权 `none/qfq/hfq`;日期严格 `YYYYMMDD`(区间用 `start_date`/`end_date`,按日期点用 `date`)。
|
|
82
|
+
|
|
83
|
+
## 测试
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv run pytest # 单元测试(字段血缘契约 + 拼装逻辑)
|
|
87
|
+
uv run pytest --runintegration # 集成测试(需通达信客户端在线)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 项目结构
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
tdx_api/
|
|
94
|
+
├── client.py # HTTP 客户端(POST 17709)+ DataFrame 拼装
|
|
95
|
+
├── schema.py # 字段血缘映射表(唯一真实来源)
|
|
96
|
+
├── enums.py # Freq / Adjust 枚举 + validate_date 日期校验
|
|
97
|
+
├── exceptions.py # 异常
|
|
98
|
+
└── api/ # 各业务接口(mixin)
|
|
99
|
+
├── market.py financial.py sector.py instrument.py calendar.py
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 常见问题
|
|
103
|
+
|
|
104
|
+
- **`server return none` / 连接失败**:确认通达信客户端已启动并登录行情;SDK 默认连 `127.0.0.1:17709`。
|
|
105
|
+
- **`502 Bad Gateway`**:本机代理(Clash/V2Ray)劫持 localhost 请求。SDK 已默认 `trust_env=False` 直连,若仍异常请关闭代理。
|
|
106
|
+
- **财务/专业数据为空**:需先在通达信客户端下载对应盘后/专业财务数据。
|
|
107
|
+
- **`get_financial` 报 end_time 缺失**:底层要求结束日期,`end_date` 留空时 SDK 自动取当天。
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# 接口参考(tdx_api.TdxAPI)
|
|
2
|
+
|
|
3
|
+
> 字段血缘见 [`field_lineage.md`](field_lineage.md)。所有数据接口返回 `pandas.DataFrame`;
|
|
4
|
+
> 缓存/下载类操作返回 `dict`。
|
|
5
|
+
|
|
6
|
+
## 构造
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
TdxAPI(base_url="http://127.0.0.1:17709", timeout=120.0)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
直连通达信客户端官方 HTTP 端口(需客户端在线)。支持 `with TdxAPI(...) as api:` 上下文。
|
|
13
|
+
`api.health()` 返回连通状态 dict。
|
|
14
|
+
|
|
15
|
+
## 代码与参数约定
|
|
16
|
+
|
|
17
|
+
- **证券代码**:`000001.SZ` / `600519.SH` / `000300.SH`(6 位 + 市场后缀)。
|
|
18
|
+
- **频率 `freq`**:`1min / 5min / 15min / 30min / 60min / daily / weekly / monthly`。
|
|
19
|
+
- **复权 `adjust`**:`none` 不复权 / `qfq` 前复权 / `hfq` 后复权。
|
|
20
|
+
- **日期**:统一字符串 `YYYYMMDD`(如 `20260613`),分钟线可 `YYYYMMDDHHMMSS`。严格校验,格式不符报错。区间型参数用 `start_date` / `end_date`,按日期点型用 `date`。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 行情类
|
|
25
|
+
|
|
26
|
+
### `get_kline(code, freq="daily", adjust="none", start_date="", end_date="", fields=None, fill_data=True)`
|
|
27
|
+
|
|
28
|
+
K线数据,返回 OHLCV 长表。
|
|
29
|
+
|
|
30
|
+
| 参数 | 说明 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `code` | 证券代码或列表 |
|
|
33
|
+
| `freq` | 频率 |
|
|
34
|
+
| `adjust` | 复权类型 |
|
|
35
|
+
| `start_date` / `end_date` | 日期区间 `YYYYMMDD`(控制返回范围) |
|
|
36
|
+
| `fields` | 返回字段筛选(原字段名) |
|
|
37
|
+
| `fill_data` | 是否填充缺失 |
|
|
38
|
+
|
|
39
|
+
返回列:`datetime, code, open, high, low, close, volume, amount, forward_factor, open_interest`
|
|
40
|
+
|
|
41
|
+
### `get_snapshot(code, fields=None, max_workers=16)`
|
|
42
|
+
|
|
43
|
+
实时快照,索引 `code`。返回五档买卖、昨收/现价/涨速等(见字段血缘快照表)。
|
|
44
|
+
|
|
45
|
+
多个代码默认走线程池并发(复用同一 `httpx.Client`):单次约 3.5ms,全市场 5500+ 只约 **5s**(串行约 19s)。
|
|
46
|
+
`max_workers=None` 或 `1` 退回串行;注意通达信客户端服务端并行上限约 12~16,超过 20 会因排队变慢。
|
|
47
|
+
|
|
48
|
+
### `get_instrument_info(code, fields=None)` / `get_more_info(code, fields=None)`
|
|
49
|
+
|
|
50
|
+
证券基本信息 / 更多信息,索引 `code`。
|
|
51
|
+
|
|
52
|
+
### `get_dividend_factors(code, start_date="", end_date="")`
|
|
53
|
+
|
|
54
|
+
分红送配,index 为除权除息日。列:`div_type, cash_dividend, rights_price, share_bonus, rights_issue`。
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 财务类
|
|
59
|
+
|
|
60
|
+
> 字段为通达信编码(`FNxxx`/`GPx`/`BKx`/`SCx`/`GOx`),SDK 转小写保留;返回长表带 `code` 列。
|
|
61
|
+
> 专业财务需客户端先下载专业财务数据。
|
|
62
|
+
|
|
63
|
+
### `get_financial(stock_list, fields=None, start_date="", end_date="", report_type="report_time")`
|
|
64
|
+
专业财务。`report_type`: `report_time`(截止日) / `announce_time`(公告日)。
|
|
65
|
+
|
|
66
|
+
### `get_financial_by_date(stock_list, fields=None, date="")`
|
|
67
|
+
指定日期专业财务(`date` 为报告期 `YYYYMMDD`)。
|
|
68
|
+
|
|
69
|
+
### `get_stock_trade_data(stock_list, fields=None, start_date="", end_date="")` / `get_stock_trade_data_by_date(stock_list, fields=None, date="")`
|
|
70
|
+
股票交易数据(`GPx`)。
|
|
71
|
+
|
|
72
|
+
### `get_sector_trade_data(...)` / `get_sector_trade_data_by_date(...)`
|
|
73
|
+
板块交易数据(`BKx`),参数同上(区间用 `start_date`/`end_date`,按日期用 `date`)。
|
|
74
|
+
|
|
75
|
+
### `get_market_trade_data(fields=None, start_date="", end_date="")` / `get_market_trade_data_by_date(fields=None, date="")`
|
|
76
|
+
市场交易数据(`SCx`,无个股维度)。
|
|
77
|
+
|
|
78
|
+
### `get_stock_single_data(stock_list, fields=None)`
|
|
79
|
+
单点数据(`GOx`,非序列)。
|
|
80
|
+
|
|
81
|
+
### `get_share_capital(code, date_list=None, count=1)` / `get_share_capital_by_date(code, start_date="", end_date="")`
|
|
82
|
+
股本数据(总股本 / 流通股本等)。
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 板块 / 分类
|
|
87
|
+
|
|
88
|
+
### `get_stock_list(market=None)`
|
|
89
|
+
分类成分股,返回 `code, market, category` 三列。`market` 不传则遍历所有主要分类(所有A股 / 沪深主板 / 沪深300 / 中证500 / 中证1000 / ETF / 可转债 / 创业板 / 科创板 / 北交所等)合并返回,同一股票属于多个分类时出现多行;传具体值(如 `"5"` / `"23"`)只返回该分类。`category` 为中文分类名,完整映射见 `sector.py` 的 `STOCK_CATEGORY`。
|
|
90
|
+
|
|
91
|
+
### `get_sector_list(list_type=0)`
|
|
92
|
+
全部板块,列 `code, name`。
|
|
93
|
+
|
|
94
|
+
### `get_user_sectors()`
|
|
95
|
+
用户自定义板块,列 `code, name`。
|
|
96
|
+
|
|
97
|
+
### `get_sector_stocks(block_code, block_type=0, list_type=0)`
|
|
98
|
+
板块成分股,返回单列 `code`。`block_code` 可为板块代码(`880081.SH`)或名称(`钛金属`);
|
|
99
|
+
`block_type=1` 时传入自定义板块简称。
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 证券
|
|
104
|
+
|
|
105
|
+
### `get_convertible_bond(code, fields=None)`
|
|
106
|
+
可转债信息。列:`bond_code, underlying_code, conversion_price, coupon_rate, ...`
|
|
107
|
+
|
|
108
|
+
### `get_ipo_info(ipo_type=0, ipo_date=0)`
|
|
109
|
+
新股/新债申购。`ipo_type`: 0 全部 / 1 新债 / 2 新股;`ipo_date`: 0 今天 / 1 今天及以后。
|
|
110
|
+
列:`code, name, subscribe_date, subscribe_price, subscribe_code, max_subscribe, issue_pe`。
|
|
111
|
+
|
|
112
|
+
### `get_track_etf(zs_code)`
|
|
113
|
+
跟踪指定指数的 ETF。列:`code, name, last_price, pre_close, iopv, total_share, scale`。
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 日历 / 缓存
|
|
118
|
+
|
|
119
|
+
### `get_trading_dates(market="SH", start_date="", end_date="", count=-1)`
|
|
120
|
+
交易日列表,列 `date`。需客户端下载上证指数(999999)盘后数据。
|
|
121
|
+
|
|
122
|
+
### `get_trading_calendar(start_date, end_date, market="SH")`
|
|
123
|
+
交易日历,列 `date`。`market` 默认 SH(上交所)。
|
|
124
|
+
|
|
125
|
+
### `refresh_cache(market="AG", force=False) -> dict`
|
|
126
|
+
刷新行情缓存。
|
|
127
|
+
|
|
128
|
+
### `refresh_kline(stock_list, period="") -> dict`
|
|
129
|
+
缓存历史 K线(仅 1m/5m/1d)。
|
|
130
|
+
|
|
131
|
+
### `download_file(code, down_time="", down_type=1) -> dict`
|
|
132
|
+
下载十大股东(`down_type=1`)/ ETF 申赎清单(`down_type=2`)。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 异常
|
|
137
|
+
|
|
138
|
+
- `TdxQuantError`:业务错误(网关返回 `error_id != 0`),含 `.error_id` / `.error_msg`。
|
|
139
|
+
- `TdxQuantConnectionError`:网络/连接错误。
|