qmt-sdk 0.3.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.
Files changed (47) hide show
  1. qmt_sdk-0.3.0/LICENSE +192 -0
  2. qmt_sdk-0.3.0/MANIFEST.in +3 -0
  3. qmt_sdk-0.3.0/PKG-INFO +204 -0
  4. qmt_sdk-0.3.0/README.md +184 -0
  5. qmt_sdk-0.3.0/pyproject.toml +42 -0
  6. qmt_sdk-0.3.0/qmt_strategy/XTQUANT_COMPAT_BRIDGE.py +811 -0
  7. qmt_sdk-0.3.0/qmt_strategy/XTQUANT_COMPAT_BRIDGE_LAUNCHER.py +17 -0
  8. qmt_sdk-0.3.0/setup.cfg +4 -0
  9. qmt_sdk-0.3.0/src/qmt_sdk/__init__.py +29 -0
  10. qmt_sdk-0.3.0/src/qmt_sdk/api_surface.py +48 -0
  11. qmt_sdk-0.3.0/src/qmt_sdk/backends/__init__.py +4 -0
  12. qmt_sdk-0.3.0/src/qmt_sdk/backends/miniqmt.py +11 -0
  13. qmt_sdk-0.3.0/src/qmt_sdk/backends/qmt.py +27 -0
  14. qmt_sdk-0.3.0/src/qmt_sdk/bridge/__init__.py +6 -0
  15. qmt_sdk-0.3.0/src/qmt_sdk/bridge/client.py +179 -0
  16. qmt_sdk-0.3.0/src/qmt_sdk/bridge/config.py +38 -0
  17. qmt_sdk-0.3.0/src/qmt_sdk/bridge/exceptions.py +26 -0
  18. qmt_sdk-0.3.0/src/qmt_sdk/bridge/protocol.py +20 -0
  19. qmt_sdk-0.3.0/src/qmt_sdk/client.py +43 -0
  20. qmt_sdk-0.3.0/src/qmt_sdk/data.py +624 -0
  21. qmt_sdk-0.3.0/src/qmt_sdk/financial.py +23 -0
  22. qmt_sdk-0.3.0/src/qmt_sdk/instruments.py +72 -0
  23. qmt_sdk-0.3.0/src/qmt_sdk/jobs.py +12 -0
  24. qmt_sdk-0.3.0/src/qmt_sdk/market.py +71 -0
  25. qmt_sdk-0.3.0/src/qmt_sdk/qmt.py +24 -0
  26. qmt_sdk-0.3.0/src/qmt_sdk.egg-info/PKG-INFO +204 -0
  27. qmt_sdk-0.3.0/src/qmt_sdk.egg-info/SOURCES.txt +45 -0
  28. qmt_sdk-0.3.0/src/qmt_sdk.egg-info/dependency_links.txt +1 -0
  29. qmt_sdk-0.3.0/src/qmt_sdk.egg-info/requires.txt +5 -0
  30. qmt_sdk-0.3.0/src/qmt_sdk.egg-info/top_level.txt +2 -0
  31. qmt_sdk-0.3.0/src/xtquant_compat/__init__.py +7 -0
  32. qmt_sdk-0.3.0/src/xtquant_compat/api_surface.py +48 -0
  33. qmt_sdk-0.3.0/src/xtquant_compat/client.py +16 -0
  34. qmt_sdk-0.3.0/src/xtquant_compat/config.py +5 -0
  35. qmt_sdk-0.3.0/src/xtquant_compat/exceptions.py +9 -0
  36. qmt_sdk-0.3.0/src/xtquant_compat/official_xtdata_api.json +2649 -0
  37. qmt_sdk-0.3.0/src/xtquant_compat/protocol.py +20 -0
  38. qmt_sdk-0.3.0/src/xtquant_compat/xtdata.py +595 -0
  39. qmt_sdk-0.3.0/tests/test_api_compatibility_document.py +40 -0
  40. qmt_sdk-0.3.0/tests/test_config.py +6 -0
  41. qmt_sdk-0.3.0/tests/test_daily_workflow_contract.py +56 -0
  42. qmt_sdk-0.3.0/tests/test_official_api_surface.py +20 -0
  43. qmt_sdk-0.3.0/tests/test_packaging.py +9 -0
  44. qmt_sdk-0.3.0/tests/test_protocol.py +9 -0
  45. qmt_sdk-0.3.0/tests/test_qmt_bridge.py +82 -0
  46. qmt_sdk-0.3.0/tests/test_qmt_sdk_facade.py +33 -0
  47. qmt_sdk-0.3.0/tests/test_xtdata.py +61 -0
qmt_sdk-0.3.0/LICENSE ADDED
@@ -0,0 +1,192 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ Copyright 2026 xtquant-compat contributors
181
+
182
+ Licensed under the Apache License, Version 2.0 (the "License");
183
+ you may not use this file except in compliance with the License.
184
+ You may obtain a copy of the License at
185
+
186
+ http://www.apache.org/licenses/LICENSE-2.0
187
+
188
+ Unless required by applicable law or agreed to in writing, software
189
+ distributed under the License is distributed on an "AS IS" BASIS,
190
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
191
+ See the License for the specific language governing permissions and
192
+ limitations under the License.
@@ -0,0 +1,3 @@
1
+ include qmt_strategy/*.py
2
+ include README.md
3
+ include LICENSE
qmt_sdk-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.4
2
+ Name: qmt-sdk
3
+ Version: 0.3.0
4
+ Summary: Unified QMT Python SDK with MiniQMT xtquant compatibility.
5
+ Author: qmt-sdk contributors
6
+ License: Apache-2.0
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: License :: OSI Approved :: Apache Software License
9
+ Classifier: Operating System :: Microsoft :: Windows
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Topic :: Office/Business :: Financial :: Investment
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: pandas>=1.5
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest>=7; extra == "dev"
18
+ Requires-Dist: ruff>=0.5; extra == "dev"
19
+ Dynamic: license-file
20
+
21
+ # qmt-sdk
22
+
23
+ `qmt-sdk` 是一个 QMT 外部调用 SDK。它通过运行在 QMT 内部的文件桥接,
24
+ 把 QMT 的查询和行情能力安全地暴露给外部 Python 程序;同时提供 `xtquant_compat`,
25
+ 用于适配 MiniQMT/`xtquant.xtdata` 的常用接口,帮助已有 MiniQMT 代码迁移到 QMT。
26
+
27
+ 项目当前以查询和行情为主,不包含下单、撤单、账户或持仓修改。文件桥接不依赖 QMT
28
+ Python 环境中的 Redis、ZeroMQ、`_socket`、`_ctypes` 或 pandas;外部 Python 环境负责
29
+ 安装 pandas 等数据处理依赖。
30
+
31
+ ## 为什么采用文件桥接
32
+
33
+ 不同券商提供的 QMT 版本,其内置 Python 运行环境并不完全相同。常见差异包括:
34
+
35
+ - 没有网络相关模块,例如 `_socket`,无法安装或使用 Redis、ZeroMQ 等通信库;
36
+ - 没有 `_ctypes`、pandas 或其他常用第三方依赖;
37
+ - Python 版本、模块搜索路径和启动方式不同;
38
+ - 策略运行环境受到白名单或沙箱限制,不能直接连接外部服务。
39
+
40
+ 如果把所有通信和数据处理都放进 QMT 内置 Python,代码就会被某个券商的运行环境绑定。
41
+ 文件桥接将 QMT 侧限制为“调用 `ContextInfo` 并读写文件”,把网络通信、数据处理和业务
42
+ 逻辑放到外部标准 Python 中。请求、响应和订阅事件通过带请求 ID 的文件交换,因此不依赖
43
+ QMT 是否带 Redis、是否允许网络连接,也不要求在 QMT 内安装第三方包。
44
+
45
+ 这种方式的代价是文件 I/O 和额外延迟,适合查询、行情同步、故障恢复和存量代码迁移;
46
+ 不定位为逐笔级高频交易通道。
47
+
48
+ ## 一、项目提供什么
49
+
50
+ ```text
51
+ 外部 Python 程序
52
+ ├─ qmt_sdk QMT 原生风格的统一客户端
53
+ └─ xtquant_compat MiniQMT/xtquant.xtdata 兼容层
54
+
55
+ 文件 bridge(运行在 QMT 策略中)
56
+
57
+ QMT ContextInfo
58
+ ```
59
+
60
+ `qmt_sdk` 尽量返回 QMT 原生结构;`xtquant_compat` 再将结果转换为存量 MiniQMT
61
+ 代码常用的结构。两者共用同一个文件 bridge 和请求队列,QMT API 始终在策略线程中串行执行。
62
+
63
+ ## 二、安装外部 Python 客户端
64
+
65
+ 不要把本项目安装到 QMT 自带的 Python。请使用外部 Python 3.8 或更高版本:
66
+
67
+ ```powershell
68
+ python -m venv .venv
69
+ .\.venv\Scripts\python.exe -m pip install -e ".[dev]"
70
+ ```
71
+
72
+ 如果只使用运行时,不需要开发依赖,可以执行:
73
+
74
+ ```powershell
75
+ .\.venv\Scripts\python.exe -m pip install -e .
76
+ ```
77
+
78
+ ## 三、在 QMT 中部署 bridge
79
+
80
+ 源码仓库的 `qmt_strategy` 目录以及安装包的模板目录都包含两个需要部署的文件:
81
+
82
+ - `XTQUANT_COMPAT_BRIDGE.py`:实际 bridge 实现;
83
+ - `XTQUANT_COMPAT_BRIDGE_LAUNCHER.py`:QMT 策略入口。
84
+
85
+ 安装步骤:
86
+
87
+ 1. 将 `qmt_strategy/XTQUANT_COMPAT_BRIDGE.py` 复制到 QMT Python 的搜索路径中。
88
+ 通常可以复制到 QMT 安装目录下的 `python` 目录;不要求使用某个固定盘符或目录名称。
89
+ 2. 在 QMT 策略管理器中新建一个策略,名称准确填写:
90
+
91
+ ```text
92
+ XTQUANT_COMPAT_BRIDGE_LAUNCHER
93
+ ```
94
+
95
+ 3. 打开仓库中的 `qmt_strategy/XTQUANT_COMPAT_BRIDGE_LAUNCHER.py`,将全部内容复制到该策略。
96
+ 4. 启动策略,确认日志出现类似:
97
+
98
+ ```text
99
+ [xtquant_compat] started root=... instance=...
100
+ [xtquant_compat] scheduled adjust interval=100nMilliSecond
101
+ ```
102
+
103
+ launcher 会自动从 QMT 的 `sys.path` 查找 `XTQUANT_COMPAT_BRIDGE.py`。如果 QMT 没有把
104
+ 复制目录加入搜索路径,可以设置环境变量 `XTQUANT_COMPAT_BRIDGE_FILE` 指向该文件。
105
+
106
+ 通过 PyPI 安装时,可以使用下面的命令定位模板目录,再从该目录复制两个文件:
107
+
108
+ ```powershell
109
+ python -c "import qmt_sdk; print(qmt_sdk.get_template_dir())"
110
+ ```
111
+
112
+ bridge 默认使用独立的数据目录;请求、响应、状态和订阅事件都会写入其中。不要把这个
113
+ 目录与其他实验 bridge 混用,也不要将其加入生产数据目录。
114
+
115
+ ## 四、外部程序调用
116
+
117
+ ### 使用 QMT 原生风格客户端
118
+
119
+ ```python
120
+ from qmt_sdk import QmtClient
121
+
122
+ client = QmtClient()
123
+ print(client.data.get_market_data_ex(
124
+ ["open", "high", "low", "close", "volume", "amount"],
125
+ ["000001.SZ"], "1d", "20260902", "20260902",
126
+ ))
127
+ ```
128
+
129
+ ### 迁移 MiniQMT/xtquant 存量代码
130
+
131
+ ```python
132
+ from xtquant_compat import xtdata
133
+
134
+ stocks = xtdata.get_stock_list_in_sector("沪深A股")
135
+ data = xtdata.get_market_data_ex(
136
+ ["open", "high", "low", "close", "volume", "amount"],
137
+ stocks[:10], "1d", "20260902", "20260902",
138
+ )
139
+ print(data)
140
+ ```
141
+
142
+ 订阅接口保持常见 MiniQMT 调用方式:
143
+
144
+ ```python
145
+ def on_quote(data):
146
+ print(data)
147
+
148
+ seq = xtdata.subscribe_quote("000001.SZ", period="tick", callback=on_quote)
149
+ # 不再需要时:
150
+ xtdata.unsubscribe_quote(seq)
151
+ ```
152
+
153
+ 默认 bridge 配置不适合时,可以显式设置目录和超时:
154
+
155
+ ```python
156
+ from xtquant_compat import configure
157
+
158
+ configure(root=r"<bridge-data-root>", timeout=120)
159
+ ```
160
+
161
+ ## 五、目前支持的能力
162
+
163
+ 下面是能力总览。`qmt_sdk` 提供 QMT 原生风格入口,`xtquant_compat` 提供 MiniQMT/`xtquant.xtdata`
164
+ 兼容入口;完整签名、实现状态、返回结构、逐字段差异和测试记录以
165
+ [API 兼容性文档](docs/xtdata-api-matrix.md) 为准。
166
+
167
+ | 能力分类 | 代表接口/功能 | `qmt_sdk` | `xtquant_compat` | 说明 |
168
+ |---|---|---|---|---|
169
+ | 行情与历史数据 | `get_market_data`、`get_market_data_ex`、`get_local_data`、`get_history_data` | 支持 | 支持 | 1d、1m、tick;下载与查询分开 |
170
+ | Tick 快照 | `get_full_tick` | 支持 | 支持 | 返回 QMT 原生或 MiniQMT 兼容结构 |
171
+ | 历史下载 | `download_history_data`、`download_history_data2` | 支持 | 支持 | 批量下载结果依赖 QMT 本地数据能力 |
172
+ | 实时订阅 | `subscribe_quote`、`subscribe_whole_quote`、`unsubscribe_quote` | 支持 | 支持 | 回调、事件持久化和取消订阅 |
173
+ | 标的与板块 | `get_stock_list_in_sector`、`get_instrument_detail*` | 支持 | 支持 | 股票、指数、合约等标的属性 |
174
+ | 交易日历与状态 | 交易日历、ST 状态、合约列表 | 支持 | 支持 | 返回结构按入口分别保持原生/兼容语义 |
175
+ | ETF、期权与指数 | ETF、期权、指数成分/权重、主力合约 | 支持 | 支持 | 具体接口以 API 文档为准 |
176
+ | 除权与计算 | 除权除息、BSM 价格、隐含波动率 | 支持 | 支持 | 查询或纯计算功能 |
177
+ | 财务与市场扩展 | `get_financial_data`、港股通、龙虎榜、北向资金 | 支持 | 支持 | 部分 QMT 环境的财务接口依赖 pandas |
178
+ | 财务扩展(暂不承诺数据) | `get_turnover_rate`、`get_raw_financial_data` | 已接入签名 | 已接入签名 | 当前环境缺少 pandas 时无法保证数据返回 |
179
+
180
+ 当前明确不在范围内:下单、撤单、交易回报、账户/持仓/资金修改,以及必须依赖厂商专有
181
+ DLL 或外部服务才能完成的功能。
182
+
183
+ ## 六、请求、订阅和可靠性
184
+
185
+ 外部请求可以并发提交,但同一个 QMT 实例中的 `ContextInfo` API 始终单线程串行执行。
186
+ 订阅建立后,行情事件走独立事件通道,不持续占用普通查询通道;订阅控制请求仍需等待
187
+ 当前正在执行的 QMT 调用结束。
188
+
189
+ 请求状态包括排队、运行、完成、失败和取消。长任务超时后,调用方应检查状态并根据业务
190
+ 需要补偿;bridge 不能强行中断已经进入 QMT 的底层调用。历史 tick 与业务数据的收盘后
191
+ 补偿也由调用方负责。
192
+
193
+ ## 七、文档与测试
194
+
195
+ - [API 兼容性与逐字段测试记录](docs/xtdata-api-matrix.md)
196
+ - [API 标准实现流程](docs/api-implementation-standard.md)
197
+ - [文件协议](docs/protocol.md)
198
+
199
+ 测试工具位于 `tools` 目录,测试输出应写入独立临时目录,不能覆盖生产数据。
200
+
201
+ ## 八、许可证
202
+
203
+ 本项目采用 Apache-2.0 许可证。QMT、MiniQMT 和 xtquant 是其各自权利人的名称;
204
+ 本项目是独立的适配实现,不包含厂商专有组件。
@@ -0,0 +1,184 @@
1
+ # qmt-sdk
2
+
3
+ `qmt-sdk` 是一个 QMT 外部调用 SDK。它通过运行在 QMT 内部的文件桥接,
4
+ 把 QMT 的查询和行情能力安全地暴露给外部 Python 程序;同时提供 `xtquant_compat`,
5
+ 用于适配 MiniQMT/`xtquant.xtdata` 的常用接口,帮助已有 MiniQMT 代码迁移到 QMT。
6
+
7
+ 项目当前以查询和行情为主,不包含下单、撤单、账户或持仓修改。文件桥接不依赖 QMT
8
+ Python 环境中的 Redis、ZeroMQ、`_socket`、`_ctypes` 或 pandas;外部 Python 环境负责
9
+ 安装 pandas 等数据处理依赖。
10
+
11
+ ## 为什么采用文件桥接
12
+
13
+ 不同券商提供的 QMT 版本,其内置 Python 运行环境并不完全相同。常见差异包括:
14
+
15
+ - 没有网络相关模块,例如 `_socket`,无法安装或使用 Redis、ZeroMQ 等通信库;
16
+ - 没有 `_ctypes`、pandas 或其他常用第三方依赖;
17
+ - Python 版本、模块搜索路径和启动方式不同;
18
+ - 策略运行环境受到白名单或沙箱限制,不能直接连接外部服务。
19
+
20
+ 如果把所有通信和数据处理都放进 QMT 内置 Python,代码就会被某个券商的运行环境绑定。
21
+ 文件桥接将 QMT 侧限制为“调用 `ContextInfo` 并读写文件”,把网络通信、数据处理和业务
22
+ 逻辑放到外部标准 Python 中。请求、响应和订阅事件通过带请求 ID 的文件交换,因此不依赖
23
+ QMT 是否带 Redis、是否允许网络连接,也不要求在 QMT 内安装第三方包。
24
+
25
+ 这种方式的代价是文件 I/O 和额外延迟,适合查询、行情同步、故障恢复和存量代码迁移;
26
+ 不定位为逐笔级高频交易通道。
27
+
28
+ ## 一、项目提供什么
29
+
30
+ ```text
31
+ 外部 Python 程序
32
+ ├─ qmt_sdk QMT 原生风格的统一客户端
33
+ └─ xtquant_compat MiniQMT/xtquant.xtdata 兼容层
34
+
35
+ 文件 bridge(运行在 QMT 策略中)
36
+
37
+ QMT ContextInfo
38
+ ```
39
+
40
+ `qmt_sdk` 尽量返回 QMT 原生结构;`xtquant_compat` 再将结果转换为存量 MiniQMT
41
+ 代码常用的结构。两者共用同一个文件 bridge 和请求队列,QMT API 始终在策略线程中串行执行。
42
+
43
+ ## 二、安装外部 Python 客户端
44
+
45
+ 不要把本项目安装到 QMT 自带的 Python。请使用外部 Python 3.8 或更高版本:
46
+
47
+ ```powershell
48
+ python -m venv .venv
49
+ .\.venv\Scripts\python.exe -m pip install -e ".[dev]"
50
+ ```
51
+
52
+ 如果只使用运行时,不需要开发依赖,可以执行:
53
+
54
+ ```powershell
55
+ .\.venv\Scripts\python.exe -m pip install -e .
56
+ ```
57
+
58
+ ## 三、在 QMT 中部署 bridge
59
+
60
+ 源码仓库的 `qmt_strategy` 目录以及安装包的模板目录都包含两个需要部署的文件:
61
+
62
+ - `XTQUANT_COMPAT_BRIDGE.py`:实际 bridge 实现;
63
+ - `XTQUANT_COMPAT_BRIDGE_LAUNCHER.py`:QMT 策略入口。
64
+
65
+ 安装步骤:
66
+
67
+ 1. 将 `qmt_strategy/XTQUANT_COMPAT_BRIDGE.py` 复制到 QMT Python 的搜索路径中。
68
+ 通常可以复制到 QMT 安装目录下的 `python` 目录;不要求使用某个固定盘符或目录名称。
69
+ 2. 在 QMT 策略管理器中新建一个策略,名称准确填写:
70
+
71
+ ```text
72
+ XTQUANT_COMPAT_BRIDGE_LAUNCHER
73
+ ```
74
+
75
+ 3. 打开仓库中的 `qmt_strategy/XTQUANT_COMPAT_BRIDGE_LAUNCHER.py`,将全部内容复制到该策略。
76
+ 4. 启动策略,确认日志出现类似:
77
+
78
+ ```text
79
+ [xtquant_compat] started root=... instance=...
80
+ [xtquant_compat] scheduled adjust interval=100nMilliSecond
81
+ ```
82
+
83
+ launcher 会自动从 QMT 的 `sys.path` 查找 `XTQUANT_COMPAT_BRIDGE.py`。如果 QMT 没有把
84
+ 复制目录加入搜索路径,可以设置环境变量 `XTQUANT_COMPAT_BRIDGE_FILE` 指向该文件。
85
+
86
+ 通过 PyPI 安装时,可以使用下面的命令定位模板目录,再从该目录复制两个文件:
87
+
88
+ ```powershell
89
+ python -c "import qmt_sdk; print(qmt_sdk.get_template_dir())"
90
+ ```
91
+
92
+ bridge 默认使用独立的数据目录;请求、响应、状态和订阅事件都会写入其中。不要把这个
93
+ 目录与其他实验 bridge 混用,也不要将其加入生产数据目录。
94
+
95
+ ## 四、外部程序调用
96
+
97
+ ### 使用 QMT 原生风格客户端
98
+
99
+ ```python
100
+ from qmt_sdk import QmtClient
101
+
102
+ client = QmtClient()
103
+ print(client.data.get_market_data_ex(
104
+ ["open", "high", "low", "close", "volume", "amount"],
105
+ ["000001.SZ"], "1d", "20260902", "20260902",
106
+ ))
107
+ ```
108
+
109
+ ### 迁移 MiniQMT/xtquant 存量代码
110
+
111
+ ```python
112
+ from xtquant_compat import xtdata
113
+
114
+ stocks = xtdata.get_stock_list_in_sector("沪深A股")
115
+ data = xtdata.get_market_data_ex(
116
+ ["open", "high", "low", "close", "volume", "amount"],
117
+ stocks[:10], "1d", "20260902", "20260902",
118
+ )
119
+ print(data)
120
+ ```
121
+
122
+ 订阅接口保持常见 MiniQMT 调用方式:
123
+
124
+ ```python
125
+ def on_quote(data):
126
+ print(data)
127
+
128
+ seq = xtdata.subscribe_quote("000001.SZ", period="tick", callback=on_quote)
129
+ # 不再需要时:
130
+ xtdata.unsubscribe_quote(seq)
131
+ ```
132
+
133
+ 默认 bridge 配置不适合时,可以显式设置目录和超时:
134
+
135
+ ```python
136
+ from xtquant_compat import configure
137
+
138
+ configure(root=r"<bridge-data-root>", timeout=120)
139
+ ```
140
+
141
+ ## 五、目前支持的能力
142
+
143
+ 下面是能力总览。`qmt_sdk` 提供 QMT 原生风格入口,`xtquant_compat` 提供 MiniQMT/`xtquant.xtdata`
144
+ 兼容入口;完整签名、实现状态、返回结构、逐字段差异和测试记录以
145
+ [API 兼容性文档](docs/xtdata-api-matrix.md) 为准。
146
+
147
+ | 能力分类 | 代表接口/功能 | `qmt_sdk` | `xtquant_compat` | 说明 |
148
+ |---|---|---|---|---|
149
+ | 行情与历史数据 | `get_market_data`、`get_market_data_ex`、`get_local_data`、`get_history_data` | 支持 | 支持 | 1d、1m、tick;下载与查询分开 |
150
+ | Tick 快照 | `get_full_tick` | 支持 | 支持 | 返回 QMT 原生或 MiniQMT 兼容结构 |
151
+ | 历史下载 | `download_history_data`、`download_history_data2` | 支持 | 支持 | 批量下载结果依赖 QMT 本地数据能力 |
152
+ | 实时订阅 | `subscribe_quote`、`subscribe_whole_quote`、`unsubscribe_quote` | 支持 | 支持 | 回调、事件持久化和取消订阅 |
153
+ | 标的与板块 | `get_stock_list_in_sector`、`get_instrument_detail*` | 支持 | 支持 | 股票、指数、合约等标的属性 |
154
+ | 交易日历与状态 | 交易日历、ST 状态、合约列表 | 支持 | 支持 | 返回结构按入口分别保持原生/兼容语义 |
155
+ | ETF、期权与指数 | ETF、期权、指数成分/权重、主力合约 | 支持 | 支持 | 具体接口以 API 文档为准 |
156
+ | 除权与计算 | 除权除息、BSM 价格、隐含波动率 | 支持 | 支持 | 查询或纯计算功能 |
157
+ | 财务与市场扩展 | `get_financial_data`、港股通、龙虎榜、北向资金 | 支持 | 支持 | 部分 QMT 环境的财务接口依赖 pandas |
158
+ | 财务扩展(暂不承诺数据) | `get_turnover_rate`、`get_raw_financial_data` | 已接入签名 | 已接入签名 | 当前环境缺少 pandas 时无法保证数据返回 |
159
+
160
+ 当前明确不在范围内:下单、撤单、交易回报、账户/持仓/资金修改,以及必须依赖厂商专有
161
+ DLL 或外部服务才能完成的功能。
162
+
163
+ ## 六、请求、订阅和可靠性
164
+
165
+ 外部请求可以并发提交,但同一个 QMT 实例中的 `ContextInfo` API 始终单线程串行执行。
166
+ 订阅建立后,行情事件走独立事件通道,不持续占用普通查询通道;订阅控制请求仍需等待
167
+ 当前正在执行的 QMT 调用结束。
168
+
169
+ 请求状态包括排队、运行、完成、失败和取消。长任务超时后,调用方应检查状态并根据业务
170
+ 需要补偿;bridge 不能强行中断已经进入 QMT 的底层调用。历史 tick 与业务数据的收盘后
171
+ 补偿也由调用方负责。
172
+
173
+ ## 七、文档与测试
174
+
175
+ - [API 兼容性与逐字段测试记录](docs/xtdata-api-matrix.md)
176
+ - [API 标准实现流程](docs/api-implementation-standard.md)
177
+ - [文件协议](docs/protocol.md)
178
+
179
+ 测试工具位于 `tools` 目录,测试输出应写入独立临时目录,不能覆盖生产数据。
180
+
181
+ ## 八、许可证
182
+
183
+ 本项目采用 Apache-2.0 许可证。QMT、MiniQMT 和 xtquant 是其各自权利人的名称;
184
+ 本项目是独立的适配实现,不包含厂商专有组件。
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "qmt-sdk"
7
+ version = "0.3.0"
8
+ description = "Unified QMT Python SDK with MiniQMT xtquant compatibility."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "Apache-2.0"}
12
+ authors = [{name = "qmt-sdk contributors"}]
13
+ dependencies = ["pandas>=1.5"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "License :: OSI Approved :: Apache Software License",
17
+ "Operating System :: Microsoft :: Windows",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Office/Business :: Financial :: Investment",
20
+ ]
21
+
22
+ [project.optional-dependencies]
23
+ dev = ["pytest>=7", "ruff>=0.5"]
24
+
25
+ [tool.setuptools.packages.find]
26
+ where = ["src"]
27
+
28
+ [tool.setuptools.package-data]
29
+ xtquant_compat = ["official_xtdata_api.json"]
30
+
31
+ [tool.setuptools.data-files]
32
+ qmt_strategy = ["qmt_strategy/*.py"]
33
+
34
+ [tool.pytest.ini_options]
35
+ testpaths = ["tests"]
36
+
37
+ [tool.ruff]
38
+ line-length = 100
39
+ target-version = "py38"
40
+
41
+ [tool.ruff.lint]
42
+ select = ["E4", "E7", "E9", "F"]