cfquant 0.2.0__tar.gz → 0.2.1__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.
- {cfquant-0.2.0 → cfquant-0.2.1}/PKG-INFO +74 -14
- {cfquant-0.2.0 → cfquant-0.2.1}/README.md +73 -13
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/cli.py +147 -45
- cfquant-0.2.1/cfquant/version.py +5 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/PKG-INFO +74 -14
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/SOURCES.txt +0 -10
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant_web_server.py +1 -1
- {cfquant-0.2.0 → cfquant-0.2.1}/pyproject.toml +1 -1
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/app.js +2 -2
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/index.html +4 -4
- cfquant-0.2.0/cfquant/version.py +0 -5
- cfquant-0.2.0/web_dashboard/image//351/200/232/347/224/250/346/250/241/345/274/217/351/203/250/347/275/262/346/214/207/345/215/227/image-1.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/200/232/347/224/250/346/250/241/345/274/217/351/203/250/347/275/262/346/214/207/345/215/227/image-2.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/200/232/347/224/250/346/250/241/345/274/217/351/203/250/347/275/262/346/214/207/345/215/227/image-3.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/200/232/347/224/250/346/250/241/345/274/217/351/203/250/347/275/262/346/214/207/345/215/227/image.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783479325179.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783479745262.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783480178700.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783480428759.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783489807217.png +0 -0
- cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783490503491.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/LICENSE +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/__init__.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/Config.txt +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/LTtx_server.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/__init__.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/tx.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/MANIFEST.in +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/__init__.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/account_routing.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/channels.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/client.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/config.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/hub.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/logging_i18n.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/normal_bridge.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_bridge.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_client.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_hub.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_transport.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/protocol.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/qmt_bridge.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/runtime_report.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/tx.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/tx_trade_bridge.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xtconstant.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xtdata.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xttrader.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xttype.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/dependency_links.txt +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/entry_points.txt +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/requires.txt +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/top_level.txt +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/cfquant_pipe_hub.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT_LITE.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT_TRADE_LOWLAT.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/__init__.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_CTYPE_ALL_LOWLAT_SH.py" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_CTYPE_ALL_LOWLAT_SZ.py" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_LITE_SH.py" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_LITE_SZ.py" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_TRADE_LOWLAT_SH.py" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_TRADE_LOWLAT_SZ.py" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/readme.md" +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/requirements.txt +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/setup.cfg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/__init__.py +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/amber-pulse.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/copper-grid.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/market-blue.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/rose-circuit.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/signal-green.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/slate-wave.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/teal-orbit.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/violet-node.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/favicon.svg +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-10.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-11.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-12.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-13.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-14.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-15.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-16.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-17.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-18.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-19.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-20.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-21.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-4.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-5.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-6.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-7.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-8.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-9.png +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/styles.css +0 -0
- {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/vendor/mermaid.min.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cfquant
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: QMT local bridge and xtquant-compatible Python client.
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -27,6 +27,7 @@ Requires-Dist: pyzmq>=25; extra == "zmq"
|
|
|
27
27
|
<a href="https://github.com/95ge/cfquant/issues"><img alt="GitHub issues" src="https://img.shields.io/github/issues/95ge/cfquant?style=flat&logo=github&label=Issues" /></a>
|
|
28
28
|
<a href="https://github.com/95ge/cfquant/commits/main"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/95ge/cfquant?style=flat&logo=git&label=Last%20commit" /></a>
|
|
29
29
|
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat" /></a>
|
|
30
|
+
<a href="https://pypi.org/project/cfquant/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/cfquant?style=flat&logo=pypi&logoColor=white" /></a>
|
|
30
31
|
<img alt="Python 3.8 to 3.12" src="https://img.shields.io/badge/Python-3.8--3.12-blue?style=flat&logo=python&logoColor=white" />
|
|
31
32
|
</p>
|
|
32
33
|
|
|
@@ -50,22 +51,80 @@ Requires-Dist: pyzmq>=25; extra == "zmq"
|
|
|
50
51
|
- 已安装并登录大 QMT
|
|
51
52
|
- Python `3.8` - `3.12`,生产环境优先使用 `3.10` 或 `3.12`
|
|
52
53
|
|
|
53
|
-
###
|
|
54
|
+
### 安装方式
|
|
55
|
+
|
|
56
|
+
#### 方式一:源码包部署(推荐)
|
|
57
|
+
|
|
58
|
+
新用户和生产环境优先使用源码包部署。原因很简单:cfquant 的 Web 控制台、QMT 入口脚本和本地配置是一起工作的,源码包保留完整项目目录,后续在网页里检查更新、更新 Web、回滚版本、提示 QMT 入口脚本变更都更方便。
|
|
54
59
|
|
|
55
60
|
1. 将项目解压到固定目录,例如 `D:\cfquant`。
|
|
56
61
|
2. 在项目目录安装依赖:
|
|
57
62
|
|
|
58
63
|
```powershell
|
|
59
64
|
cd D:\cfquant
|
|
60
|
-
pip install -r requirements.txt
|
|
65
|
+
python -m pip install -r requirements.txt
|
|
61
66
|
```
|
|
62
67
|
|
|
63
|
-
3. 运行
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
3. 运行 `start_cfquant.bat`。
|
|
69
|
+
|
|
70
|
+
启动后打开 <http://127.0.0.1:8765/>,按网页中的“新手初始化向导”完成账号、模式和 QMT 目录配置。然后在 QMT 中加载对应的入口脚本,回到网页验证资金、持仓、委托和行情。
|
|
71
|
+
|
|
72
|
+
重点:
|
|
73
|
+
|
|
74
|
+
- 源码部署后,网页里的“版本/更新”功能会按完整项目目录更新,适合从官网或 GitHub 拉取新版本。
|
|
75
|
+
- 更新时会尽量保留本地配置、数据库、日志和运行目录,便于日常升级和回滚。
|
|
76
|
+
- 如果新版本修改了 `qmt_scripts/` 里的入口脚本,网页会提示你重新更新 QMT 侧脚本并重启对应 QMT 策略。
|
|
77
|
+
- 建议把源码目录固定下来,例如 `D:\cfquant`,不要频繁挪动目录。
|
|
66
78
|
|
|
67
79
|
新用户建议先使用**通用模式**。一个 QMT 加载一个入口脚本即可完成大多数部署。
|
|
68
80
|
|
|
81
|
+
#### 方式二:PyPI 安装(仅推荐库调用或临时体验)
|
|
82
|
+
|
|
83
|
+
PyPI 适合外部 Python 策略只安装 `cfquant` 库,或者临时体验命令行启动方式;不建议把它作为完整 Web 部署的主要方式。pip 安装后的项目文件位于当前 Python 环境的 `site-packages`,网页里的项目更新、源码回滚和入口脚本同步不如源码包部署直观。
|
|
84
|
+
|
|
85
|
+
```powershell
|
|
86
|
+
python -m pip install -U cfquant
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
After installation, you can start the local Web Console:
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
cfquant --open-browser
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
如果使用 pip 安装,QMT 侧仍需要加载入口脚本。查看 pip 包内置的 QMT 入口脚本目录:
|
|
96
|
+
|
|
97
|
+
```powershell
|
|
98
|
+
cfquant qmt-scripts
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
在 Windows 资源管理器中打开脚本目录:
|
|
102
|
+
|
|
103
|
+
```powershell
|
|
104
|
+
cfquant qmt-scripts --open
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
把入口脚本复制到 QMT 可加载目录:
|
|
108
|
+
|
|
109
|
+
```powershell
|
|
110
|
+
cfquant qmt-scripts --output D:\QMT\cfquant
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
后续升级 pip 包需要回到命令行执行:
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
python -m pip install -U cfquant
|
|
117
|
+
cfquant qmt-scripts --output D:\QMT\cfquant --force
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
升级后建议重启本地 `cfquant` 服务,并在 QMT 中重新加载入口脚本,确保 Web、本地 Python 库和 QMT 侧入口属于同一版本。
|
|
121
|
+
|
|
122
|
+
验证安装版本和脚本目录:
|
|
123
|
+
|
|
124
|
+
```powershell
|
|
125
|
+
cfquant version
|
|
126
|
+
```
|
|
127
|
+
|
|
69
128
|
## 模式选择
|
|
70
129
|
|
|
71
130
|
| 模式 | QMT 入口 | 适用场景 |
|
|
@@ -78,7 +137,7 @@ Requires-Dist: pyzmq>=25; extra == "zmq"
|
|
|
78
137
|
|
|
79
138
|
## Python 接入
|
|
80
139
|
|
|
81
|
-
从 PyPI
|
|
140
|
+
从 PyPI 安装并在外部策略中调用:
|
|
82
141
|
|
|
83
142
|
```powershell
|
|
84
143
|
pip install cfquant
|
|
@@ -95,22 +154,23 @@ print(tick)
|
|
|
95
154
|
|
|
96
155
|
`cfquant` 默认使用 `transport=auto`,通常不需要手动配置通信通道。完整导入方式、路由规则和特殊部署方式见[外部 Python 接入](docs/外部Python接入.md)。
|
|
97
156
|
|
|
98
|
-
## Web
|
|
157
|
+
## Web Console
|
|
99
158
|
|
|
100
|
-
Web
|
|
159
|
+
The Web Console provides account binding, cash and positions, order fills, order placement and cancellation, market subscriptions, API debugging, deployment guides, and update management.
|
|
101
160
|
|
|
102
|
-
|
|
161
|
+
Common scripts:
|
|
103
162
|
|
|
104
163
|
```text
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
164
|
+
start_cfquant.bat Start
|
|
165
|
+
stop_cfquant.bat Stop
|
|
166
|
+
restart_cfquant.bat Restart
|
|
108
167
|
```
|
|
109
168
|
|
|
110
169
|
## 文档
|
|
111
170
|
|
|
112
171
|
| 需求 | 文档 |
|
|
113
172
|
|---|---|
|
|
173
|
+
| QMT 综合部署教程 | [QMT 部署教程](docs/QMT部署教程.md) |
|
|
114
174
|
| 通用模式部署 | [通用模式部署指南](docs/通用模式部署指南.md) |
|
|
115
175
|
| 极致模式部署 | [极致模式部署指南](docs/极致模式部署指南.md) |
|
|
116
176
|
| 高级模式部署 | [高级模式部署指南](docs/高级模式部署指南.md) |
|
|
@@ -122,7 +182,7 @@ Web 控制台提供账号绑定、资金持仓、委托成交、下单撤单、
|
|
|
122
182
|
| 日志、更新和回滚 | [运维与更新](docs/运维与更新.md) |
|
|
123
183
|
| 版本变化 | [版本日志](docs/版本日志.md) |
|
|
124
184
|
|
|
125
|
-
|
|
185
|
+
More detailed tutorials are also available on the Web Console "Tutorials" page.
|
|
126
186
|
|
|
127
187
|
## Star History
|
|
128
188
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
<a href="https://github.com/95ge/cfquant/issues"><img alt="GitHub issues" src="https://img.shields.io/github/issues/95ge/cfquant?style=flat&logo=github&label=Issues" /></a>
|
|
7
7
|
<a href="https://github.com/95ge/cfquant/commits/main"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/95ge/cfquant?style=flat&logo=git&label=Last%20commit" /></a>
|
|
8
8
|
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat" /></a>
|
|
9
|
+
<a href="https://pypi.org/project/cfquant/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/cfquant?style=flat&logo=pypi&logoColor=white" /></a>
|
|
9
10
|
<img alt="Python 3.8 to 3.12" src="https://img.shields.io/badge/Python-3.8--3.12-blue?style=flat&logo=python&logoColor=white" />
|
|
10
11
|
</p>
|
|
11
12
|
|
|
@@ -29,22 +30,80 @@
|
|
|
29
30
|
- 已安装并登录大 QMT
|
|
30
31
|
- Python `3.8` - `3.12`,生产环境优先使用 `3.10` 或 `3.12`
|
|
31
32
|
|
|
32
|
-
###
|
|
33
|
+
### 安装方式
|
|
34
|
+
|
|
35
|
+
#### 方式一:源码包部署(推荐)
|
|
36
|
+
|
|
37
|
+
新用户和生产环境优先使用源码包部署。原因很简单:cfquant 的 Web 控制台、QMT 入口脚本和本地配置是一起工作的,源码包保留完整项目目录,后续在网页里检查更新、更新 Web、回滚版本、提示 QMT 入口脚本变更都更方便。
|
|
33
38
|
|
|
34
39
|
1. 将项目解压到固定目录,例如 `D:\cfquant`。
|
|
35
40
|
2. 在项目目录安装依赖:
|
|
36
41
|
|
|
37
42
|
```powershell
|
|
38
43
|
cd D:\cfquant
|
|
39
|
-
pip install -r requirements.txt
|
|
44
|
+
python -m pip install -r requirements.txt
|
|
40
45
|
```
|
|
41
46
|
|
|
42
|
-
3. 运行
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
3. 运行 `start_cfquant.bat`。
|
|
48
|
+
|
|
49
|
+
启动后打开 <http://127.0.0.1:8765/>,按网页中的“新手初始化向导”完成账号、模式和 QMT 目录配置。然后在 QMT 中加载对应的入口脚本,回到网页验证资金、持仓、委托和行情。
|
|
50
|
+
|
|
51
|
+
重点:
|
|
52
|
+
|
|
53
|
+
- 源码部署后,网页里的“版本/更新”功能会按完整项目目录更新,适合从官网或 GitHub 拉取新版本。
|
|
54
|
+
- 更新时会尽量保留本地配置、数据库、日志和运行目录,便于日常升级和回滚。
|
|
55
|
+
- 如果新版本修改了 `qmt_scripts/` 里的入口脚本,网页会提示你重新更新 QMT 侧脚本并重启对应 QMT 策略。
|
|
56
|
+
- 建议把源码目录固定下来,例如 `D:\cfquant`,不要频繁挪动目录。
|
|
45
57
|
|
|
46
58
|
新用户建议先使用**通用模式**。一个 QMT 加载一个入口脚本即可完成大多数部署。
|
|
47
59
|
|
|
60
|
+
#### 方式二:PyPI 安装(仅推荐库调用或临时体验)
|
|
61
|
+
|
|
62
|
+
PyPI 适合外部 Python 策略只安装 `cfquant` 库,或者临时体验命令行启动方式;不建议把它作为完整 Web 部署的主要方式。pip 安装后的项目文件位于当前 Python 环境的 `site-packages`,网页里的项目更新、源码回滚和入口脚本同步不如源码包部署直观。
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
python -m pip install -U cfquant
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
After installation, you can start the local Web Console:
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
cfquant --open-browser
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
如果使用 pip 安装,QMT 侧仍需要加载入口脚本。查看 pip 包内置的 QMT 入口脚本目录:
|
|
75
|
+
|
|
76
|
+
```powershell
|
|
77
|
+
cfquant qmt-scripts
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
在 Windows 资源管理器中打开脚本目录:
|
|
81
|
+
|
|
82
|
+
```powershell
|
|
83
|
+
cfquant qmt-scripts --open
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
把入口脚本复制到 QMT 可加载目录:
|
|
87
|
+
|
|
88
|
+
```powershell
|
|
89
|
+
cfquant qmt-scripts --output D:\QMT\cfquant
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
后续升级 pip 包需要回到命令行执行:
|
|
93
|
+
|
|
94
|
+
```powershell
|
|
95
|
+
python -m pip install -U cfquant
|
|
96
|
+
cfquant qmt-scripts --output D:\QMT\cfquant --force
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
升级后建议重启本地 `cfquant` 服务,并在 QMT 中重新加载入口脚本,确保 Web、本地 Python 库和 QMT 侧入口属于同一版本。
|
|
100
|
+
|
|
101
|
+
验证安装版本和脚本目录:
|
|
102
|
+
|
|
103
|
+
```powershell
|
|
104
|
+
cfquant version
|
|
105
|
+
```
|
|
106
|
+
|
|
48
107
|
## 模式选择
|
|
49
108
|
|
|
50
109
|
| 模式 | QMT 入口 | 适用场景 |
|
|
@@ -57,7 +116,7 @@
|
|
|
57
116
|
|
|
58
117
|
## Python 接入
|
|
59
118
|
|
|
60
|
-
从 PyPI
|
|
119
|
+
从 PyPI 安装并在外部策略中调用:
|
|
61
120
|
|
|
62
121
|
```powershell
|
|
63
122
|
pip install cfquant
|
|
@@ -74,22 +133,23 @@ print(tick)
|
|
|
74
133
|
|
|
75
134
|
`cfquant` 默认使用 `transport=auto`,通常不需要手动配置通信通道。完整导入方式、路由规则和特殊部署方式见[外部 Python 接入](docs/外部Python接入.md)。
|
|
76
135
|
|
|
77
|
-
## Web
|
|
136
|
+
## Web Console
|
|
78
137
|
|
|
79
|
-
Web
|
|
138
|
+
The Web Console provides account binding, cash and positions, order fills, order placement and cancellation, market subscriptions, API debugging, deployment guides, and update management.
|
|
80
139
|
|
|
81
|
-
|
|
140
|
+
Common scripts:
|
|
82
141
|
|
|
83
142
|
```text
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
143
|
+
start_cfquant.bat Start
|
|
144
|
+
stop_cfquant.bat Stop
|
|
145
|
+
restart_cfquant.bat Restart
|
|
87
146
|
```
|
|
88
147
|
|
|
89
148
|
## 文档
|
|
90
149
|
|
|
91
150
|
| 需求 | 文档 |
|
|
92
151
|
|---|---|
|
|
152
|
+
| QMT 综合部署教程 | [QMT 部署教程](docs/QMT部署教程.md) |
|
|
93
153
|
| 通用模式部署 | [通用模式部署指南](docs/通用模式部署指南.md) |
|
|
94
154
|
| 极致模式部署 | [极致模式部署指南](docs/极致模式部署指南.md) |
|
|
95
155
|
| 高级模式部署 | [高级模式部署指南](docs/高级模式部署指南.md) |
|
|
@@ -101,7 +161,7 @@ Web 控制台提供账号绑定、资金持仓、委托成交、下单撤单、
|
|
|
101
161
|
| 日志、更新和回滚 | [运维与更新](docs/运维与更新.md) |
|
|
102
162
|
| 版本变化 | [版本日志](docs/版本日志.md) |
|
|
103
163
|
|
|
104
|
-
|
|
164
|
+
More detailed tutorials are also available on the Web Console "Tutorials" page.
|
|
105
165
|
|
|
106
166
|
## Star History
|
|
107
167
|
|
|
@@ -7,6 +7,7 @@ import argparse
|
|
|
7
7
|
import os
|
|
8
8
|
import shutil
|
|
9
9
|
import socket
|
|
10
|
+
import subprocess
|
|
10
11
|
import sys
|
|
11
12
|
import threading
|
|
12
13
|
import time
|
|
@@ -31,13 +32,40 @@ QMT_SCRIPT_FILES = (
|
|
|
31
32
|
)
|
|
32
33
|
|
|
33
34
|
|
|
35
|
+
def _configure_console_encoding():
|
|
36
|
+
"""Keep Chinese CLI output readable on Windows and redirected consoles."""
|
|
37
|
+
os.environ.setdefault("PYTHONUTF8", "1")
|
|
38
|
+
os.environ.setdefault("PYTHONIOENCODING", "utf-8")
|
|
39
|
+
for stream_name in ("stdout", "stderr"):
|
|
40
|
+
stream = getattr(sys, stream_name, None)
|
|
41
|
+
reconfigure = getattr(stream, "reconfigure", None)
|
|
42
|
+
if reconfigure is None:
|
|
43
|
+
continue
|
|
44
|
+
try:
|
|
45
|
+
reconfigure(encoding="utf-8", errors="replace")
|
|
46
|
+
except Exception:
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
34
50
|
def _package_version():
|
|
51
|
+
project_file = Path(__file__).resolve().parent.parent / "pyproject.toml"
|
|
52
|
+
try:
|
|
53
|
+
for line in project_file.read_text(encoding="utf-8").splitlines():
|
|
54
|
+
if line.strip().startswith("version"):
|
|
55
|
+
name, value = line.split("=", 1)
|
|
56
|
+
if name.strip() == "version":
|
|
57
|
+
return value.strip().strip('"').strip("'")
|
|
58
|
+
except Exception:
|
|
59
|
+
pass
|
|
60
|
+
|
|
35
61
|
try:
|
|
36
62
|
from importlib import metadata
|
|
37
63
|
|
|
38
|
-
|
|
64
|
+
dist = metadata.distribution("cfquant")
|
|
65
|
+
return dist.version
|
|
39
66
|
except Exception:
|
|
40
|
-
|
|
67
|
+
pass
|
|
68
|
+
return "unknown"
|
|
41
69
|
|
|
42
70
|
|
|
43
71
|
def _port(value):
|
|
@@ -79,37 +107,40 @@ def _serve_parser(prog="cfquant"):
|
|
|
79
107
|
help_command = "%s serve --help" % prog if prog == "cfquant" else "%s --help" % prog
|
|
80
108
|
if prog == "cfquant":
|
|
81
109
|
epilog = (
|
|
82
|
-
"
|
|
83
|
-
" cfquant
|
|
84
|
-
" cfquant qmt-scripts
|
|
85
|
-
" cfquant
|
|
86
|
-
"
|
|
110
|
+
"常用命令:\n"
|
|
111
|
+
" cfquant 启动本地 Web 控制台。\n"
|
|
112
|
+
" cfquant qmt-scripts 查看已安装的 QMT 入口脚本目录。\n"
|
|
113
|
+
" cfquant qmt-scripts --open 在资源管理器中打开 QMT 入口脚本目录。\n"
|
|
114
|
+
" cfquant qmt-scripts --output DIRECTORY 导出 QMT 入口脚本到指定目录。\n"
|
|
115
|
+
" cfquant pipe-hub [options] 只启动 named-pipe hub。\n"
|
|
116
|
+
" cfquant version 显示安装版本和目录。\n"
|
|
117
|
+
"使用 '%s' 查看 Web 启动参数。" % help_command
|
|
87
118
|
)
|
|
88
119
|
else:
|
|
89
|
-
epilog = "
|
|
120
|
+
epilog = "使用 '%s' 查看 Web 启动参数。" % help_command
|
|
90
121
|
parser = argparse.ArgumentParser(
|
|
91
122
|
prog=prog,
|
|
92
|
-
description="
|
|
123
|
+
description="启动 cfquant 本地 Web 控制台。",
|
|
93
124
|
epilog=epilog,
|
|
94
125
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
95
126
|
)
|
|
96
|
-
parser.add_argument("--host", help="Web
|
|
97
|
-
parser.add_argument("--port", type=_port, help="Web
|
|
127
|
+
parser.add_argument("--host", help="Web 绑定地址。默认使用本机地址或已保存配置。")
|
|
128
|
+
parser.add_argument("--port", type=_port, help="Web 监听端口。默认使用已保存配置或 8765。")
|
|
98
129
|
parser.add_argument(
|
|
99
130
|
"--home",
|
|
100
131
|
"--state-dir",
|
|
101
132
|
dest="home",
|
|
102
|
-
help="
|
|
133
|
+
help="cfquant 可写运行目录,用于保存配置、数据库、日志和状态文件。",
|
|
103
134
|
)
|
|
104
|
-
parser.add_argument("--runtime-dir", help="
|
|
105
|
-
parser.add_argument("--log-dir", help="
|
|
106
|
-
parser.add_argument("--config", help="
|
|
107
|
-
parser.add_argument("--pipe-name", help=r"
|
|
108
|
-
parser.add_argument("--lttx-host", help="LTtx
|
|
109
|
-
parser.add_argument("--lttx-port", type=_port, help="LTtx
|
|
110
|
-
parser.add_argument("--account-id", help="
|
|
111
|
-
parser.add_argument("--open-browser", action="store_true", help="
|
|
112
|
-
parser.add_argument("--dry-run", action="store_true", help="
|
|
135
|
+
parser.add_argument("--runtime-dir", help="覆盖 runtime 子目录。")
|
|
136
|
+
parser.add_argument("--log-dir", help="覆盖日志目录。")
|
|
137
|
+
parser.add_argument("--config", help="Web 配置 JSON 文件路径。")
|
|
138
|
+
parser.add_argument("--pipe-name", help=r"覆盖 QMT named pipe 名称,例如 \\.\pipe\cfquant_pipe_hub。")
|
|
139
|
+
parser.add_argument("--lttx-host", help="LTtx 地址。默认 127.0.0.1。")
|
|
140
|
+
parser.add_argument("--lttx-port", type=_port, help="LTtx 端口。默认 2049。")
|
|
141
|
+
parser.add_argument("--account-id", help="Web 初始化完成前使用的默认资金账号。")
|
|
142
|
+
parser.add_argument("--open-browser", action="store_true", help="服务就绪后自动打开浏览器。")
|
|
143
|
+
parser.add_argument("--dry-run", action="store_true", help="只打印启动参数,不启动服务。")
|
|
113
144
|
parser.add_argument("--version", action="version", version=_version_text())
|
|
114
145
|
return parser
|
|
115
146
|
|
|
@@ -127,6 +158,41 @@ def _browser_url(host, port):
|
|
|
127
158
|
return "http://%s:%s/" % (host, port)
|
|
128
159
|
|
|
129
160
|
|
|
161
|
+
def _resolve_web_address(args):
|
|
162
|
+
host = args.host or os.environ.get("CFQUANT_WEB_HOST")
|
|
163
|
+
port = args.port
|
|
164
|
+
if host and port is not None:
|
|
165
|
+
return host, port
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
from cfquant_web_server import WEB_CONFIG, normalize_web_port
|
|
169
|
+
|
|
170
|
+
if not host:
|
|
171
|
+
host = "0.0.0.0" if WEB_CONFIG.allow_remote() else "127.0.0.1"
|
|
172
|
+
if port is None:
|
|
173
|
+
port = normalize_web_port(
|
|
174
|
+
os.environ.get("CFQUANT_WEB_PORT"),
|
|
175
|
+
default=WEB_CONFIG.web_port(),
|
|
176
|
+
)
|
|
177
|
+
except Exception:
|
|
178
|
+
if not host:
|
|
179
|
+
host = "127.0.0.1"
|
|
180
|
+
if port is None:
|
|
181
|
+
port = 8765
|
|
182
|
+
return host, port
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _print_startup_banner(args):
|
|
186
|
+
host, port = _resolve_web_address(args)
|
|
187
|
+
command = "cfquant"
|
|
188
|
+
print("cfquant 本地服务启动中...")
|
|
189
|
+
print("包版本: %s | 核心版本: %s | Web版本: %s" % (_package_version(), CORE_VERSION, WEB_VERSION))
|
|
190
|
+
print("Web 控制台: %s" % _browser_url(host, port))
|
|
191
|
+
print("QMT 入口脚本目录: %s" % _qmt_scripts_source_dir())
|
|
192
|
+
print("查看脚本目录: %s qmt-scripts --show" % command)
|
|
193
|
+
print(r"导出 QMT 入口脚本: %s qmt-scripts --output D:\QMT\cfquant" % command)
|
|
194
|
+
|
|
195
|
+
|
|
130
196
|
def _wait_and_open_browser(host, port):
|
|
131
197
|
connect_host = str(host or "").strip()
|
|
132
198
|
if not connect_host or connect_host in ("0.0.0.0", "::"):
|
|
@@ -143,11 +209,14 @@ def _wait_and_open_browser(host, port):
|
|
|
143
209
|
|
|
144
210
|
|
|
145
211
|
def _serve(argv, prog="cfquant"):
|
|
212
|
+
_configure_console_encoding()
|
|
146
213
|
parser = _serve_parser(prog)
|
|
147
214
|
args = parser.parse_args(argv)
|
|
148
215
|
_apply_web_environment(args)
|
|
149
216
|
if args.dry_run:
|
|
217
|
+
print("cfquant 启动参数预览")
|
|
150
218
|
print("cfquant package=%s core=%s web=%s" % (_package_version(), CORE_VERSION, WEB_VERSION))
|
|
219
|
+
print("QMT 入口脚本目录=%s" % _qmt_scripts_source_dir())
|
|
151
220
|
for key in (
|
|
152
221
|
"CFQUANT_HOME",
|
|
153
222
|
"CFQUANT_RUNTIME_DIR",
|
|
@@ -169,18 +238,9 @@ def _serve(argv, prog="cfquant"):
|
|
|
169
238
|
server_args.extend(["--host", args.host])
|
|
170
239
|
if args.port:
|
|
171
240
|
server_args.extend(["--port", str(args.port)])
|
|
241
|
+
_print_startup_banner(args)
|
|
172
242
|
if args.open_browser:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
host = args.host or os.environ.get("CFQUANT_WEB_HOST")
|
|
176
|
-
if not host:
|
|
177
|
-
host = "0.0.0.0" if WEB_CONFIG.allow_remote() else "127.0.0.1"
|
|
178
|
-
port = args.port
|
|
179
|
-
if port is None:
|
|
180
|
-
port = normalize_web_port(
|
|
181
|
-
os.environ.get("CFQUANT_WEB_PORT"),
|
|
182
|
-
default=WEB_CONFIG.web_port(),
|
|
183
|
-
)
|
|
243
|
+
host, port = _resolve_web_address(args)
|
|
184
244
|
thread = threading.Thread(target=_wait_and_open_browser, args=(host, port))
|
|
185
245
|
thread.daemon = True
|
|
186
246
|
thread.start()
|
|
@@ -196,27 +256,66 @@ def _qmt_scripts_source_dir():
|
|
|
196
256
|
def _qmt_scripts_parser():
|
|
197
257
|
parser = argparse.ArgumentParser(
|
|
198
258
|
prog="cfquant qmt-scripts",
|
|
199
|
-
description="
|
|
259
|
+
description="查看、打开或导出当前 cfquant 安装包内置的 QMT 入口脚本。",
|
|
200
260
|
)
|
|
201
|
-
parser.add_argument("--
|
|
202
|
-
parser.add_argument("--
|
|
261
|
+
parser.add_argument("--show", action="store_true", help="显示当前安装包内置的 QMT 脚本目录。")
|
|
262
|
+
parser.add_argument("--list", dest="list_files", action="store_true", help="列出内置 QMT 脚本文件。")
|
|
263
|
+
parser.add_argument("--open", dest="open_dir", action="store_true", help="在系统文件管理器中打开 QMT 脚本目录。")
|
|
264
|
+
parser.add_argument("--output", "-o", help="把 QMT 脚本导出到指定目录。")
|
|
265
|
+
parser.add_argument("--force", action="store_true", help="导出时覆盖目标目录中的同名文件。")
|
|
203
266
|
return parser
|
|
204
267
|
|
|
205
268
|
|
|
269
|
+
def _validate_qmt_scripts(source_dir):
|
|
270
|
+
missing = [name for name in QMT_SCRIPT_FILES if not (source_dir / name).is_file()]
|
|
271
|
+
if missing:
|
|
272
|
+
raise RuntimeError("当前 cfquant 安装包缺少 QMT 脚本: %s" % ", ".join(missing))
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _print_qmt_scripts_info(source_dir, list_files=False):
|
|
276
|
+
print("QMT 入口脚本目录: %s" % source_dir)
|
|
277
|
+
print("查看目录: cfquant qmt-scripts --open")
|
|
278
|
+
print(r"导出命令: cfquant qmt-scripts --output D:\QMT\cfquant")
|
|
279
|
+
if list_files:
|
|
280
|
+
print("内置脚本文件:")
|
|
281
|
+
for relative_name in QMT_SCRIPT_FILES:
|
|
282
|
+
print(" %s" % relative_name)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def _open_directory(path):
|
|
286
|
+
if os.name == "nt" and hasattr(os, "startfile"):
|
|
287
|
+
os.startfile(str(path)) # pylint: disable=no-member
|
|
288
|
+
return
|
|
289
|
+
command = "open" if sys.platform == "darwin" else "xdg-open"
|
|
290
|
+
if shutil.which(command) is None:
|
|
291
|
+
raise RuntimeError("当前系统未找到可用的文件管理器打开命令: %s" % command)
|
|
292
|
+
subprocess.Popen([command, str(path)])
|
|
293
|
+
|
|
294
|
+
|
|
206
295
|
def _export_qmt_scripts(argv):
|
|
207
296
|
parser = _qmt_scripts_parser()
|
|
208
297
|
args = parser.parse_args(argv)
|
|
298
|
+
source_dir = _qmt_scripts_source_dir()
|
|
299
|
+
_validate_qmt_scripts(source_dir)
|
|
300
|
+
|
|
301
|
+
if not args.output and not args.show and not args.list_files and not args.open_dir:
|
|
302
|
+
args.show = True
|
|
303
|
+
args.list_files = True
|
|
304
|
+
|
|
305
|
+
if args.show or args.list_files:
|
|
306
|
+
_print_qmt_scripts_info(source_dir, list_files=args.list_files)
|
|
307
|
+
if args.open_dir:
|
|
308
|
+
_open_directory(source_dir)
|
|
309
|
+
print("已打开 QMT 入口脚本目录: %s" % source_dir)
|
|
310
|
+
if not args.output:
|
|
311
|
+
return 0
|
|
312
|
+
|
|
209
313
|
output_dir = Path(_path(args.output))
|
|
210
314
|
if output_dir.exists() and not output_dir.is_dir():
|
|
211
|
-
parser.error("
|
|
212
|
-
|
|
213
|
-
source_dir = _qmt_scripts_source_dir()
|
|
214
|
-
missing = [name for name in QMT_SCRIPT_FILES if not (source_dir / name).is_file()]
|
|
215
|
-
if missing:
|
|
216
|
-
raise RuntimeError("installed cfquant package is missing QMT scripts: %s" % ", ".join(missing))
|
|
315
|
+
parser.error("输出路径不是目录: %s" % output_dir)
|
|
217
316
|
existing = [name for name in QMT_SCRIPT_FILES if (output_dir / name).exists()]
|
|
218
317
|
if existing and not args.force:
|
|
219
|
-
parser.error("
|
|
318
|
+
parser.error("目标目录已存在同名文件;如需覆盖请加 --force: %s" % ", ".join(existing))
|
|
220
319
|
|
|
221
320
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
222
321
|
for relative_name in QMT_SCRIPT_FILES:
|
|
@@ -224,7 +323,7 @@ def _export_qmt_scripts(argv):
|
|
|
224
323
|
target = output_dir / relative_name
|
|
225
324
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
226
325
|
shutil.copy2(str(source), str(target))
|
|
227
|
-
print("
|
|
326
|
+
print("已导出 %s 个 QMT 入口脚本到: %s" % (len(QMT_SCRIPT_FILES), output_dir))
|
|
228
327
|
return 0
|
|
229
328
|
|
|
230
329
|
|
|
@@ -232,8 +331,10 @@ def _print_version():
|
|
|
232
331
|
package_root = Path(__file__).resolve().parent
|
|
233
332
|
qmt_scripts_dir = _qmt_scripts_source_dir()
|
|
234
333
|
print(_version_text())
|
|
235
|
-
print("
|
|
236
|
-
print("
|
|
334
|
+
print("cfquant 包目录 %s" % package_root)
|
|
335
|
+
print("QMT 入口脚本目录 %s" % qmt_scripts_dir)
|
|
336
|
+
print("打开脚本目录 cfquant qmt-scripts --open")
|
|
337
|
+
print(r"导出脚本目录 cfquant qmt-scripts --output D:\QMT\cfquant")
|
|
237
338
|
return 0
|
|
238
339
|
|
|
239
340
|
|
|
@@ -243,6 +344,7 @@ def web_main(argv=None):
|
|
|
243
344
|
|
|
244
345
|
|
|
245
346
|
def main(argv=None):
|
|
347
|
+
_configure_console_encoding()
|
|
246
348
|
argv = list(sys.argv[1:] if argv is None else argv)
|
|
247
349
|
if not argv:
|
|
248
350
|
return _serve([])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cfquant
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: QMT local bridge and xtquant-compatible Python client.
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -27,6 +27,7 @@ Requires-Dist: pyzmq>=25; extra == "zmq"
|
|
|
27
27
|
<a href="https://github.com/95ge/cfquant/issues"><img alt="GitHub issues" src="https://img.shields.io/github/issues/95ge/cfquant?style=flat&logo=github&label=Issues" /></a>
|
|
28
28
|
<a href="https://github.com/95ge/cfquant/commits/main"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/95ge/cfquant?style=flat&logo=git&label=Last%20commit" /></a>
|
|
29
29
|
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat" /></a>
|
|
30
|
+
<a href="https://pypi.org/project/cfquant/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/cfquant?style=flat&logo=pypi&logoColor=white" /></a>
|
|
30
31
|
<img alt="Python 3.8 to 3.12" src="https://img.shields.io/badge/Python-3.8--3.12-blue?style=flat&logo=python&logoColor=white" />
|
|
31
32
|
</p>
|
|
32
33
|
|
|
@@ -50,22 +51,80 @@ Requires-Dist: pyzmq>=25; extra == "zmq"
|
|
|
50
51
|
- 已安装并登录大 QMT
|
|
51
52
|
- Python `3.8` - `3.12`,生产环境优先使用 `3.10` 或 `3.12`
|
|
52
53
|
|
|
53
|
-
###
|
|
54
|
+
### 安装方式
|
|
55
|
+
|
|
56
|
+
#### 方式一:源码包部署(推荐)
|
|
57
|
+
|
|
58
|
+
新用户和生产环境优先使用源码包部署。原因很简单:cfquant 的 Web 控制台、QMT 入口脚本和本地配置是一起工作的,源码包保留完整项目目录,后续在网页里检查更新、更新 Web、回滚版本、提示 QMT 入口脚本变更都更方便。
|
|
54
59
|
|
|
55
60
|
1. 将项目解压到固定目录,例如 `D:\cfquant`。
|
|
56
61
|
2. 在项目目录安装依赖:
|
|
57
62
|
|
|
58
63
|
```powershell
|
|
59
64
|
cd D:\cfquant
|
|
60
|
-
pip install -r requirements.txt
|
|
65
|
+
python -m pip install -r requirements.txt
|
|
61
66
|
```
|
|
62
67
|
|
|
63
|
-
3. 运行
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
3. 运行 `start_cfquant.bat`。
|
|
69
|
+
|
|
70
|
+
启动后打开 <http://127.0.0.1:8765/>,按网页中的“新手初始化向导”完成账号、模式和 QMT 目录配置。然后在 QMT 中加载对应的入口脚本,回到网页验证资金、持仓、委托和行情。
|
|
71
|
+
|
|
72
|
+
重点:
|
|
73
|
+
|
|
74
|
+
- 源码部署后,网页里的“版本/更新”功能会按完整项目目录更新,适合从官网或 GitHub 拉取新版本。
|
|
75
|
+
- 更新时会尽量保留本地配置、数据库、日志和运行目录,便于日常升级和回滚。
|
|
76
|
+
- 如果新版本修改了 `qmt_scripts/` 里的入口脚本,网页会提示你重新更新 QMT 侧脚本并重启对应 QMT 策略。
|
|
77
|
+
- 建议把源码目录固定下来,例如 `D:\cfquant`,不要频繁挪动目录。
|
|
66
78
|
|
|
67
79
|
新用户建议先使用**通用模式**。一个 QMT 加载一个入口脚本即可完成大多数部署。
|
|
68
80
|
|
|
81
|
+
#### 方式二:PyPI 安装(仅推荐库调用或临时体验)
|
|
82
|
+
|
|
83
|
+
PyPI 适合外部 Python 策略只安装 `cfquant` 库,或者临时体验命令行启动方式;不建议把它作为完整 Web 部署的主要方式。pip 安装后的项目文件位于当前 Python 环境的 `site-packages`,网页里的项目更新、源码回滚和入口脚本同步不如源码包部署直观。
|
|
84
|
+
|
|
85
|
+
```powershell
|
|
86
|
+
python -m pip install -U cfquant
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
After installation, you can start the local Web Console:
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
cfquant --open-browser
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
如果使用 pip 安装,QMT 侧仍需要加载入口脚本。查看 pip 包内置的 QMT 入口脚本目录:
|
|
96
|
+
|
|
97
|
+
```powershell
|
|
98
|
+
cfquant qmt-scripts
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
在 Windows 资源管理器中打开脚本目录:
|
|
102
|
+
|
|
103
|
+
```powershell
|
|
104
|
+
cfquant qmt-scripts --open
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
把入口脚本复制到 QMT 可加载目录:
|
|
108
|
+
|
|
109
|
+
```powershell
|
|
110
|
+
cfquant qmt-scripts --output D:\QMT\cfquant
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
后续升级 pip 包需要回到命令行执行:
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
python -m pip install -U cfquant
|
|
117
|
+
cfquant qmt-scripts --output D:\QMT\cfquant --force
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
升级后建议重启本地 `cfquant` 服务,并在 QMT 中重新加载入口脚本,确保 Web、本地 Python 库和 QMT 侧入口属于同一版本。
|
|
121
|
+
|
|
122
|
+
验证安装版本和脚本目录:
|
|
123
|
+
|
|
124
|
+
```powershell
|
|
125
|
+
cfquant version
|
|
126
|
+
```
|
|
127
|
+
|
|
69
128
|
## 模式选择
|
|
70
129
|
|
|
71
130
|
| 模式 | QMT 入口 | 适用场景 |
|
|
@@ -78,7 +137,7 @@ Requires-Dist: pyzmq>=25; extra == "zmq"
|
|
|
78
137
|
|
|
79
138
|
## Python 接入
|
|
80
139
|
|
|
81
|
-
从 PyPI
|
|
140
|
+
从 PyPI 安装并在外部策略中调用:
|
|
82
141
|
|
|
83
142
|
```powershell
|
|
84
143
|
pip install cfquant
|
|
@@ -95,22 +154,23 @@ print(tick)
|
|
|
95
154
|
|
|
96
155
|
`cfquant` 默认使用 `transport=auto`,通常不需要手动配置通信通道。完整导入方式、路由规则和特殊部署方式见[外部 Python 接入](docs/外部Python接入.md)。
|
|
97
156
|
|
|
98
|
-
## Web
|
|
157
|
+
## Web Console
|
|
99
158
|
|
|
100
|
-
Web
|
|
159
|
+
The Web Console provides account binding, cash and positions, order fills, order placement and cancellation, market subscriptions, API debugging, deployment guides, and update management.
|
|
101
160
|
|
|
102
|
-
|
|
161
|
+
Common scripts:
|
|
103
162
|
|
|
104
163
|
```text
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
164
|
+
start_cfquant.bat Start
|
|
165
|
+
stop_cfquant.bat Stop
|
|
166
|
+
restart_cfquant.bat Restart
|
|
108
167
|
```
|
|
109
168
|
|
|
110
169
|
## 文档
|
|
111
170
|
|
|
112
171
|
| 需求 | 文档 |
|
|
113
172
|
|---|---|
|
|
173
|
+
| QMT 综合部署教程 | [QMT 部署教程](docs/QMT部署教程.md) |
|
|
114
174
|
| 通用模式部署 | [通用模式部署指南](docs/通用模式部署指南.md) |
|
|
115
175
|
| 极致模式部署 | [极致模式部署指南](docs/极致模式部署指南.md) |
|
|
116
176
|
| 高级模式部署 | [高级模式部署指南](docs/高级模式部署指南.md) |
|
|
@@ -122,7 +182,7 @@ Web 控制台提供账号绑定、资金持仓、委托成交、下单撤单、
|
|
|
122
182
|
| 日志、更新和回滚 | [运维与更新](docs/运维与更新.md) |
|
|
123
183
|
| 版本变化 | [版本日志](docs/版本日志.md) |
|
|
124
184
|
|
|
125
|
-
|
|
185
|
+
More detailed tutorials are also available on the Web Console "Tutorials" page.
|
|
126
186
|
|
|
127
187
|
## Star History
|
|
128
188
|
|
|
@@ -82,14 +82,4 @@ web_dashboard/image/qmt_deploy/image-6.png
|
|
|
82
82
|
web_dashboard/image/qmt_deploy/image-7.png
|
|
83
83
|
web_dashboard/image/qmt_deploy/image-8.png
|
|
84
84
|
web_dashboard/image/qmt_deploy/image-9.png
|
|
85
|
-
web_dashboard/image/通用模式部署指南/image-1.png
|
|
86
|
-
web_dashboard/image/通用模式部署指南/image-2.png
|
|
87
|
-
web_dashboard/image/通用模式部署指南/image-3.png
|
|
88
|
-
web_dashboard/image/通用模式部署指南/image.png
|
|
89
|
-
web_dashboard/image/部署指南/1783479325179.png
|
|
90
|
-
web_dashboard/image/部署指南/1783479745262.png
|
|
91
|
-
web_dashboard/image/部署指南/1783480178700.png
|
|
92
|
-
web_dashboard/image/部署指南/1783480428759.png
|
|
93
|
-
web_dashboard/image/部署指南/1783489807217.png
|
|
94
|
-
web_dashboard/image/部署指南/1783490503491.png
|
|
95
85
|
web_dashboard/vendor/mermaid.min.js
|
|
@@ -7992,7 +7992,7 @@ def stop_lttx_server(full_exit=False):
|
|
|
7992
7992
|
return {
|
|
7993
7993
|
"stopped": False,
|
|
7994
7994
|
"blocked": True,
|
|
7995
|
-
"reason": "LTtx 会在 Web 重启和定时重启期间保持运行;请使用
|
|
7995
|
+
"reason": "LTtx 会在 Web 重启和定时重启期间保持运行;请使用 stop_cfquant.bat 完整退出时再停止 LTtx。",
|
|
7996
7996
|
"status": before,
|
|
7997
7997
|
}
|
|
7998
7998
|
if not before["running"]:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const FRONTEND_VERSION = '
|
|
1
|
+
const FRONTEND_VERSION = 'web_20260904_11';
|
|
2
2
|
|
|
3
3
|
const state = {
|
|
4
4
|
accountId: '',
|
|
@@ -6851,7 +6851,7 @@ function renderLttxStatus(data) {
|
|
|
6851
6851
|
} else if (!data) {
|
|
6852
6852
|
runtime.textContent = 'LTtx 状态未知';
|
|
6853
6853
|
} else {
|
|
6854
|
-
runtime.textContent = `LTtx 未运行,cfquant Python 库自动发现不可用;可通过网页或 cfquant
|
|
6854
|
+
runtime.textContent = `LTtx 未运行,cfquant Python 库自动发现不可用;可通过网页或 cfquant\\start_cfquant.bat 启动。`;
|
|
6855
6855
|
}
|
|
6856
6856
|
}
|
|
6857
6857
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>cfquant 控制台</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
8
|
-
<link rel="stylesheet" href="/styles.css?v=
|
|
8
|
+
<link rel="stylesheet" href="/styles.css?v=web_20260904_11">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="webAuthOverlay" class="auth-overlay hidden" aria-live="polite">
|
|
@@ -1439,7 +1439,7 @@
|
|
|
1439
1439
|
<div class="guide-section">
|
|
1440
1440
|
<h3>快速开始</h3>
|
|
1441
1441
|
<ol class="guide-list detailed">
|
|
1442
|
-
<li><strong>启动服务。</strong>运行 <code
|
|
1442
|
+
<li><strong>启动服务。</strong>运行 <code>start_cfquant.bat</code>,或执行 <code>cfquant --open-browser</code>。</li>
|
|
1443
1443
|
<li><strong>完成初始化。</strong>填写资金账号、账户类型、QMT <code>bin.x64</code> 目录和运行模式。</li>
|
|
1444
1444
|
<li><strong>部署 QMT。</strong>按“QMT 部署教程”复制核心包和入口脚本。</li>
|
|
1445
1445
|
<li><strong>启动脚本。</strong>通用模式启动一个入口;高级模式分别启动普通端和极速交易端。</li>
|
|
@@ -1535,7 +1535,7 @@ configure(transport="ctypes", pipe_name=r"\\.\pipe\cfquant_pipe_hub")
|
|
|
1535
1535
|
<div class="deploy-primer-grid">
|
|
1536
1536
|
<div>
|
|
1537
1537
|
<strong>1. 先启动本地服务</strong>
|
|
1538
|
-
<span>通过 <code
|
|
1538
|
+
<span>通过 <code>start_cfquant.bat</code> 或 <code>cfquant --open-browser</code> 打开 Web 控制台,默认地址是 <code>http://127.0.0.1:8765/</code>。</span>
|
|
1539
1539
|
</div>
|
|
1540
1540
|
<div>
|
|
1541
1541
|
<strong>2. 再准备 QMT 环境</strong>
|
|
@@ -2312,6 +2312,6 @@ configure(transport="ctypes", pipe_name=r"\\.\pipe\cfquant_pipe_hub")
|
|
|
2312
2312
|
</div>
|
|
2313
2313
|
|
|
2314
2314
|
<script src="/vendor/mermaid.min.js?v=10.9.1"></script>
|
|
2315
|
-
<script src="/app.js?v=
|
|
2315
|
+
<script src="/app.js?v=web_20260904_11"></script>
|
|
2316
2316
|
</body>
|
|
2317
2317
|
</html>
|
cfquant-0.2.0/cfquant/version.py
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783479325179.png
DELETED
|
Binary file
|
cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783479745262.png
DELETED
|
Binary file
|
cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783480178700.png
DELETED
|
Binary file
|
cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783480428759.png
DELETED
|
Binary file
|
cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783489807217.png
DELETED
|
Binary file
|
cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783490503491.png
DELETED
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|