cfquant 0.2.0__py3-none-any.whl

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 (90) hide show
  1. LTtx/__init__.py +2 -0
  2. LTtx/tx/Config.txt +8 -0
  3. LTtx/tx/LTtx_server.py +1177 -0
  4. LTtx/tx/__init__.py +5 -0
  5. LTtx/tx/tx.py +1935 -0
  6. cfquant/__init__.py +26 -0
  7. cfquant/account_routing.py +119 -0
  8. cfquant/channels.py +76 -0
  9. cfquant/cli.py +266 -0
  10. cfquant/client.py +365 -0
  11. cfquant/config.py +86 -0
  12. cfquant/hub.py +304 -0
  13. cfquant/logging_i18n.py +348 -0
  14. cfquant/normal_bridge.py +676 -0
  15. cfquant/pipe_bridge.py +249 -0
  16. cfquant/pipe_client.py +223 -0
  17. cfquant/pipe_hub.py +602 -0
  18. cfquant/pipe_transport.py +493 -0
  19. cfquant/protocol.py +238 -0
  20. cfquant/qmt_bridge.py +1081 -0
  21. cfquant/runtime_report.py +334 -0
  22. cfquant/tx.py +1898 -0
  23. cfquant/tx_trade_bridge.py +1905 -0
  24. cfquant/version.py +5 -0
  25. cfquant/xtconstant.py +262 -0
  26. cfquant/xtdata.py +462 -0
  27. cfquant/xttrader.py +955 -0
  28. cfquant/xttype.py +586 -0
  29. cfquant-0.2.0.dist-info/LICENSE +21 -0
  30. cfquant-0.2.0.dist-info/METADATA +144 -0
  31. cfquant-0.2.0.dist-info/RECORD +90 -0
  32. cfquant-0.2.0.dist-info/WHEEL +5 -0
  33. cfquant-0.2.0.dist-info/entry_points.txt +4 -0
  34. cfquant-0.2.0.dist-info/top_level.txt +6 -0
  35. cfquant_pipe_hub.py +45 -0
  36. cfquant_web_server.py +12137 -0
  37. qmt_scripts/CFQUANT.py +507 -0
  38. qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +830 -0
  39. qmt_scripts/CFQUANT_LITE.py +4928 -0
  40. qmt_scripts/CFQUANT_TRADE_LOWLAT.py +382 -0
  41. qmt_scripts/__init__.py +1 -0
  42. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_CTYPE_ALL_LOWLAT_SH.py +866 -0
  43. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_CTYPE_ALL_LOWLAT_SZ.py +866 -0
  44. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_LITE_SH.py +5020 -0
  45. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_LITE_SZ.py +5020 -0
  46. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_TRADE_LOWLAT_SH.py +436 -0
  47. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_TRADE_LOWLAT_SZ.py +436 -0
  48. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/readme.md +95 -0
  49. web_dashboard/__init__.py +1 -0
  50. web_dashboard/app.js +9847 -0
  51. web_dashboard/avatars/amber-pulse.svg +15 -0
  52. web_dashboard/avatars/copper-grid.svg +15 -0
  53. web_dashboard/avatars/market-blue.svg +15 -0
  54. web_dashboard/avatars/rose-circuit.svg +15 -0
  55. web_dashboard/avatars/signal-green.svg +15 -0
  56. web_dashboard/avatars/slate-wave.svg +15 -0
  57. web_dashboard/avatars/teal-orbit.svg +16 -0
  58. web_dashboard/avatars/violet-node.svg +15 -0
  59. web_dashboard/favicon.svg +5 -0
  60. web_dashboard/image/qmt_deploy/image-10.png +0 -0
  61. web_dashboard/image/qmt_deploy/image-11.png +0 -0
  62. web_dashboard/image/qmt_deploy/image-12.png +0 -0
  63. web_dashboard/image/qmt_deploy/image-13.png +0 -0
  64. web_dashboard/image/qmt_deploy/image-14.png +0 -0
  65. web_dashboard/image/qmt_deploy/image-15.png +0 -0
  66. web_dashboard/image/qmt_deploy/image-16.png +0 -0
  67. web_dashboard/image/qmt_deploy/image-17.png +0 -0
  68. web_dashboard/image/qmt_deploy/image-18.png +0 -0
  69. web_dashboard/image/qmt_deploy/image-19.png +0 -0
  70. web_dashboard/image/qmt_deploy/image-20.png +0 -0
  71. web_dashboard/image/qmt_deploy/image-21.png +0 -0
  72. web_dashboard/image/qmt_deploy/image-4.png +0 -0
  73. web_dashboard/image/qmt_deploy/image-5.png +0 -0
  74. web_dashboard/image/qmt_deploy/image-6.png +0 -0
  75. web_dashboard/image/qmt_deploy/image-7.png +0 -0
  76. web_dashboard/image/qmt_deploy/image-8.png +0 -0
  77. web_dashboard/image/qmt_deploy/image-9.png +0 -0
  78. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-1.png +0 -0
  79. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-2.png +0 -0
  80. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-3.png +0 -0
  81. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image.png +0 -0
  82. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783479325179.png +0 -0
  83. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783479745262.png +0 -0
  84. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783480178700.png +0 -0
  85. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783480428759.png +0 -0
  86. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783489807217.png +0 -0
  87. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783490503491.png +0 -0
  88. web_dashboard/index.html +2317 -0
  89. web_dashboard/styles.css +7817 -0
  90. web_dashboard/vendor/mermaid.min.js +2029 -0
@@ -0,0 +1,2317 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>cfquant 控制台</title>
7
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
8
+ <link rel="stylesheet" href="/styles.css?v=web_20260904_09">
9
+ </head>
10
+ <body>
11
+ <div id="webAuthOverlay" class="auth-overlay hidden" aria-live="polite">
12
+ <div class="login-shell" role="dialog" aria-modal="true" aria-labelledby="webAuthTitle">
13
+ <section class="login-showcase" aria-label="系统架构轮播">
14
+ <div class="login-brandline">
15
+ <div class="login-brandmark">cf</div>
16
+ <div>
17
+ <strong>cfquant</strong>
18
+ <span>QMT Bridge Console</span>
19
+ </div>
20
+ </div>
21
+ <div class="login-carousel" aria-live="off">
22
+ <article class="login-slide login-slide-1">
23
+ <div class="login-slide-copy">
24
+ <span>Architecture</span>
25
+ <h2>本地 Web 到 QMT 的交易与行情桥接</h2>
26
+ <p>统一处理鉴权、账号路由、行情订阅和交易请求,让外部程序通过稳定接口接入 QMT 能力。</p>
27
+ </div>
28
+ <div class="architecture-map" aria-hidden="true">
29
+ <div class="arch-node source">外部程序</div>
30
+ <div class="arch-link"></div>
31
+ <div class="arch-node web">cfquant Web</div>
32
+ <div class="arch-link"></div>
33
+ <div class="arch-node bridge">Socket / Pipe</div>
34
+ <div class="arch-link"></div>
35
+ <div class="arch-node qmt">QMT 终端</div>
36
+ </div>
37
+ </article>
38
+ <article class="login-slide login-slide-2">
39
+ <div class="login-slide-copy">
40
+ <span>Operations</span>
41
+ <h2>多账号运行配置集中管理</h2>
42
+ <p>默认账号、通用模式、高级模式和数据源状态集中呈现,减少部署和排障时的切换成本。</p>
43
+ </div>
44
+ <div class="login-metrics" aria-hidden="true">
45
+ <div><strong>HTTP</strong><span>外部接口</span></div>
46
+ <div><strong>WS</strong><span>回调推送</span></div>
47
+ <div><strong>QMT</strong><span>柜台链路</span></div>
48
+ </div>
49
+ </article>
50
+ <article class="login-slide login-slide-3">
51
+ <div class="login-slide-copy">
52
+ <span>Security</span>
53
+ <h2>管理员登录与自动会话保持</h2>
54
+ <p>首次使用创建管理员账号,后续自动登录;主动退出后回到登录界面,适合本机和局域网部署。</p>
55
+ </div>
56
+ <div class="login-security-grid" aria-hidden="true">
57
+ <div>加盐哈希</div>
58
+ <div>Token 会话</div>
59
+ <div>API Key</div>
60
+ <div>访问白名单</div>
61
+ </div>
62
+ </article>
63
+ </div>
64
+ <div class="login-carousel-dots" aria-hidden="true">
65
+ <span></span>
66
+ <span></span>
67
+ <span></span>
68
+ </div>
69
+ </section>
70
+ <section class="login-panel">
71
+ <div class="login-panel-head">
72
+ <span>安全入口</span>
73
+ <h1 id="webAuthTitle">登录 cfquant 控制台</h1>
74
+ <p>登录后可管理 QMT 桥接、行情订阅、交易请求和外部接口配置。</p>
75
+ </div>
76
+ <form id="webAuthForm" class="auth-form login-form">
77
+ <div class="login-form-card">
78
+ <label class="login-field wide" for="webAuthLoginUserInput">
79
+ <span class="login-field-label">管理员账号</span>
80
+ <span class="login-input-wrap login-input-account">
81
+ <input id="webAuthLoginUserInput" autocomplete="username" placeholder="admin">
82
+ </span>
83
+ </label>
84
+ <label class="login-field wide" for="webAuthLoginPasswordInput">
85
+ <span class="login-field-label">管理员密码</span>
86
+ <span class="login-input-wrap login-input-password">
87
+ <input id="webAuthLoginPasswordInput" type="password" autocomplete="current-password" placeholder="请输入密码">
88
+ </span>
89
+ </label>
90
+ <div class="login-session-note wide">
91
+ <strong>自动登录</strong>
92
+ <span>登录成功后保持会话,主动退出前不再要求输入密码。</span>
93
+ </div>
94
+ <button id="webAuthLoginBtn" class="primary login-submit wide" type="submit"><span>登录</span></button>
95
+ <span id="webAuthLoginStatus" class="metric-note login-status" role="status"></span>
96
+ </div>
97
+ </form>
98
+ <div class="login-footnote">
99
+ <strong>本地优先</strong>
100
+ <span>默认只监听本机地址,远程访问可在登录后进入设置页开启。</span>
101
+ </div>
102
+ </section>
103
+ </div>
104
+ </div>
105
+ <div id="setupOverlay" class="auth-overlay hidden" aria-live="polite">
106
+ <div class="auth-card setup-card">
107
+ <div class="setup-head">
108
+ <div>
109
+ <span class="setup-kicker">第一次启动</span>
110
+ <h2>先连接 QMT</h2>
111
+ <p>填写账号和目录,保存后进入系统。</p>
112
+ </div>
113
+ <span class="setup-required">首次配置</span>
114
+ </div>
115
+ <ol class="setup-steps" id="setupSteps" aria-label="初始化步骤">
116
+ <li class="active" data-setup-step="config">
117
+ <span class="setup-step-index">1</span>
118
+ <span class="setup-step-copy"><strong>填写</strong><em>账号与 QMT</em></span>
119
+ </li>
120
+ <li data-setup-step="identity">
121
+ <span class="setup-step-index">2</span>
122
+ <span class="setup-step-copy"><strong>保存</strong><em>写入本机配置</em></span>
123
+ </li>
124
+ <li data-setup-step="qmt">
125
+ <span class="setup-step-index">3</span>
126
+ <span class="setup-step-copy"><strong>进入</strong><em>启动项目</em></span>
127
+ </li>
128
+ </ol>
129
+ <form id="setupForm" class="auth-form">
130
+ <section id="setupAdminFields" class="setup-section setup-admin-fields">
131
+ <div class="setup-section-head">
132
+ <strong>管理员</strong>
133
+ <span>创建登录账号</span>
134
+ </div>
135
+ <div class="setup-fields-grid">
136
+ <label class="field">
137
+ <span>管理员账号</span>
138
+ <input id="setupAdminUsername" name="admin_username" autocomplete="username" placeholder="admin">
139
+ </label>
140
+ <label class="field">
141
+ <span>管理员密码</span>
142
+ <input id="setupAdminPassword" name="admin_password" type="password" autocomplete="new-password" placeholder="至少 6 位">
143
+ </label>
144
+ <label class="field">
145
+ <span>确认密码</span>
146
+ <input id="setupAdminPasswordConfirm" name="admin_password_confirm" type="password" autocomplete="new-password">
147
+ </label>
148
+ </div>
149
+ </section>
150
+ <section class="setup-section">
151
+ <div class="setup-section-head">
152
+ <strong>交易账号</strong>
153
+ <span>默认账号</span>
154
+ </div>
155
+ <div class="setup-fields-grid">
156
+ <label class="field">
157
+ <span>账号</span>
158
+ <input id="setupAccountId" name="account_id" autocomplete="off" placeholder="请输入资金账号">
159
+ </label>
160
+ <label class="field">
161
+ <span>账户类型</span>
162
+ <select id="setupAccountType" name="account_type">
163
+ <option value="STOCK">普通证券账户</option>
164
+ <option value="CREDIT">信用账户</option>
165
+ </select>
166
+ <small>信用账户选择信用类型</small>
167
+ </label>
168
+ </div>
169
+ </section>
170
+ <section class="setup-section">
171
+ <div class="setup-section-head">
172
+ <strong>QMT 连接</strong>
173
+ <span>目录建议填写 <code>bin.x64</code></span>
174
+ </div>
175
+ <div class="setup-fields-grid">
176
+ <label class="field wide">
177
+ <span>普通端 QMT 核心目录</span>
178
+ <input id="setupQmtDir" name="qmt_dir" autocomplete="off" placeholder="D:\国金证券QMT交易端\bin.x64">
179
+ <small>用于桥接和后续更新</small>
180
+ </label>
181
+ <label class="field wide">
182
+ <span>运行模式</span>
183
+ <select id="setupMode" name="mode">
184
+ <option value="ctypes">通用模式(推荐)</option>
185
+ <option value="lite">极致模式</option>
186
+ <option value="lttx">高级模式(两个 QMT)</option>
187
+ </select>
188
+ </label>
189
+ <label id="setupQmtTradeDirField" class="field wide hidden">
190
+ <span>极速交易端 QMT 核心目录</span>
191
+ <input id="setupQmtTradeDir" name="qmt_trade_dir" autocomplete="off" placeholder="D:\国金证券QMT交易端-交易端\bin.x64">
192
+ <small>高级模式需填写另一个 QMT 目录</small>
193
+ </label>
194
+ </div>
195
+ </section>
196
+ <div class="setup-actions">
197
+ <button class="primary" type="submit">保存并进入</button>
198
+ <span id="setupStatus" class="metric-note"></span>
199
+ </div>
200
+ </form>
201
+ </div>
202
+ </div>
203
+ <div class="admin-layout">
204
+ <aside class="sidebar">
205
+ <div class="side-brand">
206
+ <div class="brand-mark">cf</div>
207
+ <div class="brand-copy">
208
+ <strong>cfquant</strong>
209
+ <span>QMT Bridge</span>
210
+ </div>
211
+ <div id="versionWidget" class="version-widget" tabindex="0" aria-label="版本信息">
212
+ <button id="versionBadge" class="version-badge" type="button" aria-describedby="versionPopover" aria-expanded="false">
213
+ <span class="version-badge-head">
214
+ <span class="version-badge-state">
215
+ <span id="versionBadgeDot" class="version-dot"></span>
216
+ <span id="versionBadgeState">等待 QMT 上报</span>
217
+ </span>
218
+ <span class="version-badge-chevron" aria-hidden="true"></span>
219
+ </span>
220
+ <span class="version-badge-value">
221
+ <span>QMT 核心版本</span>
222
+ <strong id="versionBadgeLabel">--</strong>
223
+ </span>
224
+ <span id="versionBadgeEntry" class="version-badge-entry">入口脚本待上报</span>
225
+ <small id="versionBadgeMeta">运行脚本后会自动同步版本信息</small>
226
+ </button>
227
+ <div id="versionPopover" class="version-popover" role="tooltip">
228
+ <div class="version-popover-head">
229
+ <div>
230
+ <span>运行状态</span>
231
+ <strong>版本与部署</strong>
232
+ </div>
233
+ <span id="versionCheckState">未检查远端</span>
234
+ </div>
235
+ <div id="versionPopoverBody" class="version-popover-body">正在加载版本信息...</div>
236
+ </div>
237
+ </div>
238
+ </div>
239
+ <nav class="side-nav">
240
+ <button class="nav-item active" data-view="overview">首页</button>
241
+ <button class="nav-item" data-view="trade">交易</button>
242
+ <button class="nav-item" data-view="orders">委托</button>
243
+ <button class="nav-item" data-view="status">状态</button>
244
+ <button class="nav-item" data-view="bindings">绑定</button>
245
+ <button class="nav-item" data-view="callbacks">回调</button>
246
+ <button class="nav-item" data-view="api">接口</button>
247
+ <button class="nav-item" data-view="settings">设置</button>
248
+ <button class="nav-item" data-view="tutorial">教程</button>
249
+ </nav>
250
+ </aside>
251
+
252
+ <div class="main-area">
253
+ <header class="topbar">
254
+ <div>
255
+ <h1 id="viewTitle">首页</h1>
256
+ <div class="subline" id="clock">--</div>
257
+ </div>
258
+ <div class="status-strip">
259
+ <div class="status-pill" id="lttxStatus"><span></span><strong id="lttxStatusLabel">LTtx(库通信)</strong></div>
260
+ <div class="status-pill" id="normalStatus"><span></span><strong id="normalStatusLabel">通用查询通道</strong></div>
261
+ <div class="status-pill" id="tradeStatus"><span></span><strong id="tradeStatusLabel">通用交易通道</strong></div>
262
+ <div class="status-pill" id="transportStatus"><span></span><strong id="transportStatusLabel">通用模式</strong></div>
263
+ <div id="versionAlert" class="topbar-alert hidden" title="">版本探测失败,不影响交易和行情功能</div>
264
+ <button id="topbarProfileBtn" class="topbar-profile" type="button" title="个人资料">
265
+ <img id="topbarAvatarImg" src="/avatars/market-blue.svg" alt="">
266
+ <span id="topbarProfileName">管理员</span>
267
+ </button>
268
+ <button id="webAuthLogoutBtn" class="topbar-logout hidden" type="button">退出登录</button>
269
+ </div>
270
+ </header>
271
+
272
+ <main class="shell">
273
+ <section class="toolbar">
274
+ <label id="bridgeField" class="field compact">
275
+ <span>内部通道</span>
276
+ <select id="bridgeSelect"></select>
277
+ </label>
278
+ <label class="field compact">
279
+ <span>账号</span>
280
+ <select id="accountInput" aria-label="账号"></select>
281
+ </label>
282
+ <button id="switchAccountBtn" class="primary" type="button">切换账号</button>
283
+ <button id="openOnboardingGlobalBtn" type="button">新手引导</button>
284
+ <label id="queryChannelField" class="field compact">
285
+ <span>查询通道</span>
286
+ <select id="queryChannel">
287
+ <option value="normal">普通 QMT 请求</option>
288
+ <option value="trade">交易端请求</option>
289
+ </select>
290
+ </label>
291
+ <label id="tradeChannelField" class="field compact">
292
+ <span>交易通道</span>
293
+ <select id="tradeChannel">
294
+ <option value="trade">交易端请求</option>
295
+ <option value="normal">普通 QMT 请求</option>
296
+ </select>
297
+ </label>
298
+ <button id="refreshBtn" class="primary">刷新</button>
299
+ <label id="autoRefreshField" class="toggle">
300
+ <input id="autoRefresh" type="checkbox" checked>
301
+ <span>回调委托</span>
302
+ </label>
303
+ </section>
304
+
305
+ <section class="grid">
306
+ <div class="panel span-12 view-panel view-overview home-intro-panel">
307
+ <div class="home-intro">
308
+ <div class="home-intro-copy">
309
+ <span class="home-kicker">QMT 能力转接控制台</span>
310
+ <h2>用 cfquant 替代 miniqmt,把大 QMT 的交易、行情和多账号能力统一接出来。</h2>
311
+ <p>项目在本机启动 Web 服务,外部 Python 默认先通过 LTtx 发现 Web 路由,网页请求直接进入 Web;两者最终都由账号配置自动路由到通用端或高级端。新用户优先使用通用模式,一个 QMT 加载一个 ctypes 文件即可完成资金、持仓、委托、下单、撤单和回调验证。</p>
312
+ <div class="home-intro-tags" aria-label="核心能力">
313
+ <span>通用模式单文件部署</span>
314
+ <span>高级模式低延迟交易</span>
315
+ <span>LTtx 自动发现</span>
316
+ <span>PipeHub 通用后端</span>
317
+ <span>多账号自动路由</span>
318
+ <span>WebSocket 回调</span>
319
+ </div>
320
+ <div class="home-intro-actions">
321
+ <button class="primary" type="button" data-view-jump="tutorial" data-guide="web_console">查看网页端教程</button>
322
+ <button type="button" data-view-jump="tutorial" data-guide="project">查看架构说明</button>
323
+ </div>
324
+ </div>
325
+ </div>
326
+ </div>
327
+
328
+ <div class="panel span-4 view-panel view-overview view-trade asset-panel">
329
+ <div class="panel-head">
330
+ <h2>资产</h2>
331
+ <span id="assetLatency" class="metric-note"></span>
332
+ </div>
333
+ <div class="asset-grid" id="assetGrid">
334
+ <div><span>总资产</span><strong>--</strong></div>
335
+ <div><span>可用资金</span><strong>--</strong></div>
336
+ <div><span>总市值</span><strong>--</strong></div>
337
+ <div><span>持仓盈亏</span><strong>--</strong></div>
338
+ </div>
339
+ </div>
340
+
341
+ <div class="panel span-4 view-panel view-overview view-status home-status-panel">
342
+ <div class="panel-head">
343
+ <h2>操作</h2>
344
+ <span id="lastRefresh" class="metric-note"></span>
345
+ </div>
346
+ <div class="action-row">
347
+ <button id="lttxStartBtn">启动 LTtx</button>
348
+ <button id="lttxStopBtn" disabled>完整退出停止</button>
349
+ <button id="statusBtn">状态检查</button>
350
+ <button id="ordersBtn">刷新委托</button>
351
+ </div>
352
+ <div id="lttxRuntime" class="runtime-note"></div>
353
+ <div class="runtime-status-grid" aria-label="LTtx 运行状态">
354
+ <div><span>LTtx 地址</span><strong id="lttxAddress">--</strong></div>
355
+ <div><span>LTtx PID</span><strong id="lttxPid">--</strong></div>
356
+ <div><span>cfquant 库</span><strong id="lttxLibraryStatus">--</strong></div>
357
+ <div><span>重启策略</span><strong id="lttxRestartPolicy">保留</strong></div>
358
+ </div>
359
+ <div class="remote-access-box">
360
+ <div id="serverAccessStatus" class="runtime-note"></div>
361
+ <button id="openAccessSettingsBtn" type="button">访问设置</button>
362
+ </div>
363
+ <div class="pair-box">
364
+ <div class="pair-head">
365
+ <strong>账号配置</strong>
366
+ <span id="accountPairCount" class="metric-note"></span>
367
+ </div>
368
+ <div class="pair-actions">
369
+ <button id="savePairBtn">保存当前账号</button>
370
+ <button id="removePairBtn">删除当前账号</button>
371
+ </div>
372
+ <div id="accountPairList" class="pair-list"></div>
373
+ </div>
374
+ <div class="overview-binding-box">
375
+ <div class="pair-head">
376
+ <strong>绑定实时状态</strong>
377
+ <span id="overviewBindingCount" class="metric-note"></span>
378
+ </div>
379
+ <div class="mini-table-wrap">
380
+ <table>
381
+ <thead>
382
+ <tr>
383
+ <th>账号</th>
384
+ <th>首选模式</th>
385
+ <th>实际模式</th>
386
+ <th>QMT 目录</th>
387
+ <th>数据源</th>
388
+ </tr>
389
+ </thead>
390
+ <tbody id="overviewBindingBody"></tbody>
391
+ </table>
392
+ </div>
393
+ </div>
394
+ </div>
395
+
396
+ <div class="panel span-8 view-panel view-overview positions-panel">
397
+ <div class="panel-head">
398
+ <h2>持仓</h2>
399
+ <span id="positionCount" class="metric-note"></span>
400
+ </div>
401
+ <div class="table-wrap">
402
+ <table>
403
+ <thead>
404
+ <tr>
405
+ <th>代码</th>
406
+ <th>名称</th>
407
+ <th class="num">持仓</th>
408
+ <th class="num">可用</th>
409
+ <th class="num">成本价</th>
410
+ <th class="num">市值</th>
411
+ <th class="num">盈亏</th>
412
+ </tr>
413
+ </thead>
414
+ <tbody id="positionsBody"></tbody>
415
+ </table>
416
+ </div>
417
+ </div>
418
+
419
+ <div class="panel span-12 view-panel view-overview view-orders orders-panel">
420
+ <div class="panel-head">
421
+ <h2>实时委托</h2>
422
+ <div class="head-actions">
423
+ <span id="orderCount" class="metric-note"></span>
424
+ <button id="cancelSelectedBtn">撤选中</button>
425
+ </div>
426
+ </div>
427
+ <div class="table-wrap compact-table">
428
+ <table>
429
+ <thead>
430
+ <tr>
431
+ <th><input id="selectAllOrders" type="checkbox"></th>
432
+ <th>序号</th>
433
+ <th><button class="sort-header" type="button" data-order-sort="time">时间<span class="sort-mark" aria-hidden="true"></span></button></th>
434
+ <th><button class="sort-header" type="button" data-order-sort="source">来源<span class="sort-mark" aria-hidden="true"></span></button></th>
435
+ <th><button class="sort-header" type="button" data-order-sort="code">代码<span class="sort-mark" aria-hidden="true"></span></button></th>
436
+ <th><button class="sort-header" type="button" data-order-sort="name">名称<span class="sort-mark" aria-hidden="true"></span></button></th>
437
+ <th class="num"><button class="sort-header" type="button" data-order-sort="volume">数量<span class="sort-mark" aria-hidden="true"></span></button></th>
438
+ <th class="num"><button class="sort-header" type="button" data-order-sort="traded">成交<span class="sort-mark" aria-hidden="true"></span></button></th>
439
+ <th><button class="sort-header" type="button" data-order-sort="status">状态<span class="sort-mark" aria-hidden="true"></span></button></th>
440
+ <th>最后回调</th>
441
+ <th><button class="sort-header" type="button" data-order-sort="id">编号<span class="sort-mark" aria-hidden="true"></span></button></th>
442
+ </tr>
443
+ </thead>
444
+ <tbody id="ordersBody"></tbody>
445
+ </table>
446
+ </div>
447
+ </div>
448
+
449
+ <div class="panel span-6 view-panel view-trade trade-ticket">
450
+ <div class="panel-head">
451
+ <h2>提交委托</h2>
452
+ <span id="orderHint" class="metric-note"></span>
453
+ </div>
454
+ <form id="orderForm" class="form-grid">
455
+ <div class="trade-tabs wide">
456
+ <button class="trade-tab active" type="button" data-side="buy">买入</button>
457
+ <button class="trade-tab" type="button" data-side="sell">卖出</button>
458
+ </div>
459
+ <input name="side" type="hidden" value="buy">
460
+ <label class="field">
461
+ <span>代码</span>
462
+ <input name="stock_code" placeholder="000001.SZ" autocomplete="off">
463
+ </label>
464
+ <label class="field">
465
+ <span>价格</span>
466
+ <input name="price" type="number" min="0" step="0.001">
467
+ </label>
468
+ <label class="field">
469
+ <span>数量</span>
470
+ <input name="volume" type="number" min="100" step="100">
471
+ </label>
472
+ <label class="field wide">
473
+ <span>确认文本</span>
474
+ <input name="confirm_text" autocomplete="off">
475
+ </label>
476
+ <button class="danger wide" type="submit">提交委托</button>
477
+ </form>
478
+ </div>
479
+
480
+ <div class="panel span-6 view-panel view-trade batch-ticket">
481
+ <div class="panel-head">
482
+ <h2>批量买入</h2>
483
+ <span id="batchOrderHint" class="metric-note"></span>
484
+ </div>
485
+ <form id="batchOrderForm" class="form-grid">
486
+ <label class="field wide">
487
+ <span>委托列表</span>
488
+ <textarea name="orders_text" class="code-textarea" placeholder="000001.SZ,10.000,100&#10;600000.SH,8.500,200"></textarea>
489
+ </label>
490
+ <label class="field wide">
491
+ <span>确认文本</span>
492
+ <input name="confirm_text" autocomplete="off" placeholder="BATCH 2">
493
+ </label>
494
+ <button class="danger wide" type="submit">批量提交</button>
495
+ </form>
496
+ </div>
497
+
498
+ <div class="panel span-8 view-panel view-trade trade-data-panel">
499
+ <div class="panel-head">
500
+ <h2>交易数据</h2>
501
+ <div class="head-actions">
502
+ <button class="data-tab active" data-tab="positions" type="button">持仓</button>
503
+ <button class="data-tab" data-tab="orders" type="button">委托</button>
504
+ <button class="data-tab" data-tab="trades" type="button">成交</button>
505
+ </div>
506
+ </div>
507
+ <div class="tab-pane active" data-pane="positions">
508
+ <div class="table-wrap">
509
+ <table>
510
+ <thead>
511
+ <tr>
512
+ <th>代码</th>
513
+ <th>名称</th>
514
+ <th class="num">持仓</th>
515
+ <th class="num">可用</th>
516
+ <th class="num">成本价</th>
517
+ <th class="num">市值</th>
518
+ <th class="num">盈亏</th>
519
+ </tr>
520
+ </thead>
521
+ <tbody id="tradePositionsBody"></tbody>
522
+ </table>
523
+ </div>
524
+ </div>
525
+ <div class="tab-pane" data-pane="orders">
526
+ <div class="table-wrap">
527
+ <table>
528
+ <thead>
529
+ <tr>
530
+ <th><input id="selectAllTradeOrders" type="checkbox"></th>
531
+ <th>序号</th>
532
+ <th><button class="sort-header" type="button" data-order-sort="time">时间<span class="sort-mark" aria-hidden="true"></span></button></th>
533
+ <th><button class="sort-header" type="button" data-order-sort="source">来源<span class="sort-mark" aria-hidden="true"></span></button></th>
534
+ <th><button class="sort-header" type="button" data-order-sort="code">代码<span class="sort-mark" aria-hidden="true"></span></button></th>
535
+ <th><button class="sort-header" type="button" data-order-sort="name">名称<span class="sort-mark" aria-hidden="true"></span></button></th>
536
+ <th class="num"><button class="sort-header" type="button" data-order-sort="volume">数量<span class="sort-mark" aria-hidden="true"></span></button></th>
537
+ <th class="num"><button class="sort-header" type="button" data-order-sort="traded">成交<span class="sort-mark" aria-hidden="true"></span></button></th>
538
+ <th><button class="sort-header" type="button" data-order-sort="status">状态<span class="sort-mark" aria-hidden="true"></span></button></th>
539
+ <th>最后回调</th>
540
+ <th><button class="sort-header" type="button" data-order-sort="id">编号<span class="sort-mark" aria-hidden="true"></span></button></th>
541
+ </tr>
542
+ </thead>
543
+ <tbody id="tradeOrdersBody"></tbody>
544
+ </table>
545
+ </div>
546
+ </div>
547
+ <div class="tab-pane" data-pane="trades">
548
+ <div class="table-wrap">
549
+ <table>
550
+ <thead>
551
+ <tr>
552
+ <th>时间</th>
553
+ <th>代码</th>
554
+ <th>名称</th>
555
+ <th class="num">价格</th>
556
+ <th class="num">数量</th>
557
+ <th class="num">金额</th>
558
+ </tr>
559
+ </thead>
560
+ <tbody id="tradeTradesBody"></tbody>
561
+ </table>
562
+ </div>
563
+ </div>
564
+ </div>
565
+
566
+ <div class="panel span-12 view-panel view-status">
567
+ <div class="panel-head">
568
+ <h2>系统状态</h2>
569
+ <span class="metric-note">LTtx / normal / trade</span>
570
+ </div>
571
+ <pre id="statusDetail" class="json-box"></pre>
572
+ </div>
573
+
574
+ <div class="panel span-12 view-panel view-bindings binding-action-panel">
575
+ <div class="panel-head">
576
+ <h2>绑定操作</h2>
577
+ </div>
578
+ <div class="binding-action-body">
579
+ <div class="panel-title-stack">
580
+ <strong>账号绑定</strong>
581
+ <span id="bindingCount" class="metric-note">--</span>
582
+ </div>
583
+ <div class="binding-action-buttons">
584
+ <button id="openBindingDialogBtn" class="primary" type="button">添加绑定</button>
585
+ <button id="openOnboardingGuideBtn" type="button">新手引导</button>
586
+ </div>
587
+ <div class="binding-guide">
588
+ <strong>列表维护账号绑定</strong>
589
+ <span>绑定信息、运行状态和验证入口集中显示。</span>
590
+ </div>
591
+ <div id="bindingPageNotice" class="binding-page-notice hidden" role="status" aria-live="polite"></div>
592
+ </div>
593
+ </div>
594
+
595
+ <div class="panel span-12 view-panel view-bindings bindings-panel">
596
+ <div class="panel-head bindings-head">
597
+ <h2>绑定列表</h2>
598
+ <span class="metric-note">账号 / 通道 / QMT 目录</span>
599
+ </div>
600
+ <div class="table-wrap binding-table-wrap">
601
+ <table class="binding-table">
602
+ <thead>
603
+ <tr>
604
+ <th>操作</th>
605
+ <th>账号名称</th>
606
+ <th>资金账号</th>
607
+ <th>连接状态</th>
608
+ <th>首选模式</th>
609
+ <th>实际模式</th>
610
+ <th>内部通道</th>
611
+ <th>QMT 目录</th>
612
+ <th>数据源</th>
613
+ </tr>
614
+ </thead>
615
+ <tbody id="bindingStatusBody"></tbody>
616
+ </table>
617
+ </div>
618
+ </div>
619
+
620
+ <div class="panel span-12 view-panel view-bindings binding-verify-panel">
621
+ <div class="panel-head">
622
+ <h2>绑定验证</h2>
623
+ <span id="pairVerifyNote" class="metric-note"></span>
624
+ </div>
625
+ <div class="verify-grid">
626
+ <div>
627
+ <h3>资金</h3>
628
+ <div id="pairAssetGrid" class="asset-grid">
629
+ <div><span>总资产</span><strong>--</strong></div>
630
+ <div><span>可用资金</span><strong>--</strong></div>
631
+ <div><span>总市值</span><strong>--</strong></div>
632
+ <div><span>持仓盈亏</span><strong>--</strong></div>
633
+ </div>
634
+ </div>
635
+ <div>
636
+ <h3>持仓</h3>
637
+ <div class="table-wrap compact-table">
638
+ <table>
639
+ <thead>
640
+ <tr>
641
+ <th>代码</th>
642
+ <th>名称</th>
643
+ <th class="num">持仓</th>
644
+ <th class="num">可用</th>
645
+ <th class="num">市值</th>
646
+ </tr>
647
+ </thead>
648
+ <tbody id="pairPositionsBody"></tbody>
649
+ </table>
650
+ </div>
651
+ </div>
652
+ </div>
653
+ </div>
654
+
655
+ <div class="panel span-12 view-panel view-callbacks">
656
+ <div class="panel-head">
657
+ <h2>交易回调</h2>
658
+ <div class="head-actions">
659
+ <span id="callbackCount" class="metric-note"></span>
660
+ <button id="callbackRefreshBtn" type="button">刷新</button>
661
+ <button id="callbackReconnectBtn" type="button">重连</button>
662
+ <button id="callbackClearBtn" type="button">清空</button>
663
+ </div>
664
+ </div>
665
+ <div class="callback-status-grid">
666
+ <div><span>连接状态</span><strong id="callbackSocketStatus">未连接</strong></div>
667
+ <div><span>订阅过滤</span><strong id="callbackFilterStatus">--</strong></div>
668
+ <div><span>最后事件</span><strong id="callbackLastEventStatus">尚未收到真实回调</strong></div>
669
+ <div><span>服务端序号</span><strong id="callbackSeqStatus">seq 0</strong></div>
670
+ </div>
671
+ <div class="table-wrap callback-table-wrap">
672
+ <table class="callback-table">
673
+ <thead>
674
+ <tr>
675
+ <th>接收时间</th>
676
+ <th>事件</th>
677
+ <th>账号</th>
678
+ <th>代码</th>
679
+ <th>委托编号</th>
680
+ <th class="num">价格</th>
681
+ <th class="num">数量</th>
682
+ <th class="num">成交</th>
683
+ <th>状态 / 摘要</th>
684
+ <th>来源</th>
685
+ <th>完整信息</th>
686
+ </tr>
687
+ </thead>
688
+ <tbody id="callbacksBody"></tbody>
689
+ </table>
690
+ </div>
691
+ </div>
692
+
693
+ <div class="panel span-12 view-panel view-api api-panel">
694
+ <div class="panel-head">
695
+ <h2>HTTP 接口文档</h2>
696
+ <span class="metric-note">在线调试</span>
697
+ </div>
698
+ <div class="api-layout">
699
+ <aside class="api-sidebar">
700
+ <div id="apiEndpointList" class="api-endpoint-list"></div>
701
+ </aside>
702
+ <section class="api-workbench">
703
+ <div class="api-settings-tip">
704
+ <span>API Key 和 IP 访问策略在设置页配置,文档调试会自动使用已保存的配置。</span>
705
+ <button id="openSettingsBtn" type="button">打开设置</button>
706
+ </div>
707
+ <div class="api-head">
708
+ <div>
709
+ <strong id="apiTitle">--</strong>
710
+ <span id="apiDesc"></span>
711
+ </div>
712
+ <code id="apiRoute">--</code>
713
+ </div>
714
+ <form id="apiForm" class="api-form"></form>
715
+ <div id="apiDocDetail" class="api-doc-detail"></div>
716
+ <div id="downloadProgressPanel" class="download-progress-panel hidden">
717
+ <div class="download-progress-head">
718
+ <div>
719
+ <h3>任务进度</h3>
720
+ <span id="downloadProgressStatus" class="metric-note">未开始</span>
721
+ </div>
722
+ <div class="download-progress-actions">
723
+ <code id="downloadProgressJob">--</code>
724
+ <button id="downloadProgressClearBtn" type="button">清空</button>
725
+ </div>
726
+ </div>
727
+ <div class="download-progress-meter" aria-hidden="true">
728
+ <span id="downloadProgressBar"></span>
729
+ </div>
730
+ <div id="downloadProgressMeta" class="download-progress-meta">耗时 --,事件 0 条,进度 未返回百分比</div>
731
+ <div id="downloadProgressEvents" class="download-progress-events">
732
+ <div><span>--</span><strong>暂无下载回调</strong></div>
733
+ </div>
734
+ </div>
735
+ <div id="quoteLivePanel" class="quote-live-panel hidden">
736
+ <div class="quote-live-head">
737
+ <div>
738
+ <h3>实时行情</h3>
739
+ <span id="quoteLiveStatus" class="metric-note">未连接</span>
740
+ </div>
741
+ <div class="quote-live-actions">
742
+ <button id="quoteConnectBtn" type="button">连接推送</button>
743
+ <button id="quoteStopBtn" type="button">停止推送</button>
744
+ </div>
745
+ </div>
746
+ <div class="table-wrap quote-live-table">
747
+ <table>
748
+ <thead>
749
+ <tr>
750
+ <th>代码</th>
751
+ <th class="num">最新价</th>
752
+ <th class="num">涨跌幅</th>
753
+ <th class="num">成交量</th>
754
+ <th>时间</th>
755
+ </tr>
756
+ </thead>
757
+ <tbody id="quoteLiveBody"></tbody>
758
+ </table>
759
+ </div>
760
+ </div>
761
+ <div class="api-preview">
762
+ <div>
763
+ <h3>请求</h3>
764
+ <pre id="apiRequestPreview" class="json-box small-json"></pre>
765
+ </div>
766
+ <div>
767
+ <h3>响应</h3>
768
+ <div id="apiResponseLatency" class="api-response-latency hidden" aria-live="polite">
769
+ <span id="apiResponseLatencyLabel" class="api-response-latency-label">接口耗时</span>
770
+ <strong id="apiResponseLatencyValue">--</strong>
771
+ <span id="apiResponseLatencyMeta" class="api-response-latency-meta"></span>
772
+ </div>
773
+ <pre id="apiResponseBox" class="json-box small-json"></pre>
774
+ </div>
775
+ </div>
776
+ </section>
777
+ </div>
778
+ </div>
779
+
780
+ <div class="panel span-12 view-panel view-settings settings-panel">
781
+ <div class="panel-head">
782
+ <h2>设置</h2>
783
+ <span class="metric-note">访问 / 日志 / 更新</span>
784
+ </div>
785
+ <div class="settings-layout">
786
+ <aside class="settings-menu" aria-label="设置菜单">
787
+ <button class="settings-menu-item" type="button" data-settings-tab="profile">
788
+ <strong>个人资料</strong>
789
+ <span>头像和名称</span>
790
+ </button>
791
+ <button class="settings-menu-item active" type="button" data-settings-tab="api-key">
792
+ <strong>API Key</strong>
793
+ <span>访问密钥</span>
794
+ </button>
795
+ <button class="settings-menu-item" type="button" data-settings-tab="web-access">
796
+ <strong>Web 访问</strong>
797
+ <span>端口和登录</span>
798
+ </button>
799
+ <button class="settings-menu-item" type="button" data-settings-tab="log-cleanup">
800
+ <strong>日志清理</strong>
801
+ <span>过期日志</span>
802
+ </button>
803
+ <button class="settings-menu-item" type="button" data-settings-tab="qmt-log">
804
+ <strong>QMT 日志</strong>
805
+ <span>显示开关</span>
806
+ </button>
807
+ <button class="settings-menu-item" type="button" data-settings-tab="transport">
808
+ <strong>通信模式</strong>
809
+ <span>桥接模式</span>
810
+ </button>
811
+ <button class="settings-menu-item" type="button" data-settings-tab="update">
812
+ <strong>系统更新</strong>
813
+ <span>Web / QMT</span>
814
+ </button>
815
+ </aside>
816
+ <section class="settings-section" data-settings-tab="profile">
817
+ <h3>个人资料</h3>
818
+ <div class="profile-settings">
819
+ <div class="profile-preview">
820
+ <img id="profileAvatarPreview" src="/avatars/market-blue.svg" alt="">
821
+ <div>
822
+ <strong id="profilePreviewName">管理员</strong>
823
+ <span id="profileAvatarMeta">内置头像</span>
824
+ </div>
825
+ </div>
826
+ <form id="userProfileForm" class="profile-form">
827
+ <label class="field">
828
+ <span>显示名称</span>
829
+ <input id="profileDisplayNameInput" type="text" maxlength="40" autocomplete="off" placeholder="管理员">
830
+ </label>
831
+ <div class="profile-upload-row">
832
+ <label class="field">
833
+ <span>上传头像</span>
834
+ <input id="profileAvatarFileInput" type="file" accept="image/png,image/jpeg,image/webp,image/gif">
835
+ </label>
836
+ <button id="uploadUserAvatarBtn" type="button">上传头像</button>
837
+ </div>
838
+ <div class="profile-avatar-picker">
839
+ <div class="profile-avatar-picker-head">
840
+ <strong>内置头像</strong>
841
+ <span>选择后点击保存资料生效</span>
842
+ </div>
843
+ <div id="builtinAvatarGrid" class="builtin-avatar-grid"></div>
844
+ </div>
845
+ <div class="profile-actions">
846
+ <span id="userProfileStatus" class="metric-note"></span>
847
+ <button id="saveUserProfileBtn" class="primary" type="submit">保存资料</button>
848
+ </div>
849
+ </form>
850
+ </div>
851
+ </section>
852
+ <section class="settings-section active" data-settings-tab="api-key">
853
+ <h3>API Key</h3>
854
+ <form id="apiKeyForm" class="api-keybar">
855
+ <label class="field">
856
+ <span>API Key</span>
857
+ <input id="apiKeyInput" type="password" autocomplete="off" placeholder="自定义或随机生成">
858
+ </label>
859
+ <button id="generateApiKeyBtn" type="button">随机生成</button>
860
+ <button id="toggleApiKeyBtn" type="button">显示</button>
861
+ <button id="copyApiKeyBtn" type="button">复制</button>
862
+ <button id="saveApiKeyBtn" class="primary" type="button">保存 API Key</button>
863
+ <span id="apiKeyStatus" class="metric-note"></span>
864
+ </form>
865
+ </section>
866
+ <section class="settings-section" data-settings-tab="web-access">
867
+ <h3>Web 访问</h3>
868
+ <form id="apiServerForm" class="server-settings-form">
869
+ <div class="server-access-summary" aria-live="polite">
870
+ <div>
871
+ <span>当前监听</span>
872
+ <strong id="webCurrentListenValue">--</strong>
873
+ </div>
874
+ <div>
875
+ <span>配置端口</span>
876
+ <strong id="webConfiguredPortValue">--</strong>
877
+ </div>
878
+ <div>
879
+ <span>访问范围</span>
880
+ <strong id="webAccessScopeValue">--</strong>
881
+ </div>
882
+ <div>
883
+ <span>网页登录</span>
884
+ <strong id="webAuthStateValue">--</strong>
885
+ </div>
886
+ </div>
887
+ <div class="server-settings-groups">
888
+ <div class="server-settings-group">
889
+ <h4>通信模式</h4>
890
+ <div class="server-settings-grid">
891
+ <label class="field">
892
+ <span>Web 通信模式</span>
893
+ <select id="transportModeSelect">
894
+ <option value="ctypes">通用模式(ctypes 单桥)</option>
895
+ <option value="lite">极致模式(纯 ctypes 自包含)</option>
896
+ <option value="lttx">高级模式(两个 QMT)</option>
897
+ </select>
898
+ </label>
899
+ </div>
900
+ </div>
901
+ <div class="server-settings-group">
902
+ <h4>监听与访问</h4>
903
+ <div class="server-settings-grid">
904
+ <label class="field">
905
+ <span>网页端口</span>
906
+ <input id="webPortInput" type="number" min="1" max="65535" step="1" autocomplete="off" placeholder="8765">
907
+ </label>
908
+ <label class="toggle api-remote-toggle">
909
+ <input id="allowApiRemoteAccess" type="checkbox">
910
+ <span>允许外网访问</span>
911
+ </label>
912
+ <label class="field wide">
913
+ <span>域名白名单</span>
914
+ <input id="webAllowedDomainsInput" type="text" autocomplete="off" placeholder="example.com,*.example.com,192.168.1.70">
915
+ </label>
916
+ </div>
917
+ <div class="server-settings-actions">
918
+ <span id="apiServerStatus" class="metric-note"></span>
919
+ <div class="server-action-buttons">
920
+ <button id="saveApiServerBtn" class="primary" type="submit">保存设置</button>
921
+ <button id="reloadWebServerBtn" type="button">保存并重载</button>
922
+ </div>
923
+ </div>
924
+ </div>
925
+ <div class="server-settings-group">
926
+ <h4>网页登录</h4>
927
+ <div class="server-settings-grid">
928
+ <label class="toggle api-remote-toggle">
929
+ <input id="webAuthEnabledInput" type="checkbox">
930
+ <span>需要账号密码</span>
931
+ </label>
932
+ <label class="field">
933
+ <span>账号</span>
934
+ <input id="webAuthUsernameInput" autocomplete="username" placeholder="admin">
935
+ </label>
936
+ <label class="field">
937
+ <span>密码</span>
938
+ <input id="webAuthPasswordInput" type="password" autocomplete="new-password" placeholder="留空则保持不变">
939
+ </label>
940
+ </div>
941
+ </div>
942
+ <div class="server-settings-group">
943
+ <h4>外部 API 地址</h4>
944
+ <div class="server-url-row">
945
+ <label class="field">
946
+ <span>接口访问地址</span>
947
+ <input id="apiBaseUrlInput" type="text" autocomplete="off" placeholder="http://192.168.1.70:8765">
948
+ </label>
949
+ <button id="useCurrentOriginBtn" type="button">当前地址</button>
950
+ <button id="useLanOriginBtn" type="button">局域网地址</button>
951
+ </div>
952
+ </div>
953
+ </div>
954
+ </form>
955
+ </section>
956
+ <section class="settings-section" data-settings-tab="log-cleanup">
957
+ <h3>日志清理</h3>
958
+ <p class="settings-note">本地服务日志统一写入项目 <code>log/</code> 目录,默认自动保留最近 30 天;根目录旧日志也会纳入过期清理。</p>
959
+ <form id="logCleanupForm" class="api-serverbar">
960
+ <label class="toggle api-remote-toggle">
961
+ <input id="cleanupQmtUserdataLogs" type="checkbox">
962
+ <span>清理 QMT userdata/log 过期日志</span>
963
+ </label>
964
+ <button id="saveLogCleanupBtn" class="primary" type="submit">保存日志设置</button>
965
+ <button id="runLogCleanupBtn" type="button">立即清理</button>
966
+ <span id="logCleanupStatus" class="metric-note"></span>
967
+ </form>
968
+ </section>
969
+ <section class="settings-section" data-settings-tab="qmt-log">
970
+ <h3>QMT 日志</h3>
971
+ <form id="qmtLogLanguageForm" class="api-serverbar">
972
+ <label class="toggle api-remote-toggle">
973
+ <input id="qmtLogEnabled" type="checkbox" checked>
974
+ <span>显示 QMT 桥接日志</span>
975
+ </label>
976
+ <label class="field">
977
+ <span>显示语言</span>
978
+ <select id="qmtLogLanguageSelect">
979
+ <option value="zh">中文</option>
980
+ <option value="en">English</option>
981
+ </select>
982
+ </label>
983
+ <button id="saveQmtLogLanguageBtn" class="primary" type="submit">保存日志设置</button>
984
+ <span id="qmtLogLanguageStatus" class="metric-note"></span>
985
+ </form>
986
+ </section>
987
+ <section class="settings-section" data-settings-tab="transport">
988
+ <h3>通信模式</h3>
989
+ <div class="api-serverbar">
990
+ <label class="field">
991
+ <span>当前模式</span>
992
+ <select id="transportModeSelect2">
993
+ <option value="ctypes">通用模式(ctypes 单桥)</option>
994
+ <option value="lite">极致模式(纯 ctypes 自包含)</option>
995
+ <option value="lttx">高级模式(两个 QMT)</option>
996
+ </select>
997
+ </label>
998
+ <button id="saveTransportModeBtn" class="primary" type="button">保存模式</button>
999
+ <button id="startPipeHubBtn" type="button">启动 PipeHub</button>
1000
+ <button id="stopPipeHubBtn" type="button">停止 PipeHub</button>
1001
+ <span id="transportStatusText" class="metric-note"></span>
1002
+ </div>
1003
+ <div id="pipeHubStatusBox" class="guide-callout">
1004
+ <strong>PipeHub 状态</strong>
1005
+ <span>--</span>
1006
+ </div>
1007
+ </section>
1008
+ <section class="settings-section" data-settings-tab="update">
1009
+ <div class="settings-section-head">
1010
+ <div>
1011
+ <h3>系统更新</h3>
1012
+ <p class="settings-note">默认使用官网更新。GitHub、zip 和回滚放在高级选项里。</p>
1013
+ </div>
1014
+ </div>
1015
+ <div class="update-workspace">
1016
+ <section class="update-lane">
1017
+ <div class="update-lane-head">
1018
+ <div>
1019
+ <span>Web 项目</span>
1020
+ <strong>控制台与本地服务</strong>
1021
+ </div>
1022
+ </div>
1023
+ <div class="update-status-row">
1024
+ <span id="projectUpdateStatus" class="metric-note">未加载项目更新状态</span>
1025
+ </div>
1026
+ <div id="projectUpdateVersionInfo" class="update-version-info"></div>
1027
+ <div class="update-primary-actions">
1028
+ <button id="runProjectGithubUpdateBtn" class="primary" type="button">更新 Web</button>
1029
+ <button id="refreshProjectUpdateStatusBtn" type="button">刷新</button>
1030
+ </div>
1031
+ <details class="update-advanced">
1032
+ <summary>高级选项</summary>
1033
+ <div class="update-action-grid">
1034
+ <label class="field">
1035
+ <span>GitHub 回退仓库</span>
1036
+ <input id="projectUpdateRepoInput" type="text" autocomplete="off" value="https://github.com/95ge/cfquant.git" placeholder="owner/repo 或 https://github.com/owner/repo">
1037
+ </label>
1038
+ <label class="field compact">
1039
+ <span>分支 / 标签</span>
1040
+ <input id="projectUpdateRefInput" type="text" autocomplete="off" value="main" placeholder="main,可空">
1041
+ </label>
1042
+ </div>
1043
+ <div class="update-action-grid">
1044
+ <label class="field">
1045
+ <span>项目源码 zip</span>
1046
+ <input id="projectUpdateZipInput" type="file" accept=".zip,application/zip">
1047
+ </label>
1048
+ <button id="uploadProjectZipUpdateBtn" class="primary" type="button">上传 zip 更新 Web</button>
1049
+ <label class="field">
1050
+ <span>可回滚项目备份</span>
1051
+ <select id="projectRollbackBackupSelect"></select>
1052
+ </label>
1053
+ <button id="rollbackProjectUpdateBtn" class="danger" type="button">回滚 Web 并重启</button>
1054
+ </div>
1055
+ </details>
1056
+ <div id="projectUpdateNoticeBox" class="update-notice hidden"></div>
1057
+ <details class="update-result-details">
1058
+ <summary>执行结果</summary>
1059
+ <pre id="projectUpdateResultBox" class="json-box small-json update-result"></pre>
1060
+ </details>
1061
+ </section>
1062
+
1063
+ <section class="update-lane qmt-update-lane">
1064
+ <div class="update-lane-head">
1065
+ <div>
1066
+ <span>QMT 核心</span>
1067
+ <strong>当前账号绑定目录</strong>
1068
+ </div>
1069
+ </div>
1070
+ <div class="update-status-row">
1071
+ <span id="updateStatus" class="metric-note">未加载更新状态</span>
1072
+ </div>
1073
+ <div id="updateVersionInfo" class="update-version-info qmt-version-info"></div>
1074
+ <div class="update-primary-actions">
1075
+ <button id="runGithubUpdateBtn" class="primary" type="button">更新 QMT</button>
1076
+ <button id="refreshUpdateStatusBtn" type="button">刷新</button>
1077
+ </div>
1078
+ <details class="update-advanced">
1079
+ <summary>高级选项</summary>
1080
+ <div class="update-action-grid">
1081
+ <label class="field">
1082
+ <span>GitHub 回退仓库</span>
1083
+ <input id="updateRepoInput" type="text" autocomplete="off" value="https://github.com/95ge/cfquant.git" placeholder="owner/repo 或 https://github.com/owner/repo">
1084
+ </label>
1085
+ <label class="field compact">
1086
+ <span>分支 / 标签</span>
1087
+ <input id="updateRefInput" type="text" autocomplete="off" value="main" placeholder="main,可空">
1088
+ </label>
1089
+ </div>
1090
+ <div class="update-action-grid">
1091
+ <label class="field">
1092
+ <span>源码 zip</span>
1093
+ <input id="updateZipInput" type="file" accept=".zip,application/zip">
1094
+ </label>
1095
+ <button id="uploadZipUpdateBtn" class="primary" type="button">上传 zip 更新 QMT</button>
1096
+ <label class="field">
1097
+ <span>可回滚备份</span>
1098
+ <select id="rollbackBackupSelect"></select>
1099
+ </label>
1100
+ <button id="rollbackUpdateBtn" class="danger" type="button">回滚 QMT</button>
1101
+ </div>
1102
+ </details>
1103
+ <div id="updateNoticeBox" class="update-notice hidden"></div>
1104
+ <details class="update-result-details">
1105
+ <summary>执行结果</summary>
1106
+ <pre id="updateResultBox" class="json-box small-json update-result"></pre>
1107
+ </details>
1108
+ </section>
1109
+ </div>
1110
+ </section>
1111
+ </div>
1112
+ </div>
1113
+
1114
+ <div class="panel span-12 view-panel view-tutorial tutorial-panel">
1115
+ <div class="panel-head">
1116
+ <h2>教程中心</h2>
1117
+ <span class="metric-note">部署 / 网页 / 接口</span>
1118
+ </div>
1119
+ <div class="tutorial-layout">
1120
+ <aside class="tutorial-menu" aria-label="教程菜单">
1121
+ <button class="tutorial-menu-item recommended active" type="button" data-guide="deploy">
1122
+ <strong>QMT 部署教程 <em>推荐</em></strong>
1123
+ <span>通用、极致、高级三种模式</span>
1124
+ </button>
1125
+ <button class="tutorial-menu-item" type="button" data-guide="onboarding">
1126
+ <strong>新手引导</strong>
1127
+ <span>单账号通用模式,最快跑通</span>
1128
+ </button>
1129
+ <button class="tutorial-menu-item" type="button" data-guide="project">
1130
+ <strong>项目架构</strong>
1131
+ <span>架构、链路和运行目录</span>
1132
+ </button>
1133
+ <button class="tutorial-menu-item" type="button" data-guide="quickstart">
1134
+ <strong>快速开始</strong>
1135
+ <span>启动、部署、验证</span>
1136
+ </button>
1137
+ <button class="tutorial-menu-item" type="button" data-guide="web_console">
1138
+ <strong>网页端教程</strong>
1139
+ <span>页面分工和操作顺序</span>
1140
+ </button>
1141
+ <button class="tutorial-menu-item" type="button" data-guide="python">
1142
+ <strong>Python 接入</strong>
1143
+ <span>pip、auto 路由、xtquant 平替</span>
1144
+ </button>
1145
+ <button class="tutorial-menu-item" type="button" data-guide="same_account_market">
1146
+ <strong>同账号独立市场</strong>
1147
+ <span>沪深两个交易端自动分流</span>
1148
+ </button>
1149
+ <button class="tutorial-menu-item" type="button" data-guide="bridge">
1150
+ <strong>多账号通道</strong>
1151
+ <span>多 QMT 的内部路由</span>
1152
+ </button>
1153
+ <button class="tutorial-menu-item" type="button" data-guide="account">
1154
+ <strong>账号绑定</strong>
1155
+ <span>多账号、信用账户、共享行情源</span>
1156
+ </button>
1157
+ <button class="tutorial-menu-item" type="button" data-guide="trade">
1158
+ <strong>交易与回调</strong>
1159
+ <span>下单、撤单、回调确认</span>
1160
+ </button>
1161
+ <button class="tutorial-menu-item" type="button" data-guide="latency">
1162
+ <strong>实测延迟</strong>
1163
+ <span>链路量级和测试口径</span>
1164
+ </button>
1165
+ <button class="tutorial-menu-item" type="button" data-guide="api">
1166
+ <strong>外部接口</strong>
1167
+ <span>HTTP、WebSocket、API Key</span>
1168
+ </button>
1169
+ <button class="tutorial-menu-item" type="button" data-guide="troubleshooting">
1170
+ <strong>排查问题</strong>
1171
+ <span>按层定位故障</span>
1172
+ </button>
1173
+ </aside>
1174
+
1175
+ <section class="tutorial-content">
1176
+ <article class="tutorial-topic" data-guide-panel="onboarding">
1177
+ <div class="guide-section">
1178
+ <h3>先把 cfquant 跑起来</h3>
1179
+ <p>按向导填账号、选模式、部署脚本、验证数据。其他说明以后再看。</p>
1180
+ <div class="guide-callout">
1181
+ <strong>推荐</strong>
1182
+ <span>第一次用通用模式,QMT 目录填 <code>bin.x64</code>。</span>
1183
+ </div>
1184
+ <div class="onboarding-inline-actions">
1185
+ <button id="openOnboardingInlineBtn" class="primary" type="button">开始初始化向导</button>
1186
+ </div>
1187
+ <div id="onboardingBackdrop" class="onboarding-backdrop hidden" aria-hidden="true"></div>
1188
+ <div class="onboarding-wizard hidden" id="onboardingWizard" role="dialog" aria-modal="true" aria-labelledby="onboardingWizardTitle">
1189
+ <div class="onboarding-modal-head">
1190
+ <div>
1191
+ <strong id="onboardingWizardTitle">新手初始化向导</strong>
1192
+ <span>只保留启动必需项。</span>
1193
+ </div>
1194
+ <button id="closeOnboardingBtn" type="button" aria-label="关闭新手初始化向导">关闭</button>
1195
+ </div>
1196
+ <div class="onboarding-progress" aria-label="新手初始化步骤">
1197
+ <button class="active" type="button" data-onboarding-step="intro"><span>1</span><strong>开始</strong></button>
1198
+ <button type="button" data-onboarding-step="config"><span>2</span><strong>账号</strong></button>
1199
+ <button type="button" data-onboarding-step="deploy"><span>3</span><strong>脚本</strong></button>
1200
+ <button type="button" data-onboarding-step="bridge"><span>4</span><strong>通道</strong></button>
1201
+ <button type="button" data-onboarding-step="data"><span>5</span><strong>数据</strong></button>
1202
+ </div>
1203
+
1204
+ <section class="onboarding-panel onboarding-panel-intro active" data-onboarding-panel="intro">
1205
+ <div class="onboarding-panel-head">
1206
+ <strong>先按默认路径跑通</strong>
1207
+ <span>第一次不用理解全部架构,完成这四步即可。</span>
1208
+ </div>
1209
+ <div class="onboarding-quick-list" aria-label="初始化步骤">
1210
+ <div class="onboarding-quick-item">
1211
+ <span>1</span>
1212
+ <strong>填资金账号</strong>
1213
+ <small>不要使用示例账号。</small>
1214
+ </div>
1215
+ <div class="onboarding-quick-item">
1216
+ <span>2</span>
1217
+ <strong>选择模式</strong>
1218
+ <small>不确定就选通用模式。</small>
1219
+ </div>
1220
+ <div class="onboarding-quick-item">
1221
+ <span>3</span>
1222
+ <strong>部署脚本</strong>
1223
+ <small>按清单复制到 QMT。</small>
1224
+ </div>
1225
+ <div class="onboarding-quick-item">
1226
+ <span>4</span>
1227
+ <strong>验证数据</strong>
1228
+ <small>能查资金或持仓即可。</small>
1229
+ </div>
1230
+ </div>
1231
+ <div class="guide-callout compact">
1232
+ <strong>高级模式</strong>
1233
+ <span>只有确认要双 QMT 低延迟交易时再选。</span>
1234
+ </div>
1235
+ <div class="onboarding-actions">
1236
+ <button id="onboardingStartConfigBtn" class="primary" type="button">开始配置</button>
1237
+ </div>
1238
+ </section>
1239
+
1240
+ <form id="onboardingConfigForm" class="onboarding-panel" data-onboarding-panel="config">
1241
+ <div class="onboarding-panel-head">
1242
+ <strong>账号配置</strong>
1243
+ <span>填资金账号、模式和 QMT 目录。</span>
1244
+ </div>
1245
+ <div class="onboarding-grid">
1246
+ <label class="field">
1247
+ <span>资金账号</span>
1248
+ <input id="onboardingAccountId" autocomplete="off" placeholder="请输入资金账号">
1249
+ </label>
1250
+ <label class="field">
1251
+ <span>账户类型</span>
1252
+ <select id="onboardingAccountType">
1253
+ <option value="STOCK">普通证券账户</option>
1254
+ <option value="CREDIT">信用账户</option>
1255
+ </select>
1256
+ </label>
1257
+ <label class="field">
1258
+ <span>运行模式</span>
1259
+ <select id="onboardingMode">
1260
+ <option value="ctypes">通用模式(推荐)</option>
1261
+ <option value="lite">极致模式</option>
1262
+ <option value="lttx">高级模式</option>
1263
+ </select>
1264
+ <small>首次建议通用模式;高级模式会要求第二个 QMT 目录。</small>
1265
+ </label>
1266
+ <label class="field wide">
1267
+ <span>QMT 核心目录</span>
1268
+ <input id="onboardingQmtDir" autocomplete="off" placeholder="D:\国金证券QMT交易端\bin.x64">
1269
+ <small>通常是 QMT 安装目录下的 <code>bin.x64</code>。</small>
1270
+ </label>
1271
+ <label id="onboardingQmtTradeDirField" class="field wide hidden">
1272
+ <span>第二个 QMT 核心目录</span>
1273
+ <input id="onboardingQmtTradeDir" autocomplete="off" placeholder="D:\国金证券QMT交易端-交易端\bin.x64">
1274
+ <small>仅高级模式必填,且不能和上面的目录相同。</small>
1275
+ </label>
1276
+ <label class="toggle wide">
1277
+ <input id="onboardingDataProvider" type="checkbox" checked>
1278
+ <span>作为默认共享行情数据源</span>
1279
+ </label>
1280
+ </div>
1281
+ <div class="onboarding-actions">
1282
+ <button id="onboardingUseCurrentBtn" type="button">读取当前配置</button>
1283
+ <button id="onboardingSaveConfigBtn" class="primary" type="submit">保存账号配置</button>
1284
+ <span id="onboardingConfigStatus" class="metric-note"></span>
1285
+ </div>
1286
+ </form>
1287
+
1288
+ <section class="onboarding-panel" data-onboarding-panel="deploy">
1289
+ <div class="onboarding-panel-head">
1290
+ <strong>部署脚本</strong>
1291
+ <span>按清单复制文件,再在 QMT 里加载。</span>
1292
+ </div>
1293
+ <div id="onboardingDeployPaths" class="onboarding-deploy-list"></div>
1294
+ <div id="onboardingDeployNotice" class="guide-callout">
1295
+ <strong>通用模式</strong>
1296
+ <span>只加载 <code>CFQUANT_CTYPE_ALL_LOWLAT.py</code>。</span>
1297
+ </div>
1298
+ <div class="onboarding-actions">
1299
+ <button id="onboardingCopyDeployBtn" type="button">复制部署清单</button>
1300
+ <button id="onboardingGoBridgeBtn" class="primary" type="button">我已部署,开始检测</button>
1301
+ <span id="onboardingDeployStatus" class="metric-note"></span>
1302
+ </div>
1303
+ </section>
1304
+
1305
+ <section class="onboarding-panel" data-onboarding-panel="bridge">
1306
+ <div class="onboarding-panel-head">
1307
+ <strong>检测通道</strong>
1308
+ <span>启动 QMT 脚本后刷新状态。</span>
1309
+ </div>
1310
+ <div id="onboardingBridgeSummary" class="onboarding-summary"></div>
1311
+ <div class="onboarding-actions">
1312
+ <button id="onboardingRefreshBridgeBtn" class="primary" type="button">刷新通道状态</button>
1313
+ <button id="onboardingOpenBindingsBtn" type="button">打开绑定页</button>
1314
+ <span id="onboardingBridgeStatus" class="metric-note"></span>
1315
+ </div>
1316
+ </section>
1317
+
1318
+ <section class="onboarding-panel" data-onboarding-panel="data">
1319
+ <div class="onboarding-panel-head">
1320
+ <strong>验证数据</strong>
1321
+ <span>能查到资金或持仓,初始化就完成。</span>
1322
+ </div>
1323
+ <div id="onboardingDataSummary" class="onboarding-summary"></div>
1324
+ <div class="onboarding-actions">
1325
+ <button id="onboardingVerifyDataBtn" class="primary" type="button">查询资金/持仓</button>
1326
+ <button id="onboardingOpenHomeBtn" type="button">回首页</button>
1327
+ <button id="onboardingOpenApiBtn" type="button">打开接口调试</button>
1328
+ <span id="onboardingDataStatus" class="metric-note"></span>
1329
+ </div>
1330
+ </section>
1331
+ <div id="onboardingSuccess" class="onboarding-success hidden" role="dialog" aria-modal="true" aria-labelledby="onboardingSuccessTitle" aria-hidden="true">
1332
+ <div class="onboarding-success-mark" aria-hidden="true"></div>
1333
+ <div class="onboarding-success-copy">
1334
+ <strong id="onboardingSuccessTitle">部署成功,可以开始使用</strong>
1335
+ <span id="onboardingSuccessText">基础数据验证已通过。</span>
1336
+ </div>
1337
+ <div class="onboarding-success-actions">
1338
+ <button id="onboardingSuccessHomeBtn" class="primary" type="button">进入首页</button>
1339
+ <button id="onboardingSuccessApiBtn" type="button">接口调试</button>
1340
+ <button id="onboardingSuccessBindingsBtn" type="button">继续添加账号</button>
1341
+ </div>
1342
+ </div>
1343
+ </div>
1344
+ </div>
1345
+
1346
+ <div class="guide-section">
1347
+ <h3>跑通后再看</h3>
1348
+ <div class="guide-kv wide">
1349
+ <span>多账号</span>
1350
+ <strong>在“绑定”继续添加账号,QMT 目录填实际登录该账号的 <code>bin.x64</code>。</strong>
1351
+ <span>高级模式</span>
1352
+ <strong>需要两个 QMT,普通端和极速交易端都在线后再使用。</strong>
1353
+ <span>排查</span>
1354
+ <strong>先看绑定状态和 QMT 日志,再看 PipeHub 是否在线。</strong>
1355
+ </div>
1356
+ </div>
1357
+ </article>
1358
+
1359
+ <article class="tutorial-topic" data-guide-panel="project">
1360
+ <div class="guide-section">
1361
+ <h3>项目架构</h3>
1362
+ <p>cfquant 是本机 QMT 桥接控制台。它把 Web 页面、外部 Python 和大 QMT 策略脚本连在一起,由 Web 统一管理账号、运行模式、回调和更新。</p>
1363
+ <div class="guide-kv wide">
1364
+ <span>用户侧</span>
1365
+ <strong>网页操作,或在外部 Python 中按 xtquant 习惯调用。</strong>
1366
+ <span>本地服务</span>
1367
+ <strong>Web Server 管账号路由;PipeHub 管通用/极致模式;LTtx 管高级模式和自动发现。</strong>
1368
+ <span>QMT 侧</span>
1369
+ <strong>根据模式加载一个或两个入口脚本,再调用 QMT 原生函数。</strong>
1370
+ </div>
1371
+ </div>
1372
+
1373
+ <div class="guide-section">
1374
+ <h3>三种运行链路</h3>
1375
+ <div class="guide-table-wrap">
1376
+ <table>
1377
+ <thead>
1378
+ <tr>
1379
+ <th>模式</th>
1380
+ <th>QMT 入口</th>
1381
+ <th>适合场景</th>
1382
+ </tr>
1383
+ </thead>
1384
+ <tbody>
1385
+ <tr>
1386
+ <td>通用模式</td>
1387
+ <td><code>CFQUANT_CTYPE_ALL_LOWLAT.py</code></td>
1388
+ <td>默认推荐。一个 QMT 即可跑通行情、查询、交易和回调。</td>
1389
+ </tr>
1390
+ <tr>
1391
+ <td>极致模式</td>
1392
+ <td><code>CFQUANT_LITE.py</code></td>
1393
+ <td>入口自包含,适合国泰君安、国泰海通等导入受限环境。</td>
1394
+ </tr>
1395
+ <tr>
1396
+ <td>高级模式</td>
1397
+ <td><code>CFQUANT.py</code> + <code>CFQUANT_TRADE_LOWLAT.py</code></td>
1398
+ <td>两个 QMT,普通端做查询和回调,极速交易端做低延迟交易请求。</td>
1399
+ </tr>
1400
+ </tbody>
1401
+ </table>
1402
+ </div>
1403
+ </div>
1404
+
1405
+ <div class="guide-section">
1406
+ <h3>关键文件</h3>
1407
+ <div class="guide-table-wrap">
1408
+ <table>
1409
+ <thead>
1410
+ <tr>
1411
+ <th>位置</th>
1412
+ <th>作用</th>
1413
+ </tr>
1414
+ </thead>
1415
+ <tbody>
1416
+ <tr>
1417
+ <td><code>runtime/config/cfquant_web_config.json</code></td>
1418
+ <td>保存账号、QMT 目录、运行模式、共享行情源和市场路由。</td>
1419
+ </tr>
1420
+ <tr>
1421
+ <td><code>qmt_scripts/</code></td>
1422
+ <td>放给 QMT 加载的入口脚本。</td>
1423
+ </tr>
1424
+ <tr>
1425
+ <td><code>bin.x64/cfquant_bridge_config.json</code></td>
1426
+ <td>Web 为 QMT 写入的身份文件,用于区分不同 QMT 终端。</td>
1427
+ </tr>
1428
+ <tr>
1429
+ <td><code>log/</code></td>
1430
+ <td>Web、PipeHub、LTtx 和 QMT 桥接日志。</td>
1431
+ </tr>
1432
+ </tbody>
1433
+ </table>
1434
+ </div>
1435
+ </div>
1436
+ </article>
1437
+
1438
+ <article class="tutorial-topic" data-guide-panel="quickstart">
1439
+ <div class="guide-section">
1440
+ <h3>快速开始</h3>
1441
+ <ol class="guide-list detailed">
1442
+ <li><strong>启动服务。</strong>运行 <code>启动cfquant.bat</code>,或执行 <code>cfquant --open-browser</code>。</li>
1443
+ <li><strong>完成初始化。</strong>填写资金账号、账户类型、QMT <code>bin.x64</code> 目录和运行模式。</li>
1444
+ <li><strong>部署 QMT。</strong>按“QMT 部署教程”复制核心包和入口脚本。</li>
1445
+ <li><strong>启动脚本。</strong>通用模式启动一个入口;高级模式分别启动普通端和极速交易端。</li>
1446
+ <li><strong>验证账号。</strong>回到“绑定”页刷新状态,再查资金、持仓。</li>
1447
+ <li><strong>接入外部程序。</strong>先在“接口”页调通参数,再改外部 Python 代码。</li>
1448
+ </ol>
1449
+ </div>
1450
+
1451
+ <div class="guide-section">
1452
+ <h3>启动后看哪里</h3>
1453
+ <div class="guide-kv wide">
1454
+ <span>首页</span>
1455
+ <strong>看当前账号资金、持仓和实时委托。</strong>
1456
+ <span>绑定</span>
1457
+ <strong>维护账号、QMT 目录、模式和共享行情源。</strong>
1458
+ <span>状态</span>
1459
+ <strong>确认 Web、PipeHub、LTtx 和 QMT 入口是否在线。</strong>
1460
+ <span>接口</span>
1461
+ <strong>调试 HTTP、WebSocket、行情下载和回调。</strong>
1462
+ </div>
1463
+ </div>
1464
+ </article>
1465
+
1466
+ <article class="tutorial-topic" data-guide-panel="web_console">
1467
+ <div class="guide-section">
1468
+ <h3>网页端</h3>
1469
+ <p>网页端负责配置、验证和排查。外部策略接入前,先用网页确认账号和 QMT 链路是通的。</p>
1470
+ <div class="web-tutorial-grid">
1471
+ <div class="web-tutorial-card"><strong>首页</strong><span>当前账号的资产、持仓、委托和基础状态。</span></div>
1472
+ <div class="web-tutorial-card"><strong>绑定</strong><span>账号、账户类型、QMT 目录、运行模式、共享行情源。</span></div>
1473
+ <div class="web-tutorial-card"><strong>交易</strong><span>单笔下单、批量下单、撤单和委托刷新。</span></div>
1474
+ <div class="web-tutorial-card"><strong>状态</strong><span>查看普通端、交易端、PipeHub、LTtx 是否在线。</span></div>
1475
+ <div class="web-tutorial-card"><strong>回调</strong><span>查看委托、成交、下单错误、撤单错误事件。</span></div>
1476
+ <div class="web-tutorial-card"><strong>接口</strong><span>在线调试行情、交易、下载和 WebSocket。</span></div>
1477
+ <div class="web-tutorial-card"><strong>设置</strong><span>API Key、远程访问、日志、版本检查和更新。</span></div>
1478
+ </div>
1479
+ </div>
1480
+
1481
+ <div class="guide-section">
1482
+ <h3>推荐顺序</h3>
1483
+ <ol class="guide-list detailed">
1484
+ <li>先在“绑定”保存账号配置。</li>
1485
+ <li>再在 QMT 启动对应入口脚本。</li>
1486
+ <li>回网页刷新绑定状态,确认实际模式在线。</li>
1487
+ <li>查资金和持仓,确认账号没有串。</li>
1488
+ <li>最后再测试下单、撤单和外部接口。</li>
1489
+ </ol>
1490
+ </div>
1491
+ </article>
1492
+
1493
+ <article class="tutorial-topic" data-guide-panel="python">
1494
+ <div class="guide-section">
1495
+ <h3>外部 Python</h3>
1496
+ <p>外部程序优先使用默认 <code>auto</code> 路由。Web 在线时请求进入 Web 统一路由,再按账号配置选择通用、极致或高级模式。</p>
1497
+ <pre class="guide-code">pip install cfquant
1498
+ pip install "cfquant[zmq]" # 需要 ZMQ 能力时再安装</pre>
1499
+ <pre class="guide-code">cfquant --open-browser
1500
+ cfquant qmt-scripts --output D:\QMT\cfquant</pre>
1501
+ </div>
1502
+
1503
+ <div class="guide-section">
1504
+ <h3>xtquant 平替写法</h3>
1505
+ <pre class="guide-code">from cfquant import xtdata
1506
+ from cfquant.xttrader import XtQuantTrader
1507
+ from cfquant.xttype import StockAccount
1508
+
1509
+ account = StockAccount("YOUR_ACCOUNT_ID")
1510
+ trader = XtQuantTrader("", 0, account=account)
1511
+ trader.start()
1512
+
1513
+ print(xtdata.get_full_tick(["000001.SZ"]))
1514
+ print(trader.query_stock_asset(account))</pre>
1515
+ </div>
1516
+
1517
+ <div class="guide-section">
1518
+ <h3>什么时候手动配置</h3>
1519
+ <p>正常多账号部署不用写 <code>configure()</code>。只有固定走某条链路、改 LTtx 端口、改 Pipe 名称或排查连接问题时再手动指定。</p>
1520
+ <pre class="guide-code">from cfquant import configure
1521
+
1522
+ configure(transport="ctypes", pipe_name=r"\\.\pipe\cfquant_pipe_hub")
1523
+ # 或:configure(transport="web_lttx", host="127.0.0.1", port=2049, token="LTtx")</pre>
1524
+ </div>
1525
+ </article>
1526
+
1527
+ <article class="tutorial-topic active" data-guide-panel="deploy">
1528
+ <div class="guide-section">
1529
+ <h3>【cfquant】QMT 部署教程</h3>
1530
+ <p>本教程介绍如何在大 QMT 中部署 cfquant,并通过本地 Web 控制台或外部 Python 调用行情、查询、交易和回调能力。</p>
1531
+ <div class="guide-recommend">
1532
+ <strong>建议先部署通用模式</strong>
1533
+ <span>通用模式只需要一个 QMT 和一个入口脚本,最适合首次验证。国泰君安和国泰海通的 QMT 建议直接使用极致模式;国泰海通无法部署高级模式。</span>
1534
+ </div>
1535
+ <div class="deploy-primer-grid">
1536
+ <div>
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>
1539
+ </div>
1540
+ <div>
1541
+ <strong>2. 再准备 QMT 环境</strong>
1542
+ <span>登录 QMT,并确认“模型研究”或“模型交易”里的 Python 环境已经安装可用。</span>
1543
+ </div>
1544
+ <div>
1545
+ <strong>3. 最后绑定账号验证</strong>
1546
+ <span>在网页“绑定”页填写资金账号、QMT 核心目录和运行模式,能查到资产、持仓或行情即部署成功。</span>
1547
+ </div>
1548
+ </div>
1549
+ <div class="guide-table-wrap">
1550
+ <table>
1551
+ <thead>
1552
+ <tr>
1553
+ <th>模式</th>
1554
+ <th>入口脚本</th>
1555
+ <th>QMT 数量</th>
1556
+ <th>说明</th>
1557
+ </tr>
1558
+ </thead>
1559
+ <tbody>
1560
+ <tr>
1561
+ <td>通用模式</td>
1562
+ <td><code>CFQUANT_CTYPE_ALL_LOWLAT.py</code></td>
1563
+ <td>1 个</td>
1564
+ <td>默认推荐,适合大多数行情、查询、下单、撤单和回调场景。</td>
1565
+ </tr>
1566
+ <tr>
1567
+ <td>极致模式</td>
1568
+ <td><code>CFQUANT_LITE.py</code></td>
1569
+ <td>1 个</td>
1570
+ <td>适合 QMT 对 Python 包导入有限制,或国泰君安、国泰海通等环境。</td>
1571
+ </tr>
1572
+ <tr>
1573
+ <td>高级模式</td>
1574
+ <td><code>CFQUANT.py</code> + <code>CFQUANT_TRADE_LOWLAT.py</code></td>
1575
+ <td>2 个</td>
1576
+ <td>部署复杂,但外部程序到 QMT 内部的下单链路延迟更低。</td>
1577
+ </tr>
1578
+ </tbody>
1579
+ </table>
1580
+ </div>
1581
+ </div>
1582
+
1583
+ <div class="deploy-mode-tabs" role="tablist" aria-label="QMT 部署模式">
1584
+ <button id="deployModeCtypes" class="active" type="button" role="tab" aria-selected="true" aria-controls="deployModePanelCtypes" data-deploy-mode="ctypes">
1585
+ <strong>通用模式</strong>
1586
+ <span>一个 QMT,默认推荐</span>
1587
+ </button>
1588
+ <button id="deployModeLite" type="button" role="tab" aria-selected="false" aria-controls="deployModePanelLite" data-deploy-mode="lite">
1589
+ <strong>极致模式</strong>
1590
+ <span>国泰君安、国泰海通等场景</span>
1591
+ </button>
1592
+ <button id="deployModeAdvanced" type="button" role="tab" aria-selected="false" aria-controls="deployModePanelAdvanced" data-deploy-mode="advanced">
1593
+ <strong>高级模式</strong>
1594
+ <span>两个 QMT,低延迟链路</span>
1595
+ </button>
1596
+ </div>
1597
+
1598
+ <div class="deploy-mode-panels">
1599
+ <section id="deployModePanelCtypes" class="deploy-mode-panel active" role="tabpanel" aria-labelledby="deployModeCtypes" data-deploy-mode-panel="ctypes">
1600
+ <div class="guide-section">
1601
+ <h3>一、通用模式部署教程</h3>
1602
+ <div class="guide-callout warning">
1603
+ <strong>特别提醒</strong>
1604
+ <span>国泰君安和国泰海通的 QMT,需要走【极致模式】。其他券商 QMT 建议先按通用模式部署。</span>
1605
+ </div>
1606
+ <ol class="guide-list detailed">
1607
+ <li><strong>下载项目解压,或通过 pip 安装后找到安装目录。</strong>下面以下载解压项目、国金证券 QMT 为例,其他证券公司的 QMT 按相同方式处理。</li>
1608
+ <li><strong>复制核心目录。</strong>将项目中的 <code>cfquant</code> 目录复制到你的 QMT 安装目录。</li>
1609
+ </ol>
1610
+ <figure class="guide-image-card">
1611
+ <img src="/image/qmt_deploy/image-4.png" alt="将 cfquant 目录复制到 QMT 安装目录">
1612
+ <figcaption>将项目中的 cfquant 目录复制到 QMT 安装目录。</figcaption>
1613
+ </figure>
1614
+ <ol class="guide-list detailed" start="3">
1615
+ <li><strong>打开 QMT。</strong>完成登录,并安装相应 Python 环境;如果已经安装,可以忽略。</li>
1616
+ </ol>
1617
+ <figure class="guide-image-card">
1618
+ <img src="/image/qmt_deploy/image-5.png" alt="QMT 登录并安装 Python 环境">
1619
+ <figcaption>打开 QMT,登录账号并确认 Python 环境可用。</figcaption>
1620
+ </figure>
1621
+ <ol class="guide-list detailed" start="4">
1622
+ <li><strong>新建 Python 策略。</strong>打开大 QMT 的“模型研究”界面,进入“新建策略”,选择“新建 Python 策略”。</li>
1623
+ </ol>
1624
+ <figure class="guide-image-card">
1625
+ <img src="/image/qmt_deploy/image-6.png" alt="QMT 模型研究中新建 Python 策略">
1626
+ <figcaption>在模型研究中新建 Python 策略。</figcaption>
1627
+ </figure>
1628
+ <ol class="guide-list detailed" start="5">
1629
+ <li><strong>启动策略。</strong>在通用模式中加载并启动 <code>CFQUANT_CTYPE_ALL_LOWLAT.py</code>。</li>
1630
+ </ol>
1631
+ <figure class="guide-image-card">
1632
+ <img src="/image/qmt_deploy/image-7.png" alt="启动通用模式策略">
1633
+ <figcaption>启动通用模式策略。</figcaption>
1634
+ </figure>
1635
+ <ol class="guide-list detailed" start="6">
1636
+ <li><strong>重启 QMT。</strong>首次部署或替换脚本后,建议重启 QMT,再重新启动策略。</li>
1637
+ </ol>
1638
+ <figure class="guide-image-card">
1639
+ <img src="/image/qmt_deploy/image-9.png" alt="重启 QMT">
1640
+ <figcaption>重启 QMT 后重新启动策略。</figcaption>
1641
+ </figure>
1642
+ <ol class="guide-list detailed" start="7">
1643
+ <li><strong>网页端绑定账号。</strong>回到 Web 控制台,在“绑定”页面填写资金账号、QMT 目录,并选择通用模式。</li>
1644
+ </ol>
1645
+ <figure class="guide-image-card">
1646
+ <img src="/image/qmt_deploy/image-10.png" alt="通用模式网页端账号绑定">
1647
+ <figcaption>在网页端完成通用模式账号绑定。</figcaption>
1648
+ </figure>
1649
+ <ol class="guide-list detailed" start="8">
1650
+ <li><strong>确认部署成功。</strong>网页端能看到对应通道在线,并能读取资产、持仓、委托或行情数据。</li>
1651
+ </ol>
1652
+ <figure class="guide-image-card">
1653
+ <img src="/image/qmt_deploy/image-8.png" alt="通用模式部署成功提示">
1654
+ <figcaption>部署成功后的网页状态提示。</figcaption>
1655
+ </figure>
1656
+ <ol class="guide-list detailed" start="9">
1657
+ <li><strong>接口调用测试。</strong>进入“接口调试”,执行一次查询或交易测试,确认调用链路可用。</li>
1658
+ </ol>
1659
+ <figure class="guide-image-card">
1660
+ <img src="/image/qmt_deploy/image-14.png" alt="通用模式接口调用测试">
1661
+ <figcaption>使用网页接口进行调用测试。</figcaption>
1662
+ </figure>
1663
+ </div>
1664
+ </section>
1665
+
1666
+ <section id="deployModePanelLite" class="deploy-mode-panel" role="tabpanel" aria-labelledby="deployModeLite" data-deploy-mode-panel="lite">
1667
+ <div class="guide-section">
1668
+ <h3>二、极致模式部署教程</h3>
1669
+ <div class="guide-callout warning">
1670
+ <strong>特别提醒</strong>
1671
+ <span>国泰君安和国泰海通的 QMT,需要走【极致模式】。极致模式在 QMT 中加载 <code>CFQUANT_LITE.py</code>。</span>
1672
+ </div>
1673
+ <ol class="guide-list detailed">
1674
+ <li><strong>准备项目目录。</strong>下载项目解压,或通过 pip 安装后找到对应安装目录。</li>
1675
+ <li><strong>按图放置项目目录。</strong>可将项目中的 <code>cfquant</code> 目录放到 QMT 安装目录;极致模式核心运行入口是 <code>CFQUANT_LITE.py</code>。</li>
1676
+ </ol>
1677
+ <figure class="guide-image-card">
1678
+ <img src="/image/qmt_deploy/image-4.png" alt="极致模式放置项目目录">
1679
+ <figcaption>将项目目录放到 QMT 安装目录。</figcaption>
1680
+ </figure>
1681
+ <ol class="guide-list detailed" start="3">
1682
+ <li><strong>打开 QMT。</strong>完成登录,并安装相应 Python 环境;如果已经安装,可以忽略。</li>
1683
+ </ol>
1684
+ <figure class="guide-image-card">
1685
+ <img src="/image/qmt_deploy/image-5.png" alt="极致模式确认 QMT Python 环境">
1686
+ <figcaption>确认 QMT Python 环境可用。</figcaption>
1687
+ </figure>
1688
+ <ol class="guide-list detailed" start="4">
1689
+ <li><strong>新建 Python 策略。</strong>打开大 QMT 的“模型研究”界面,进入“新建策略”,选择“新建 Python 策略”。</li>
1690
+ </ol>
1691
+ <figure class="guide-image-card">
1692
+ <img src="/image/qmt_deploy/image-11.png" alt="创建极致模式 Python 策略">
1693
+ <figcaption>创建极致模式 Python 策略。</figcaption>
1694
+ </figure>
1695
+ <ol class="guide-list detailed" start="5">
1696
+ <li><strong>启动策略。</strong>在 QMT 中加载并启动 <code>CFQUANT_LITE.py</code>。</li>
1697
+ </ol>
1698
+ <figure class="guide-image-card">
1699
+ <img src="/image/qmt_deploy/image-12.png" alt="启动极致模式策略">
1700
+ <figcaption>启动极致模式策略。</figcaption>
1701
+ </figure>
1702
+ <ol class="guide-list detailed" start="6">
1703
+ <li><strong>重启 QMT。</strong>首次部署或更新入口脚本后,重启 QMT 并重新启动策略。</li>
1704
+ </ol>
1705
+ <figure class="guide-image-card">
1706
+ <img src="/image/qmt_deploy/image-9.png" alt="极致模式重启 QMT">
1707
+ <figcaption>重启 QMT 后重新启动极致模式策略。</figcaption>
1708
+ </figure>
1709
+ <ol class="guide-list detailed" start="7">
1710
+ <li><strong>网页端绑定账号。</strong>在 Web 控制台“绑定”页面选择极致模式,填写账号和 QMT 目录后保存。</li>
1711
+ </ol>
1712
+ <figure class="guide-image-card">
1713
+ <img src="/image/qmt_deploy/image-13.png" alt="极致模式网页端账号绑定">
1714
+ <figcaption>在网页端完成极致模式账号绑定。</figcaption>
1715
+ </figure>
1716
+ <ol class="guide-list detailed" start="8">
1717
+ <li><strong>接口调用测试。</strong>部署成功后,可以在网页端的“接口调试”中进行调用测试。</li>
1718
+ </ol>
1719
+ <figure class="guide-image-card">
1720
+ <img src="/image/qmt_deploy/image-15.png" alt="极致模式接口调用测试">
1721
+ <figcaption>极致模式部署成功后的接口调用测试。</figcaption>
1722
+ </figure>
1723
+ </div>
1724
+ </section>
1725
+
1726
+ <section id="deployModePanelAdvanced" class="deploy-mode-panel" role="tabpanel" aria-labelledby="deployModeAdvanced" data-deploy-mode-panel="advanced">
1727
+ <div class="guide-section">
1728
+ <h3>三、高级模式部署教程</h3>
1729
+ <div class="guide-recommend warning">
1730
+ <strong>高级模式部署比较复杂</strong>
1731
+ <span>建议先跑通通用模式后再尝试高级模式。高级模式下单延迟约 4ms,这里的延迟是指外部程序到 QMT 内部,不是到交易所;QMT 到交易所的延迟不在本项目控制范围内。</span>
1732
+ </div>
1733
+ <div class="guide-callout warning">
1734
+ <strong>部署规则</strong>
1735
+ <span>高级模式需要两个 QMT。一般将 <code>qmt_scripts/CFQUANT.py</code> 放到第一个 QMT,将 <code>qmt_scripts/CFQUANT_TRADE_LOWLAT.py</code> 放到第二个安装的 QMT。不要在同一个 QMT 里同时运行这两个脚本;国泰海通无法部署高级模式。</span>
1736
+ </div>
1737
+ <ol class="guide-list detailed">
1738
+ <li><strong>准备两个 QMT。</strong>一个作为普通端,一个作为极速交易端。</li>
1739
+ </ol>
1740
+ <figure class="guide-image-card">
1741
+ <img src="/image/qmt_deploy/image-16.png" alt="高级模式准备两个 QMT">
1742
+ <figcaption>高级模式需要准备两个 QMT。</figcaption>
1743
+ </figure>
1744
+ <ol class="guide-list detailed" start="2">
1745
+ <li><strong>准备项目安装目录。</strong>下载项目解压,或通过 pip 安装后找到安装目录。下面以下载解压项目、国金证券 QMT 为例。</li>
1746
+ </ol>
1747
+ <figure class="guide-image-card">
1748
+ <img src="/image/qmt_deploy/image-17.png" alt="高级模式项目文件准备">
1749
+ <figcaption>准备高级模式所需项目文件。</figcaption>
1750
+ </figure>
1751
+ <ol class="guide-list detailed" start="3">
1752
+ <li><strong>复制核心目录。</strong>将项目中的 <code>cfquant</code> 目录复制到 QMT 安装目录。</li>
1753
+ </ol>
1754
+ <figure class="guide-image-card">
1755
+ <img src="/image/qmt_deploy/image-4.png" alt="高级模式复制 cfquant 目录">
1756
+ <figcaption>复制 cfquant 核心目录。</figcaption>
1757
+ </figure>
1758
+ <ol class="guide-list detailed" start="4">
1759
+ <li><strong>打开两个 QMT。</strong>登录并安装相应 Python 环境;如果已经安装,可以忽略。</li>
1760
+ </ol>
1761
+ <figure class="guide-image-card">
1762
+ <img src="/image/qmt_deploy/image-5.png" alt="高级模式确认两个 QMT Python 环境">
1763
+ <figcaption>确认两个 QMT 的 Python 环境可用。</figcaption>
1764
+ </figure>
1765
+ <ol class="guide-list detailed" start="5">
1766
+ <li><strong>新建 Python 策略。</strong>分别在两个 QMT 的“模型研究”界面中新建 Python 策略。</li>
1767
+ </ol>
1768
+ <figure class="guide-image-card">
1769
+ <img src="/image/qmt_deploy/image-18.png" alt="高级模式创建 Python 策略">
1770
+ <figcaption>高级模式创建 Python 策略。</figcaption>
1771
+ </figure>
1772
+ <ol class="guide-list detailed" start="6">
1773
+ <li><strong>启动两个策略。</strong>第一个 QMT 启动 <code>CFQUANT.py</code>,第二个 QMT 启动 <code>CFQUANT_TRADE_LOWLAT.py</code>。</li>
1774
+ </ol>
1775
+ <figure class="guide-image-card">
1776
+ <img src="/image/qmt_deploy/image-7.png" alt="高级模式启动两个策略">
1777
+ <figcaption>启动两个 QMT 里的策略。</figcaption>
1778
+ </figure>
1779
+ <ol class="guide-list detailed" start="7">
1780
+ <li><strong>重启 QMT。</strong>首次部署或替换脚本后,建议重启两个 QMT,再重新启动策略。</li>
1781
+ </ol>
1782
+ <figure class="guide-image-card">
1783
+ <img src="/image/qmt_deploy/image-9.png" alt="高级模式重启 QMT">
1784
+ <figcaption>重启两个 QMT 后重新启动策略。</figcaption>
1785
+ </figure>
1786
+ <ol class="guide-list detailed" start="8">
1787
+ <li><strong>网页端绑定账号。</strong>在 Web 控制台“绑定”页面选择高级模式,并填写普通端和极速交易端 QMT 目录。</li>
1788
+ </ol>
1789
+ <figure class="guide-image-card">
1790
+ <img src="/image/qmt_deploy/image-19.png" alt="高级模式网页端账号绑定">
1791
+ <figcaption>在网页端完成高级模式账号绑定。</figcaption>
1792
+ </figure>
1793
+ <ol class="guide-list detailed" start="9">
1794
+ <li><strong>确认部署成功。</strong>网页端应能看到普通端和极速交易端都在线。</li>
1795
+ </ol>
1796
+ <figure class="guide-image-card">
1797
+ <img src="/image/qmt_deploy/image-8.png" alt="高级模式部署成功提示">
1798
+ <figcaption>高级模式部署成功后的状态提示。</figcaption>
1799
+ </figure>
1800
+ <figure class="guide-image-card">
1801
+ <img src="/image/qmt_deploy/image-20.png" alt="高级模式双端状态">
1802
+ <figcaption>高级模式普通端和极速交易端状态。</figcaption>
1803
+ </figure>
1804
+ <ol class="guide-list detailed" start="10">
1805
+ <li><strong>接口调用测试。</strong>用网页端“接口调试”执行一次调用测试。</li>
1806
+ </ol>
1807
+ <figure class="guide-image-card">
1808
+ <img src="/image/qmt_deploy/image-14.png" alt="高级模式接口调用测试">
1809
+ <figcaption>高级模式接口调用测试。</figcaption>
1810
+ </figure>
1811
+ <ol class="guide-list detailed" start="11">
1812
+ <li><strong>非开盘时间低延迟测试。</strong>可用低延迟测试结果作为链路参考,但真实表现会受 QMT、机器负载和券商环境影响。</li>
1813
+ </ol>
1814
+ <figure class="guide-image-card">
1815
+ <img src="/image/qmt_deploy/image-21.png" alt="高级模式非开盘时间低延迟测试结果">
1816
+ <figcaption>非开盘时间下的低延迟测试结果。</figcaption>
1817
+ </figure>
1818
+ </div>
1819
+ </section>
1820
+ </div>
1821
+
1822
+ <div class="guide-section">
1823
+ <h3>四、写在最后</h3>
1824
+ <ul class="guide-list detailed">
1825
+ <li>部署相对复杂一些,但延迟确实是做得比较低。</li>
1826
+ <li>有不清楚的可以通过首页加入项目交流群。</li>
1827
+ <li>如有远程帮忙部署指导需求,可以添加微信 <code>13696119612</code>,服务费 100 元/次。</li>
1828
+ <li>如有其他二次开发需求、整体系统架构方案、多账号交易矩阵、低延迟链路需求,敬请联系。</li>
1829
+ </ul>
1830
+ </div>
1831
+ </article>
1832
+
1833
+ <article class="tutorial-topic" data-guide-panel="same_account_market">
1834
+ <div class="guide-section">
1835
+ <h3>同账号独立市场</h3>
1836
+ <p>适合同一资金账号拆成上海、深圳两个 QMT 交易端的场景。网页保存一个主账号,交易请求按证券后缀自动分流。</p>
1837
+ <div class="guide-kv wide">
1838
+ <span><code>*.SH</code></span>
1839
+ <strong>走上海 QMT 子桥。</strong>
1840
+ <span><code>*.SZ</code></span>
1841
+ <strong>走深圳 QMT 子桥。</strong>
1842
+ <span>批量下单</span>
1843
+ <strong>自动拆成 SH、SZ 两组请求,再合并返回。</strong>
1844
+ </div>
1845
+ </div>
1846
+
1847
+ <div class="guide-section">
1848
+ <h3>配置步骤</h3>
1849
+ <ol class="guide-list detailed">
1850
+ <li>在“绑定”页编辑账号,打开“同账号独立市场路由”。</li>
1851
+ <li>分别填写上海、深圳 QMT 的 <code>bin.x64</code> 目录。</li>
1852
+ <li>保存后确认两个目录生成市场身份文件。</li>
1853
+ <li>上海 QMT 加载 <code>_SH.py</code>,深圳 QMT 加载 <code>_SZ.py</code>。</li>
1854
+ </ol>
1855
+ </div>
1856
+
1857
+ <div class="guide-section">
1858
+ <h3>入口文件</h3>
1859
+ <div class="guide-table-wrap">
1860
+ <table>
1861
+ <thead>
1862
+ <tr>
1863
+ <th>模式</th>
1864
+ <th>上海</th>
1865
+ <th>深圳</th>
1866
+ </tr>
1867
+ </thead>
1868
+ <tbody>
1869
+ <tr>
1870
+ <td>通用</td>
1871
+ <td><code>CFQUANT_CTYPE_ALL_LOWLAT_SH.py</code></td>
1872
+ <td><code>CFQUANT_CTYPE_ALL_LOWLAT_SZ.py</code></td>
1873
+ </tr>
1874
+ <tr>
1875
+ <td>极致</td>
1876
+ <td><code>CFQUANT_LITE_SH.py</code></td>
1877
+ <td><code>CFQUANT_LITE_SZ.py</code></td>
1878
+ </tr>
1879
+ <tr>
1880
+ <td>高级交易端</td>
1881
+ <td><code>CFQUANT_TRADE_LOWLAT_SH.py</code></td>
1882
+ <td><code>CFQUANT_TRADE_LOWLAT_SZ.py</code></td>
1883
+ </tr>
1884
+ </tbody>
1885
+ </table>
1886
+ </div>
1887
+ </div>
1888
+ </article>
1889
+
1890
+ <article class="tutorial-topic" data-guide-panel="bridge">
1891
+ <div class="guide-section">
1892
+ <h3>多账号通道</h3>
1893
+ <p><code>bridge_id</code> 是内部路由标识。普通用户只需要填写账号和 QMT 目录,Web 会按目录复用或分配通道。</p>
1894
+ <div class="guide-table-wrap">
1895
+ <table>
1896
+ <thead>
1897
+ <tr>
1898
+ <th>场景</th>
1899
+ <th>建议</th>
1900
+ </tr>
1901
+ </thead>
1902
+ <tbody>
1903
+ <tr>
1904
+ <td>单 QMT 单账号</td>
1905
+ <td>使用默认通道 <code>default</code>。</td>
1906
+ </tr>
1907
+ <tr>
1908
+ <td>单 QMT 多账号</td>
1909
+ <td>多个账号可共用同一个 QMT 目录。</td>
1910
+ </tr>
1911
+ <tr>
1912
+ <td>多 QMT 多账号</td>
1913
+ <td>每个账号填写实际登录它的 QMT <code>bin.x64</code> 目录。</td>
1914
+ </tr>
1915
+ </tbody>
1916
+ </table>
1917
+ </div>
1918
+ </div>
1919
+
1920
+ <div class="guide-section">
1921
+ <h3>排查要点</h3>
1922
+ <ul class="guide-list detailed">
1923
+ <li>QMT 日志里的 <code>bridge_id</code> 要和网页绑定状态一致。</li>
1924
+ <li>目录填错时,Web 可能把身份文件写到另一个 QMT。</li>
1925
+ <li>外部程序优先传 <code>account_id</code>,不要手动写死 <code>bridge_id</code>。</li>
1926
+ </ul>
1927
+ </div>
1928
+ </article>
1929
+
1930
+ <article class="tutorial-topic" data-guide-panel="account">
1931
+ <div class="guide-section">
1932
+ <h3>账号绑定</h3>
1933
+ <p>账号绑定是运行配置的核心。每个账号保存自己的账户类型、QMT 目录、首选模式、启用状态和共享行情源标记。</p>
1934
+ <div class="guide-table-wrap">
1935
+ <table>
1936
+ <thead>
1937
+ <tr>
1938
+ <th>字段</th>
1939
+ <th>说明</th>
1940
+ </tr>
1941
+ </thead>
1942
+ <tbody>
1943
+ <tr>
1944
+ <td>资金账号</td>
1945
+ <td>外部请求按它路由,普通和信用账户要区分账户类型。</td>
1946
+ </tr>
1947
+ <tr>
1948
+ <td>QMT 核心目录</td>
1949
+ <td>填写对应 QMT 的 <code>bin.x64</code>,用于身份文件和核心更新。</td>
1950
+ </tr>
1951
+ <tr>
1952
+ <td>运行模式</td>
1953
+ <td><code>ctypes</code>、<code>lite</code>、<code>lttx</code> 三选一。</td>
1954
+ </tr>
1955
+ <tr>
1956
+ <td>高级模式第二目录</td>
1957
+ <td>选择高级模式时必须填写另一个 QMT 的 <code>bin.x64</code>。</td>
1958
+ </tr>
1959
+ <tr>
1960
+ <td>共享行情源</td>
1961
+ <td>多账号时只选一个稳定账号,避免重复订阅全推行情。</td>
1962
+ </tr>
1963
+ </tbody>
1964
+ </table>
1965
+ </div>
1966
+ </div>
1967
+
1968
+ <div class="guide-section">
1969
+ <h3>保存后怎么验证</h3>
1970
+ <ol class="guide-list detailed">
1971
+ <li>刷新“绑定状态”,看首选模式和实际模式。</li>
1972
+ <li>点击“验证”,确认资金和持仓来自正确账号。</li>
1973
+ <li>高级模式离线时会自动回退通用模式,状态里会显示回退原因。</li>
1974
+ </ol>
1975
+ </div>
1976
+ </article>
1977
+
1978
+ <article class="tutorial-topic" data-guide-panel="trade">
1979
+ <div class="guide-section">
1980
+ <h3>交易与回调</h3>
1981
+ <p>交易页适合做实盘前验证:先查资金和持仓,再用小数量测试下单、撤单和回调。</p>
1982
+ <div class="guide-table-wrap">
1983
+ <table>
1984
+ <thead>
1985
+ <tr>
1986
+ <th>能力</th>
1987
+ <th>说明</th>
1988
+ </tr>
1989
+ </thead>
1990
+ <tbody>
1991
+ <tr>
1992
+ <td>单笔下单</td>
1993
+ <td><code>POST /api/order</code>,对应 <code>order_stock</code>。</td>
1994
+ </tr>
1995
+ <tr>
1996
+ <td>批量下单</td>
1997
+ <td><code>POST /api/orders/batch</code>,逐笔提交并合并结果。</td>
1998
+ </tr>
1999
+ <tr>
2000
+ <td>撤单</td>
2001
+ <td><code>POST /api/cancel</code>,委托状态仍以 QMT 和回调为准。</td>
2002
+ </tr>
2003
+ <tr>
2004
+ <td>信用查询</td>
2005
+ <td>支持信用资产、标的、担保品、合约等只读探测。</td>
2006
+ </tr>
2007
+ <tr>
2008
+ <td>回调</td>
2009
+ <td><code>GET /api/callbacks</code> 或 <code>WS /ws/callbacks</code> 接收委托、成交和错误事件。</td>
2010
+ </tr>
2011
+ </tbody>
2012
+ </table>
2013
+ </div>
2014
+ </div>
2015
+
2016
+ <div class="guide-section">
2017
+ <h3>实盘前检查</h3>
2018
+ <ul class="guide-list detailed">
2019
+ <li>确认页面当前账号就是要交易的资金账号。</li>
2020
+ <li>确认下单确认文本、价格、数量和买卖方向。</li>
2021
+ <li>确认回调页能收到委托或错误事件。</li>
2022
+ <li>自动化程序不要只看请求返回,还要结合回调或后续查询确认最终状态。</li>
2023
+ </ul>
2024
+ </div>
2025
+ </article>
2026
+
2027
+ <article class="tutorial-topic" data-guide-panel="latency">
2028
+ <div class="guide-section">
2029
+ <h3>延迟参考</h3>
2030
+ <p>延迟只表示本机程序到 QMT 脚本的链路量级,不代表券商柜台或交易所确认速度。实际结果会受 QMT 版本、券商环境、机器负载和交易时段影响。</p>
2031
+ <div class="guide-callout">
2032
+ <strong>推荐读法</strong>
2033
+ <span>普通用户优先看稳定性;低延迟交易再比较极速交易端和 ctypes 交易通道。</span>
2034
+ </div>
2035
+ </div>
2036
+
2037
+ <div class="guide-section">
2038
+ <h3>当前测试量级</h3>
2039
+ <div class="guide-table-wrap latency-table wide">
2040
+ <table>
2041
+ <thead>
2042
+ <tr>
2043
+ <th>链路</th>
2044
+ <th>查询量级</th>
2045
+ <th>下单请求样本</th>
2046
+ <th>适合场景</th>
2047
+ </tr>
2048
+ </thead>
2049
+ <tbody>
2050
+ <tr>
2051
+ <td>通用 ctypes</td>
2052
+ <td>约 180-260 ms</td>
2053
+ <td>约 20 ms</td>
2054
+ <td>部署简单、功能验证、多账号日常使用。</td>
2055
+ </tr>
2056
+ <tr>
2057
+ <td>高级普通端</td>
2058
+ <td>约 250 ms</td>
2059
+ <td>约 176 ms</td>
2060
+ <td>查询、行情、账号级回调。</td>
2061
+ </tr>
2062
+ <tr>
2063
+ <td>高级极速交易端</td>
2064
+ <td>约 1-4 ms</td>
2065
+ <td>约 1 ms</td>
2066
+ <td>追求更低本机到 QMT 下单链路。</td>
2067
+ </tr>
2068
+ </tbody>
2069
+ </table>
2070
+ </div>
2071
+ </div>
2072
+
2073
+ <div class="guide-section">
2074
+ <h3>注意事项</h3>
2075
+ <ul class="guide-list detailed">
2076
+ <li>撤单请求返回和委托状态变成“已撤”不是同一个时点。</li>
2077
+ <li>午间、收盘后和首次请求通常比交易时段更不稳定。</li>
2078
+ <li>需要严肃评估时,用自己的券商、账号、机器和目标时间段重新测。</li>
2079
+ </ul>
2080
+ </div>
2081
+ </article>
2082
+
2083
+ <article class="tutorial-topic" data-guide-panel="api">
2084
+ <div class="guide-section">
2085
+ <h3>外部接口</h3>
2086
+ <p>“接口”页就是在线调试台。外部程序接入前,先在这里跑通同一个账号和参数。</p>
2087
+ <pre class="guide-code">curl -H "X-API-Key: your-api-key" ^
2088
+ "http://127.0.0.1:8765/api/account?account_id=YOUR_ACCOUNT_ID&sections=asset,positions&force=1"</pre>
2089
+ <p>启用 API Key 后,HTTP 使用 <code>X-API-Key</code> 请求头;WebSocket 使用 <code>apikey</code> 查询参数。</p>
2090
+ </div>
2091
+
2092
+ <div class="guide-section">
2093
+ <h3>常用接口</h3>
2094
+ <div class="guide-table-wrap">
2095
+ <table>
2096
+ <thead>
2097
+ <tr>
2098
+ <th>接口</th>
2099
+ <th>用途</th>
2100
+ </tr>
2101
+ </thead>
2102
+ <tbody>
2103
+ <tr><td><code>GET /api/account</code></td><td>资金、持仓、委托、成交。</td></tr>
2104
+ <tr><td><code>POST /api/order</code></td><td>单笔下单。</td></tr>
2105
+ <tr><td><code>POST /api/orders/batch</code></td><td>批量下单。</td></tr>
2106
+ <tr><td><code>POST /api/cancel</code></td><td>撤单。</td></tr>
2107
+ <tr><td><code>POST /api/data/full-tick</code></td><td>实时 Tick。</td></tr>
2108
+ <tr><td><code>POST /api/data/market</code></td><td>K 线和行情数据。</td></tr>
2109
+ <tr><td><code>POST /api/data/history/download</code></td><td>历史行情下载。</td></tr>
2110
+ <tr><td><code>POST /api/data/financial</code></td><td>财务数据读取。</td></tr>
2111
+ <tr><td><code>GET /api/callbacks</code></td><td>读取交易回调。</td></tr>
2112
+ <tr><td><code>WS /ws/callbacks</code></td><td>实时交易回调。</td></tr>
2113
+ <tr><td><code>WS /ws/quotes</code></td><td>实时行情事件。</td></tr>
2114
+ </tbody>
2115
+ </table>
2116
+ </div>
2117
+ </div>
2118
+ </article>
2119
+
2120
+ <article class="tutorial-topic" data-guide-panel="troubleshooting">
2121
+ <div class="guide-section">
2122
+ <h3>排查问题</h3>
2123
+ <p>按层排查最快:先确认 Web 能访问,再看本地服务,再看 QMT 脚本,最后看账号和权限。</p>
2124
+ <div class="guide-table-wrap">
2125
+ <table>
2126
+ <thead>
2127
+ <tr>
2128
+ <th>现象</th>
2129
+ <th>优先检查</th>
2130
+ <th>处理</th>
2131
+ </tr>
2132
+ </thead>
2133
+ <tbody>
2134
+ <tr>
2135
+ <td>网页打不开</td>
2136
+ <td>Web 端口、启动日志</td>
2137
+ <td>重启服务,查看 <code>log/cfquant_web_server.stderr.log</code>。</td>
2138
+ </tr>
2139
+ <tr>
2140
+ <td>QMT 离线</td>
2141
+ <td>入口脚本、QMT 登录、<code>bridge_id</code></td>
2142
+ <td>重启 QMT 入口,确认加载了当前模式对应脚本。</td>
2143
+ </tr>
2144
+ <tr>
2145
+ <td>高级模式缺交易端</td>
2146
+ <td>第二个 QMT 目录、<code>CFQUANT_TRADE_LOWLAT.py</code></td>
2147
+ <td>在绑定页补充极速交易端目录并重新保存。</td>
2148
+ </tr>
2149
+ <tr>
2150
+ <td>查不到账号数据</td>
2151
+ <td>账号类型、QMT 登录账号、绑定目录</td>
2152
+ <td>在绑定页点击验证,确认资金和持仓来自预期账号。</td>
2153
+ </tr>
2154
+ <tr>
2155
+ <td>下单失败</td>
2156
+ <td>确认文本、价格数量、权限、回调错误</td>
2157
+ <td>先小数量测试,再查看回调页和 QMT 日志。</td>
2158
+ </tr>
2159
+ <tr>
2160
+ <td>版本或缓存异常</td>
2161
+ <td>前端版本、浏览器缓存</td>
2162
+ <td>重启 Web 后用 <code>Ctrl + F5</code> 强制刷新。</td>
2163
+ </tr>
2164
+ </tbody>
2165
+ </table>
2166
+ </div>
2167
+ </div>
2168
+ </article>
2169
+ </section>
2170
+ </div>
2171
+ </div>
2172
+
2173
+ <div class="panel span-12 view-panel view-overview view-trade view-orders view-status view-callbacks">
2174
+ <div class="panel-head">
2175
+ <h2>日志</h2>
2176
+ <button id="clearLogBtn">清空</button>
2177
+ </div>
2178
+ <div id="logBox" class="log-box"></div>
2179
+ </div>
2180
+ </section>
2181
+ </main>
2182
+ </div>
2183
+ </div>
2184
+
2185
+ <div id="bindingDialogOverlay" class="binding-dialog-overlay hidden" aria-hidden="true">
2186
+ <div class="binding-dialog" role="dialog" aria-modal="true" aria-labelledby="bindingDialogTitle">
2187
+ <div class="binding-dialog-head">
2188
+ <div>
2189
+ <strong id="bindingDialogTitle">添加账号绑定</strong>
2190
+ <span id="bindingDialogSubtitle">保存后系统会按账号自动路由到对应 QMT 通道。</span>
2191
+ </div>
2192
+ <button id="closeBindingDialogBtn" type="button" aria-label="关闭绑定编辑">关闭</button>
2193
+ </div>
2194
+ <form id="bindingForm" class="form-grid binding-dialog-form">
2195
+ <label class="field">
2196
+ <span>账号名称(可选)</span>
2197
+ <input id="bindingDisplayName" name="display_name" placeholder="主账户 / 信用账户 / 家人账户" autocomplete="off">
2198
+ </label>
2199
+ <label class="field">
2200
+ <span>账号</span>
2201
+ <input id="bindingAccountId" name="account_id" placeholder="请输入资金账号" autocomplete="off">
2202
+ </label>
2203
+ <label class="field">
2204
+ <span>账户类型</span>
2205
+ <select id="bindingAccountType" name="account_type">
2206
+ <option value="STOCK">普通证券账户</option>
2207
+ <option value="CREDIT">信用账户</option>
2208
+ </select>
2209
+ </label>
2210
+ <label class="field wide">
2211
+ <span>QMT 核心目录(可选)</span>
2212
+ <input id="bindingQmtDir" name="qmt_dir" placeholder="D:\国金证券QMT交易端\bin.x64" autocomplete="off">
2213
+ <small>建议填写 QMT 的 bin.x64 目录。留空时该账号仍可运行,但自动更新、脚本定位和多 QMT 部署辅助会失效。</small>
2214
+ </label>
2215
+ <label class="field">
2216
+ <span>账号模式</span>
2217
+ <select id="bindingMode" name="mode">
2218
+ <option value="ctypes">通用模式(ctypes)</option>
2219
+ <option value="lite">极致模式(纯 ctypes 自包含)</option>
2220
+ <option value="lttx">高级模式(两个 QMT)</option>
2221
+ </select>
2222
+ </label>
2223
+ <label id="bindingQmtTradeDirField" class="field wide hidden">
2224
+ <span>高级模式极速交易端 QMT 核心目录</span>
2225
+ <input id="bindingQmtTradeDir" name="qmt_trade_dir" placeholder="D:\国金证券QMT交易端-交易端\bin.x64" autocomplete="off">
2226
+ <small>高级模式必须填写与普通端不同的第二个 QMT <code>bin.x64</code> 目录,用于交易端脚本更新和身份配置。</small>
2227
+ </label>
2228
+ <div class="market-routing-panel wide">
2229
+ <label class="toggle binding-dialog-toggle">
2230
+ <input id="bindingMarketRoutingEnabled" name="market_routing_enabled" type="checkbox">
2231
+ <span>开启同账号独立市场路由</span>
2232
+ </label>
2233
+ <div class="market-routing-grid">
2234
+ <label class="field">
2235
+ <span>上海交易端目录</span>
2236
+ <input id="bindingMarketShQmtDir" name="market_sh_qmt_dir" placeholder="D:\上海QMT交易端\bin.x64" autocomplete="off">
2237
+ </label>
2238
+ <label class="field">
2239
+ <span>上海 bridge_id(可选)</span>
2240
+ <input id="bindingMarketShBridgeId" name="market_sh_bridge_id" placeholder="自动生成" autocomplete="off">
2241
+ </label>
2242
+ <label class="field">
2243
+ <span>深圳交易端目录</span>
2244
+ <input id="bindingMarketSzQmtDir" name="market_sz_qmt_dir" placeholder="D:\深圳QMT交易端\bin.x64" autocomplete="off">
2245
+ </label>
2246
+ <label class="field">
2247
+ <span>深圳 bridge_id(可选)</span>
2248
+ <input id="bindingMarketSzBridgeId" name="market_sz_bridge_id" placeholder="自动生成" autocomplete="off">
2249
+ </label>
2250
+ </div>
2251
+ </div>
2252
+ <label class="toggle binding-dialog-toggle">
2253
+ <input id="bindingDataProvider" name="data_provider" type="checkbox">
2254
+ <span>作为共享行情数据提供商</span>
2255
+ </label>
2256
+ <div id="bindingSaveStatus" class="binding-save-status hidden" role="status" aria-live="polite"></div>
2257
+ <div class="binding-dialog-actions">
2258
+ <button id="reinitializeSetupBtn" type="button">重新初始化默认配置</button>
2259
+ <span id="bindingDialogHint" class="metric-note"></span>
2260
+ <button id="cancelBindingDialogBtn" type="button">取消</button>
2261
+ <button class="primary" type="submit">保存绑定</button>
2262
+ </div>
2263
+ </form>
2264
+ </div>
2265
+ </div>
2266
+
2267
+ <div id="qmtUpdateProgressOverlay" class="update-progress-overlay hidden" aria-hidden="true">
2268
+ <div class="update-progress-dialog" role="dialog" aria-modal="true" aria-labelledby="qmtUpdateProgressTitle">
2269
+ <div class="update-progress-head">
2270
+ <div>
2271
+ <strong id="qmtUpdateProgressTitle">QMT 核心更新进度</strong>
2272
+ <span id="qmtUpdateProgressDetail">准备更新 QMT 核心包...</span>
2273
+ </div>
2274
+ <button id="qmtUpdateProgressCloseBtn" type="button" disabled>关闭</button>
2275
+ </div>
2276
+ <div class="update-progress-meter" aria-hidden="true">
2277
+ <span id="qmtUpdateProgressBar"></span>
2278
+ </div>
2279
+ <div class="update-progress-meta">
2280
+ <span>当前进度</span>
2281
+ <strong id="qmtUpdateProgressPercent">0%</strong>
2282
+ </div>
2283
+ <ol id="qmtUpdateProgressSteps" class="update-progress-steps"></ol>
2284
+ <div class="update-progress-actions">
2285
+ <button id="qmtUpdateProgressCloseBottomBtn" type="button" disabled>完成后关闭</button>
2286
+ </div>
2287
+ </div>
2288
+ </div>
2289
+
2290
+ <div id="updateRestartNoticeOverlay" class="restart-notice-overlay hidden" aria-hidden="true">
2291
+ <div class="restart-notice-dialog" role="dialog" aria-modal="true" aria-labelledby="updateRestartNoticeTitle">
2292
+ <div class="restart-notice-head">
2293
+ <div>
2294
+ <span>更新后操作</span>
2295
+ <strong id="updateRestartNoticeTitle">QMT 侧需要重启</strong>
2296
+ <p id="updateRestartNoticeSummary">核心文件已经写入磁盘,但 QMT 运行中的脚本不会自动加载新代码。</p>
2297
+ </div>
2298
+ <button id="updateRestartNoticeCloseBtn" type="button" aria-label="关闭重启提醒">关闭</button>
2299
+ </div>
2300
+ <div id="updateRestartNoticeBody" class="restart-notice-body"></div>
2301
+ <div class="restart-notice-actions">
2302
+ <button id="updateRestartNoticeSettingsBtn" type="button">打开更新设置</button>
2303
+ <button id="updateRestartNoticeCloseBottomBtn" class="primary" type="button">我知道了</button>
2304
+ </div>
2305
+ </div>
2306
+ </div>
2307
+
2308
+ <div class="image-lightbox" id="imageLightbox" aria-hidden="true">
2309
+ <button class="image-lightbox-close" id="imageLightboxClose" type="button" aria-label="关闭图片预览">关闭</button>
2310
+ <img id="imageLightboxImg" alt="">
2311
+ <div class="image-lightbox-caption" id="imageLightboxCaption"></div>
2312
+ </div>
2313
+
2314
+ <script src="/vendor/mermaid.min.js?v=10.9.1"></script>
2315
+ <script src="/app.js?v=web_20260904_09"></script>
2316
+ </body>
2317
+ </html>