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.
Files changed (98) hide show
  1. {cfquant-0.2.0 → cfquant-0.2.1}/PKG-INFO +74 -14
  2. {cfquant-0.2.0 → cfquant-0.2.1}/README.md +73 -13
  3. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/cli.py +147 -45
  4. cfquant-0.2.1/cfquant/version.py +5 -0
  5. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/PKG-INFO +74 -14
  6. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/SOURCES.txt +0 -10
  7. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant_web_server.py +1 -1
  8. {cfquant-0.2.0 → cfquant-0.2.1}/pyproject.toml +1 -1
  9. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/app.js +2 -2
  10. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/index.html +4 -4
  11. cfquant-0.2.0/cfquant/version.py +0 -5
  12. 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
  13. 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
  14. 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
  15. 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
  16. cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783479325179.png +0 -0
  17. cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783479745262.png +0 -0
  18. cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783480178700.png +0 -0
  19. cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783480428759.png +0 -0
  20. cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783489807217.png +0 -0
  21. cfquant-0.2.0/web_dashboard/image//351/203/250/347/275/262/346/214/207/345/215/227/1783490503491.png +0 -0
  22. {cfquant-0.2.0 → cfquant-0.2.1}/LICENSE +0 -0
  23. {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/__init__.py +0 -0
  24. {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/Config.txt +0 -0
  25. {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/LTtx_server.py +0 -0
  26. {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/__init__.py +0 -0
  27. {cfquant-0.2.0 → cfquant-0.2.1}/LTtx/tx/tx.py +0 -0
  28. {cfquant-0.2.0 → cfquant-0.2.1}/MANIFEST.in +0 -0
  29. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/__init__.py +0 -0
  30. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/account_routing.py +0 -0
  31. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/channels.py +0 -0
  32. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/client.py +0 -0
  33. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/config.py +0 -0
  34. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/hub.py +0 -0
  35. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/logging_i18n.py +0 -0
  36. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/normal_bridge.py +0 -0
  37. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_bridge.py +0 -0
  38. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_client.py +0 -0
  39. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_hub.py +0 -0
  40. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/pipe_transport.py +0 -0
  41. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/protocol.py +0 -0
  42. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/qmt_bridge.py +0 -0
  43. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/runtime_report.py +0 -0
  44. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/tx.py +0 -0
  45. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/tx_trade_bridge.py +0 -0
  46. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xtconstant.py +0 -0
  47. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xtdata.py +0 -0
  48. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xttrader.py +0 -0
  49. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant/xttype.py +0 -0
  50. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/dependency_links.txt +0 -0
  51. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/entry_points.txt +0 -0
  52. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/requires.txt +0 -0
  53. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant.egg-info/top_level.txt +0 -0
  54. {cfquant-0.2.0 → cfquant-0.2.1}/cfquant_pipe_hub.py +0 -0
  55. {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT.py +0 -0
  56. {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +0 -0
  57. {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT_LITE.py +0 -0
  58. {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/CFQUANT_TRADE_LOWLAT.py +0 -0
  59. {cfquant-0.2.0 → cfquant-0.2.1}/qmt_scripts/__init__.py +0 -0
  60. {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
  61. {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
  62. {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
  63. {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
  64. {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
  65. {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
  66. {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
  67. {cfquant-0.2.0 → cfquant-0.2.1}/requirements.txt +0 -0
  68. {cfquant-0.2.0 → cfquant-0.2.1}/setup.cfg +0 -0
  69. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/__init__.py +0 -0
  70. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/amber-pulse.svg +0 -0
  71. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/copper-grid.svg +0 -0
  72. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/market-blue.svg +0 -0
  73. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/rose-circuit.svg +0 -0
  74. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/signal-green.svg +0 -0
  75. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/slate-wave.svg +0 -0
  76. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/teal-orbit.svg +0 -0
  77. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/avatars/violet-node.svg +0 -0
  78. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/favicon.svg +0 -0
  79. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-10.png +0 -0
  80. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-11.png +0 -0
  81. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-12.png +0 -0
  82. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-13.png +0 -0
  83. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-14.png +0 -0
  84. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-15.png +0 -0
  85. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-16.png +0 -0
  86. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-17.png +0 -0
  87. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-18.png +0 -0
  88. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-19.png +0 -0
  89. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-20.png +0 -0
  90. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-21.png +0 -0
  91. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-4.png +0 -0
  92. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-5.png +0 -0
  93. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-6.png +0 -0
  94. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-7.png +0 -0
  95. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-8.png +0 -0
  96. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/image/qmt_deploy/image-9.png +0 -0
  97. {cfquant-0.2.0 → cfquant-0.2.1}/web_dashboard/styles.css +0 -0
  98. {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.0
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. 运行 `启动cfquant.bat`。
64
- 4. 打开 <http://127.0.0.1:8765/>,按网页中的“新手初始化向导”完成账号、模式和 QMT 目录配置。
65
- 5. 在 QMT 中加载对应的入口脚本,回到网页验证资金、持仓、委托和行情。
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
- 启动cfquant.bat 启动
106
- 停止cfquant.bat 停止
107
- 重启cfquant.bat 重启
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
- 更详细的图文教程也可以直接在 Web 控制台的“教程”页面查看。
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. 运行 `启动cfquant.bat`。
43
- 4. 打开 <http://127.0.0.1:8765/>,按网页中的“新手初始化向导”完成账号、模式和 QMT 目录配置。
44
- 5. 在 QMT 中加载对应的入口脚本,回到网页验证资金、持仓、委托和行情。
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
- 启动cfquant.bat 启动
85
- 停止cfquant.bat 停止
86
- 重启cfquant.bat 重启
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
- 更详细的图文教程也可以直接在 Web 控制台的“教程”页面查看。
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
- return metadata.version("cfquant")
64
+ dist = metadata.distribution("cfquant")
65
+ return dist.version
39
66
  except Exception:
40
- return "unknown"
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
- "Commands:\n"
83
- " cfquant pipe-hub [options] Start only the named-pipe hub.\n"
84
- " cfquant qmt-scripts --output DIRECTORY Export bundled QMT entry scripts.\n"
85
- " cfquant version Show installed package details.\n"
86
- "Use '%s' for dashboard options." % help_command
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 = "Use '%s' for dashboard options." % help_command
120
+ epilog = "使用 '%s' 查看 Web 启动参数。" % help_command
90
121
  parser = argparse.ArgumentParser(
91
122
  prog=prog,
92
- description="Start the cfquant local web dashboard.",
123
+ description="启动 cfquant 本地 Web 控制台。",
93
124
  epilog=epilog,
94
125
  formatter_class=argparse.RawDescriptionHelpFormatter,
95
126
  )
96
- parser.add_argument("--host", help="Web bind address. Defaults to localhost or saved configuration.")
97
- parser.add_argument("--port", type=_port, help="Web listen port. Defaults to saved configuration or 8765.")
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="Writable cfquant state directory for runtime data, configuration, and logs.",
133
+ help="cfquant 可写运行目录,用于保存配置、数据库、日志和状态文件。",
103
134
  )
104
- parser.add_argument("--runtime-dir", help="Override the runtime subdirectory.")
105
- parser.add_argument("--log-dir", help="Override the log directory.")
106
- parser.add_argument("--config", help="Path to the web configuration JSON file.")
107
- parser.add_argument("--pipe-name", help=r"Override the QMT named pipe, e.g. \\.\pipe\cfquant_pipe_hub.")
108
- parser.add_argument("--lttx-host", help="LTtx host. Defaults to 127.0.0.1.")
109
- parser.add_argument("--lttx-port", type=_port, help="LTtx port. Defaults to 2049.")
110
- parser.add_argument("--account-id", help="Default account ID before the web setup wizard is completed.")
111
- parser.add_argument("--open-browser", action="store_true", help="Open the dashboard in the default browser after it is ready.")
112
- parser.add_argument("--dry-run", action="store_true", help="Print the effective startup settings without starting services.")
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
- from cfquant_web_server import WEB_CONFIG, normalize_web_port
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="Export the QMT entry scripts bundled with this cfquant installation.",
259
+ description="查看、打开或导出当前 cfquant 安装包内置的 QMT 入口脚本。",
200
260
  )
201
- parser.add_argument("--output", "-o", required=True, help="Destination directory for QMT scripts.")
202
- parser.add_argument("--force", action="store_true", help="Overwrite existing files in the destination.")
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("output path is not a directory: %s" % output_dir)
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("destination already has files; use --force to replace: %s" % ", ".join(existing))
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("Exported %s QMT files to %s" % (len(QMT_SCRIPT_FILES), output_dir))
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("package_root %s" % package_root)
236
- print("qmt_scripts %s" % qmt_scripts_dir)
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([])
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ """cfquant core version metadata."""
3
+
4
+ __version__ = "core_20260904_02"
5
+ WEB_VERSION = "web_20260904_11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cfquant
3
- Version: 0.2.0
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. 运行 `启动cfquant.bat`。
64
- 4. 打开 <http://127.0.0.1:8765/>,按网页中的“新手初始化向导”完成账号、模式和 QMT 目录配置。
65
- 5. 在 QMT 中加载对应的入口脚本,回到网页验证资金、持仓、委托和行情。
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
- 启动cfquant.bat 启动
106
- 停止cfquant.bat 停止
107
- 重启cfquant.bat 重启
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
- 更详细的图文教程也可以直接在 Web 控制台的“教程”页面查看。
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 重启和定时重启期间保持运行;请使用 停止cfquant.bat 完整退出时再停止 LTtx。",
7995
+ "reason": "LTtx 会在 Web 重启和定时重启期间保持运行;请使用 stop_cfquant.bat 完整退出时再停止 LTtx。",
7996
7996
  "status": before,
7997
7997
  }
7998
7998
  if not before["running"]:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cfquant"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "QMT local bridge and xtquant-compatible Python client."
9
9
  license = {text = "MIT"}
10
10
  readme = "README.md"
@@ -1,4 +1,4 @@
1
- const FRONTEND_VERSION = 'web_20260904_09';
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\\启动cfquant.bat 启动。`;
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=web_20260904_09">
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>启动cfquant.bat</code>,或执行 <code>cfquant --open-browser</code>。</li>
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>启动cfquant.bat</code> 或 <code>cfquant --open-browser</code> 打开 Web 控制台,默认地址是 <code>http://127.0.0.1:8765/</code>。</span>
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=web_20260904_09"></script>
2315
+ <script src="/app.js?v=web_20260904_11"></script>
2316
2316
  </body>
2317
2317
  </html>
@@ -1,5 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """cfquant core version metadata."""
3
-
4
- __version__ = "core_20260904_01"
5
- WEB_VERSION = "web_20260904_09"
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