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.
- qmt_sdk-0.3.0/LICENSE +192 -0
- qmt_sdk-0.3.0/MANIFEST.in +3 -0
- qmt_sdk-0.3.0/PKG-INFO +204 -0
- qmt_sdk-0.3.0/README.md +184 -0
- qmt_sdk-0.3.0/pyproject.toml +42 -0
- qmt_sdk-0.3.0/qmt_strategy/XTQUANT_COMPAT_BRIDGE.py +811 -0
- qmt_sdk-0.3.0/qmt_strategy/XTQUANT_COMPAT_BRIDGE_LAUNCHER.py +17 -0
- qmt_sdk-0.3.0/setup.cfg +4 -0
- qmt_sdk-0.3.0/src/qmt_sdk/__init__.py +29 -0
- qmt_sdk-0.3.0/src/qmt_sdk/api_surface.py +48 -0
- qmt_sdk-0.3.0/src/qmt_sdk/backends/__init__.py +4 -0
- qmt_sdk-0.3.0/src/qmt_sdk/backends/miniqmt.py +11 -0
- qmt_sdk-0.3.0/src/qmt_sdk/backends/qmt.py +27 -0
- qmt_sdk-0.3.0/src/qmt_sdk/bridge/__init__.py +6 -0
- qmt_sdk-0.3.0/src/qmt_sdk/bridge/client.py +179 -0
- qmt_sdk-0.3.0/src/qmt_sdk/bridge/config.py +38 -0
- qmt_sdk-0.3.0/src/qmt_sdk/bridge/exceptions.py +26 -0
- qmt_sdk-0.3.0/src/qmt_sdk/bridge/protocol.py +20 -0
- qmt_sdk-0.3.0/src/qmt_sdk/client.py +43 -0
- qmt_sdk-0.3.0/src/qmt_sdk/data.py +624 -0
- qmt_sdk-0.3.0/src/qmt_sdk/financial.py +23 -0
- qmt_sdk-0.3.0/src/qmt_sdk/instruments.py +72 -0
- qmt_sdk-0.3.0/src/qmt_sdk/jobs.py +12 -0
- qmt_sdk-0.3.0/src/qmt_sdk/market.py +71 -0
- qmt_sdk-0.3.0/src/qmt_sdk/qmt.py +24 -0
- qmt_sdk-0.3.0/src/qmt_sdk.egg-info/PKG-INFO +204 -0
- qmt_sdk-0.3.0/src/qmt_sdk.egg-info/SOURCES.txt +45 -0
- qmt_sdk-0.3.0/src/qmt_sdk.egg-info/dependency_links.txt +1 -0
- qmt_sdk-0.3.0/src/qmt_sdk.egg-info/requires.txt +5 -0
- qmt_sdk-0.3.0/src/qmt_sdk.egg-info/top_level.txt +2 -0
- qmt_sdk-0.3.0/src/xtquant_compat/__init__.py +7 -0
- qmt_sdk-0.3.0/src/xtquant_compat/api_surface.py +48 -0
- qmt_sdk-0.3.0/src/xtquant_compat/client.py +16 -0
- qmt_sdk-0.3.0/src/xtquant_compat/config.py +5 -0
- qmt_sdk-0.3.0/src/xtquant_compat/exceptions.py +9 -0
- qmt_sdk-0.3.0/src/xtquant_compat/official_xtdata_api.json +2649 -0
- qmt_sdk-0.3.0/src/xtquant_compat/protocol.py +20 -0
- qmt_sdk-0.3.0/src/xtquant_compat/xtdata.py +595 -0
- qmt_sdk-0.3.0/tests/test_api_compatibility_document.py +40 -0
- qmt_sdk-0.3.0/tests/test_config.py +6 -0
- qmt_sdk-0.3.0/tests/test_daily_workflow_contract.py +56 -0
- qmt_sdk-0.3.0/tests/test_official_api_surface.py +20 -0
- qmt_sdk-0.3.0/tests/test_packaging.py +9 -0
- qmt_sdk-0.3.0/tests/test_protocol.py +9 -0
- qmt_sdk-0.3.0/tests/test_qmt_bridge.py +82 -0
- qmt_sdk-0.3.0/tests/test_qmt_sdk_facade.py +33 -0
- 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.
|
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
|
+
本项目是独立的适配实现,不包含厂商专有组件。
|
qmt_sdk-0.3.0/README.md
ADDED
|
@@ -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"]
|