xtquant-share 1.1.2__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.
@@ -0,0 +1,756 @@
1
+ Metadata-Version: 2.4
2
+ Name: xtquant-share
3
+ Version: 1.1.2
4
+ Summary: Xtreme Quant Share - eXtreme transparent sharing proxy for XtQuant on macOS/Linux
5
+ Author-email: Jason Hu <63170682@qq.com>
6
+ License-Expression: GPL-3.0-only
7
+ Project-URL: Homepage, https://gitee.com/jdragonhu/xqshare
8
+ Project-URL: Documentation, https://gitee.com/jdragonhu/xqshare#readme
9
+ Project-URL: Repository, https://gitee.com/jdragonhu/xqshare
10
+ Project-URL: Issues, https://gitee.com/jdragonhu/xqshare/issues
11
+ Keywords: xtquant,rpyc,remote,proxy,quant,stock,trading,qmt
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Financial and Insurance Industry
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Office/Business :: Financial :: Investment
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: System :: Networking
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: rpyc>=6.0
29
+ Requires-Dist: python-dotenv>=1.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7.0; extra == "dev"
32
+ Requires-Dist: black>=23.0; extra == "dev"
33
+ Requires-Dist: flake8>=6.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # 极限量化 (xqshare)
37
+
38
+ 完全透明的 XtQuant 远程调用方案,让 macOS/Linux 可以像本地一样调用 Windows 上的 xtquant 库。
39
+
40
+ ## 特性
41
+
42
+ - ✅ **完全透明** - 客户端用法与本地 xtquant 完全一致
43
+ - ✅ **认证加密** - 支持 HMAC token 认证,可选 SSL/TLS 加密
44
+ - ✅ **断线重连** - 自动检测断线并重连,指数退避策略
45
+ - ✅ **心跳保活** - 定期心跳检测,保持连接活跃
46
+ - ✅ **异步回调** - 支持行情订阅等回调场景
47
+ - ✅ **完整日志** - API调用日志,记录函数名、参数、耗时
48
+ - ✅ **零学习成本** - 无需记忆新 API
49
+
50
+ ## 架构
51
+
52
+ ```
53
+ ┌─────────────────┐ ┌─────────────────┐
54
+ │ macOS/Linux │ RPyC │ Windows │
55
+ │ (客户端) │ ──────► │ (服务端) │
56
+ │ │ 18812 │ │
57
+ │ xt.xtdata.xxx │ ◄────── │ xtquant 实际运行│
58
+ │ xt.xttrader.xxx│ 加密 │ │
59
+ │ │ 回调 │ │
60
+ └─────────────────┘ └─────────────────┘
61
+ ```
62
+
63
+ ## 安装
64
+
65
+ ### 从 PyPI 安装(推荐)
66
+
67
+ ```bash
68
+ pip install xqshare
69
+ ```
70
+
71
+ ### 从源码安装
72
+
73
+ ```bash
74
+ # Gitee(国内推荐)
75
+ git clone https://gitee.com/jdragonhu/xqshare.git
76
+
77
+ # GitHub(备用)
78
+ git clone https://github.com/jasonhu/xqshare.git
79
+
80
+ cd xqshare
81
+ pip install -e .
82
+ ```
83
+
84
+ ### 依赖
85
+
86
+ ```bash
87
+ pip install rpyc
88
+ ```
89
+
90
+ ## 快速启动
91
+
92
+ ### 启动前准备
93
+
94
+ **服务端(Windows):** Python 环境 | 启动 miniQMT 并登录 | `pip install xqshare pyyaml`
95
+
96
+ **客户端(macOS/Linux):** Python 环境 | `pip install xqshare`
97
+
98
+ ### 服务器 Windows 快速启动
99
+
100
+ ```powershell
101
+ python -m xqshare.server
102
+ ```
103
+
104
+ ### 客户端快速测试
105
+
106
+ ```bash
107
+ export XQSHARE_REMOTE_HOST="192.168.1.100"
108
+ xtdata get_stock_list_in_sector --sector-name "沪深A股" --limit 10
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 命令行工具
114
+
115
+ 安装后提供两个命令行工具:`xtdata`(行情)和 `xttrader`(交易)。
116
+
117
+ ### xtdata - 行情数据工具
118
+
119
+ ```bash
120
+ # 查看帮助
121
+ xtdata --help
122
+
123
+ # 获取股票列表
124
+ xtdata get_stock_list_in_sector --sector-name "沪深A股"
125
+
126
+ # 限制输出数量
127
+ xtdata --limit 100 get_stock_list_in_sector --sector-name "沪深A股"
128
+
129
+ # 获取K线数据
130
+ xtdata get_market_data_ex --stock-list "['000001.SZ']" --period "1d" --start-time "20260101" --end-time "20260228"
131
+
132
+ # 获取实时行情
133
+ xtdata get_full_tick --stock-list "['000001.SZ', '600000.SH']"
134
+ ```
135
+
136
+ ### xttrader - 交易工具
137
+
138
+ ```bash
139
+ # 查看帮助
140
+ xttrader --help
141
+
142
+ # 查询持仓(需要设置账号)
143
+ xttrader --account-id "12345678" query_stock_positions
144
+
145
+ # 查询资产
146
+ xttrader --account-id "12345678" query_stock_asset
147
+
148
+ # 下单(需要更多参数)
149
+ xttrader --account-id "12345678" order_stock --stock-code "000001.SZ" --order-type 23 --order-volume 100
150
+ ```
151
+
152
+ ### 全局参数
153
+
154
+ | 参数 | 环境变量 | 说明 |
155
+ |------|----------|------|
156
+ | `--host` | XQSHARE_REMOTE_HOST | 服务端地址 |
157
+ | `--port` | XQSHARE_REMOTE_PORT | 服务端端口 |
158
+ | `--secret` | XQSHARE_CLIENT_SECRET | 认证密钥 |
159
+ | `--client-id` | XQSHARE_CLIENT_ID | 客户端标识 |
160
+ | `--limit`, `-n` | - | 列表输出数量限制(默认50) |
161
+ | `--verbose`, `-v` | - | 显示详细日志 |
162
+
163
+ ### 限制
164
+
165
+ - **不支持订阅功能**:以 `subscribe` 开头的命令(需要回调函数)
166
+ - **不支持回调参数**:`callback` 参数(需要使用 Python API)
167
+ - **交易工具限制**:不支持以 `register` 开头的命令
168
+
169
+ **基础下载周期**:
170
+
171
+ 只有以下 3 个周期是基础数据,需要实际下载:
172
+ | 周期 | 说明 |
173
+ |------|------|
174
+ | `1m` | 1分钟线,1年数据,58378条 |
175
+ | `5m` | 5分钟线,1年数据,11640条 |
176
+ | `1d` | 日线,全量 |
177
+
178
+ ---
179
+
180
+ ## 示例脚本
181
+
182
+ 项目提供了示例脚本,位于 `examples/` 目录,方便快速测试。
183
+
184
+ **推荐:使用环境变量配置(避免敏感信息泄露)**
185
+ ```bash
186
+ # 设置环境变量
187
+ export XQSHARE_REMOTE_HOST="192.168.1.100"
188
+ export XQSHARE_CLIENT_SECRET="your-secret"
189
+
190
+ # 获取股票列表
191
+ python examples/get_stock_list.py --sector "沪深300"
192
+
193
+ # 下载历史数据(首次使用需要先下载数据)
194
+ python examples/download_history_data2.py
195
+
196
+ # 获取K线数据(支持 1d/1m/5m/15m/30m/60m)
197
+ python examples/get_market_data_ex.py --codes "000001.SZ,600000.SH" --period 1d
198
+
199
+ # 获取实时行情(含五档盘口)
200
+ python examples/get_tick_data.py --codes "000001.SZ"
201
+
202
+ # 订阅行情推送(duration=0 持续订阅,Ctrl+C 停止)
203
+ python examples/subscribe_quote.py --codes "000001.SZ" --duration 60
204
+ ```
205
+
206
+ **交易功能(需要额外配置):**
207
+ ```bash
208
+ # 设置交易相关环境变量
209
+ export QMT_ACCOUNT_ID="12345678"
210
+ export QMT_USERDATA_PATH="C:\\QMT\\userdata_mini"
211
+
212
+ # 查询持仓
213
+ python examples/query_positions.py
214
+ ```
215
+
216
+ **备选:命令行参数(覆盖环境变量):**
217
+ ```bash
218
+ # 显式指定服务端地址
219
+ python examples/get_stock_list.py --host 192.168.1.100 --sector "沪深300"
220
+
221
+ # 显式指定认证密钥
222
+ python examples/get_tick_data.py --host 192.168.1.100 --secret "your-secret" --codes "000001.SZ"
223
+
224
+ # 查看帮助
225
+ python examples/get_stock_list.py --help
226
+ ```
227
+
228
+ ---
229
+
230
+ ## API 文档
231
+
232
+ ```python
233
+ from xqshare import XtQuantRemote, connect, disconnect, xtdata, xttrader, xttype
234
+
235
+ # 方式1:类实例(推荐)
236
+ with XtQuantRemote("192.168.1.100", client_secret="xxx") as xt:
237
+ stocks = xt.xtdata.get_stock_list_in_sector("沪深A股")
238
+
239
+ # 方式2:全局便捷函数
240
+ connect(host="192.168.1.100", client_secret="xxx")
241
+ stocks = xtdata.get_stock_list_in_sector("沪深A股")
242
+ disconnect()
243
+ ```
244
+
245
+ **核心属性/方法:**
246
+ - `xt.xtdata` - 行情数据模块
247
+ - `xt.xttype` - 类型定义模块(StockAccount 等)
248
+ - `xt.datadir` - QMT datadir 文件解析模块(无需 miniQMT 进程)
249
+ - `xt.create_trader()` - 创建交易实例
250
+
251
+ 详细 API 请查看 [xqshare/client.py](xqshare/client.py) 源码。
252
+
253
+ ---
254
+
255
+ ## datadir 文件解析功能
256
+
257
+ `xqshare.datadir` 将 Windows 端 QMT `datadir` 目录的**直接文件解析能力**通过 RPyC 透明暴露给 Mac/Linux 端,无需 miniQMT 进程即可读取 K 线、板块等数据,作为 `xtdata` API 的补充数据源。
258
+
259
+ ### 架构
260
+
261
+ ```
262
+ Mac/Linux Windows
263
+ ┌──────────────────────────┐ RPyC ┌──────────────────────────────┐
264
+ │ xqshare.xtdata │ ────────► │ xtdata(原生 xtquant) │
265
+ │ xqshare.datadir ← 新增 │ ────────► │ QmtDataReader(datadir/) │
266
+ └──────────────────────────┘ │ (直接读取本地 .DAT 文件) │
267
+ └──────────────────────────────┘
268
+ ```
269
+
270
+ ### Server 端配置(Windows)
271
+
272
+ 在 `.env` 文件中配置 datadir 路径:
273
+
274
+ ```ini
275
+ # [可选] QMT datadir 目录路径(用于文件解析功能)
276
+ # 若不配置,server 启动时会尝试通过 xtdata.get_data_dir() 自动推断
277
+ QMT_DATADIR_PATH=D:\国金证券QMT交易端\datadir
278
+ ```
279
+
280
+ > **自动推断规则**:若未配置 `QMT_DATADIR_PATH`,server 会尝试调用 `xtdata.get_data_dir()` 获取默认路径,并自动将 `userdata_mini\datadir` 替换为 `datadir`(主数据目录,数据更全)。
281
+
282
+ ### Client 端使用
283
+
284
+ ```python
285
+ from xqshare import XtQuantRemote
286
+
287
+ with XtQuantRemote("192.168.1.100", client_secret="my-secret") as xt:
288
+ # 读取 K 线数据(直接解析 .DAT 文件,无需 miniQMT 进程)
289
+ df = xt.datadir.kline("600000.SH", "1d")
290
+ print(df.tail())
291
+
292
+ # 读取 5 分钟线
293
+ df5m = xt.datadir.kline("000001.SZ", "5m")
294
+
295
+ # 获取板块分类列表
296
+ categories = xt.datadir.sector_categories()
297
+ print(categories) # ['申万行业', '证监会行业', ...]
298
+
299
+ # 获取某分类下所有板块成分股
300
+ sw_sectors = xt.datadir.sectors("申万行业") # {板块名: [代码列表]}
301
+
302
+ # 获取单个板块成分股
303
+ bank_stocks = xt.datadir.sector("申万行业", "SW1银行")
304
+ print(f"银行板块:{len(bank_stocks)} 只")
305
+ ```
306
+
307
+ ### 全局便捷方式
308
+
309
+ ```python
310
+ import xqshare
311
+
312
+ xqshare.connect(host="192.168.1.100", client_secret="my-secret")
313
+
314
+ # 与 xqshare.xtdata 用法完全对称
315
+ df = xqshare.datadir.kline("600000.SH", "1d")
316
+ ```
317
+
318
+ ### 与 xtdata 的对比
319
+
320
+ | 特性 | `xqshare.xtdata` | `xqshare.datadir` |
321
+ |------|-----------------|-------------------|
322
+ | 数据来源 | miniQMT 进程 API | 直接解析 .DAT 文件 |
323
+ | 是否需要 miniQMT 运行 | ✅ 必须 | ❌ 不需要 |
324
+ | 支持实时行情 | ✅ 支持 | ❌ 不支持 |
325
+ | 支持历史 K 线 | ✅ 支持 | ✅ 支持 |
326
+ | 支持板块成分股 | ✅ 支持 | ✅ 支持 |
327
+ | 适用场景 | 实时/在线场景 | 离线/备用/批量场景 |
328
+
329
+ ### datadir 不可用时的处理
330
+
331
+ 若 server 端未配置 `QMT_DATADIR_PATH` 且无法自动推断,调用 `datadir` 相关方法时会抛出 `RuntimeError`,包含明确的配置提示:
332
+
333
+ ```
334
+ RuntimeError: datadir 不可用:未配置 QMT_DATADIR_PATH 且无法自动推断路径
335
+ 路径:<未配置>
336
+ 请在 server 端 .env 中配置 QMT_DATADIR_PATH,或确认 xtdata.get_data_dir() 可用。
337
+ ```
338
+
339
+ ---
340
+
341
+ ## 使用示例
342
+
343
+ ```python
344
+ from xqshare import XtQuantRemote
345
+
346
+ with XtQuantRemote("192.168.1.100", client_secret="my-secret") as xt:
347
+ # 获取股票列表
348
+ stocks = xt.xtdata.get_stock_list_in_sector("沪深A股")
349
+ print(f"股票数量: {len(stocks)}")
350
+
351
+ # 获取K线数据
352
+ df = xt.xtdata.get_market_data(
353
+ stock_list=["000001.SZ", "600000.SH"],
354
+ period="1d",
355
+ start_time="20260101"
356
+ )
357
+ print(df)
358
+
359
+ # 获取实时行情
360
+ ticks = xt.xtdata.get_full_tick(["000001.SZ"])
361
+ print(ticks)
362
+ ```
363
+
364
+ ### 交易功能
365
+
366
+ ```python
367
+ from xqshare import XtQuantRemote
368
+
369
+ with XtQuantRemote("192.168.1.100", client_secret="my-secret") as xt:
370
+ # 创建交易实例(已自动 start)
371
+ # userdata_path 可通过环境变量 QMT_USERDATA_PATH 配置
372
+ trader = xt.create_trader("C:\\QMT\\userdata_mini")
373
+
374
+ # 创建账户对象
375
+ account = xt.xttype.StockAccount("12345678", "STOCK")
376
+
377
+ # 连接交易服务器
378
+ trader.connect()
379
+
380
+ # 查询持仓
381
+ positions = trader.query_stock_positions(account)
382
+ for pos in positions:
383
+ print(f"股票: {pos.stock_code}, 持仓: {pos.volume}")
384
+ ```
385
+
386
+ **更多示例请查看 [examples/](examples/) 目录:**
387
+
388
+ | 文件 | 功能 |
389
+ |------|------|
390
+ | `get_stock_list.py` | 获取股票列表 |
391
+ | `download_history_data2.py` | 下载历史数据 |
392
+ | `get_market_data_ex.py` | 获取K线数据 |
393
+ | `get_tick_data.py` | 获取实时行情 |
394
+ | `subscribe_quote.py` | 订阅行情推送 |
395
+ | `query_positions.py` | 查询账户持仓 |
396
+
397
+ ### 账户类型
398
+
399
+ | account_type | 说明 |
400
+ |--------------|------|
401
+ | `STOCK` | 普通股票账户 |
402
+ | `CREDIT` | 信用账户(两融) |
403
+ | `FUTURE` | 期货账户 |
404
+ | `HUGANGTONG` | 沪港通 |
405
+ | `SHENGANGTONG` | 深港通 |
406
+
407
+ ---
408
+
409
+ ## 日志系统
410
+
411
+ ### 服务端日志
412
+
413
+ **日志文件位置:**
414
+ ```
415
+ logs/
416
+ ├── xtquant_service_20260228.log # 主日志
417
+ └── api_calls_20260228.log # API调用日志(单独文件)
418
+ ```
419
+
420
+ **日志格式:**
421
+ ```
422
+ 时间戳 | 级别 | 模块 | 消息
423
+ 2026-02-28 23:45:12.345 | INFO | api | [CALL] get_market_data | ...
424
+ ```
425
+
426
+ **API调用日志记录内容:**
427
+ - 函数名称
428
+ - 客户端信息(client_id + IP)
429
+ - 调用参数(截断摘要)
430
+ - 执行耗时(毫秒)
431
+ - 返回值摘要
432
+
433
+ **日志示例:**
434
+ ```
435
+ 2026-02-28 23:45:12.345 | INFO | api | [CALL] get_market_data | client=my-app@192.168.1.50 | args=(['000001.SZ'],) | kwargs={'period': '1d', 'start_time': '20260101'}
436
+ 2026-02-28 23:45:12.456 | INFO | api | [OK] get_market_data | elapsed=111.23ms | result=DataFrame[shape=(100, 6)]
437
+
438
+ 2026-02-28 23:45:15.123 | INFO | api | [CALL] get_full_tick | client=my-app@192.168.1.50 | args=(['000001.SZ'],) | kwargs={}
439
+ 2026-02-28 23:45:15.145 | INFO | api | [OK] get_full_tick | elapsed=22.11ms | result=dict{000001.SZ}
440
+
441
+ 2026-02-28 23:45:20.000 | ERROR | api | [ERROR] get_market_data | elapsed=5000.00ms | error=TimeoutError: Connection timed out
442
+ ```
443
+
444
+ ### 客户端日志
445
+
446
+ **日志文件位置:**
447
+ ```
448
+ logs/client_20260228.log
449
+ ```
450
+
451
+ **客户端也会记录调用:**
452
+ ```python
453
+ # 设置日志级别
454
+ xt = XtQuantRemote("192.168.1.100", log_level="DEBUG")
455
+ ```
456
+
457
+ 客户端日志示例:
458
+ ```
459
+ 2026-02-28 23:50:01.123 | INFO | [OK] xtdata.get_market_data | 111.23ms | DataFrame[shape=(100, 6)]
460
+ 2026-02-28 23:50:02.456 | INFO | [OK] xtdata.get_full_tick | 22.11ms | dict[1 keys]
461
+ 2026-02-28 23:50:05.000 | ERROR | [ERROR] xtdata.get_market_data | 5000.00ms | TimeoutError: Connection timed out
462
+ ```
463
+
464
+ ---
465
+
466
+ ## 配置选项
467
+
468
+ ### 客户端参数
469
+
470
+ | 参数 | 说明 | 默认值 |
471
+ |------|------|--------|
472
+ | host | 服务端地址 | localhost |
473
+ | port | 服务端端口 | 18812 |
474
+ | client_id | 客户端标识 | default |
475
+ | client_secret | 认证密钥 | 空 |
476
+ | use_ssl | 启用 SSL | False |
477
+ | ssl_verify | 验证 SSL 证书 | True |
478
+ | auto_reconnect | 自动重连 | True |
479
+ | max_retries | 最大重试次数 | 5 |
480
+ | heartbeat_interval | 心跳间隔(秒) | 30 |
481
+ | log_level | 日志级别 | INFO |
482
+ | callback_port | 回调服务器端口 | 0(自动) |
483
+
484
+ ### 服务端参数
485
+
486
+ | 参数 | 说明 | 默认值 |
487
+ |------|------|--------|
488
+ | --host | 监听地址 | 0.0.0.0 |
489
+ | --port | 监听端口 | 18812 |
490
+ | --ssl | 启用 SSL | False |
491
+ | --cert | SSL 证书文件 | - |
492
+ | --key | SSL 私钥文件 | - |
493
+ | --log-level | 日志级别 | INFO |
494
+
495
+ ---
496
+
497
+ ## 认证机制
498
+
499
+ 服务端和客户端需要配置相同的密钥,详见上方"环境变量配置"。
500
+
501
+ ### 多客户端认证
502
+
503
+ 服务端为每个客户端配置独立密钥:
504
+ ```bash
505
+ export XQSHARE_CLIENT_app1="secret-for-app1"
506
+ export XQSHARE_CLIENT_app2="secret-for-app2"
507
+ ```
508
+
509
+ 客户端:
510
+ ```python
511
+ xt1 = XtQuantRemote(client_id="app1", client_secret="secret-for-app1")
512
+ xt2 = XtQuantRemote(client_id="app2", client_secret="secret-for-app2")
513
+ ```
514
+
515
+ ---
516
+
517
+ ## SSL 加密
518
+
519
+ ### 生成自签名证书
520
+
521
+ ```bash
522
+ openssl genrsa -out server.key 2048
523
+ openssl req -new -x509 -days 365 -key server.key -out server.crt
524
+ ```
525
+
526
+ ### 启动服务端
527
+
528
+ ```bash
529
+ python -m xqshare.server --ssl --cert server.crt --key server.key
530
+ ```
531
+
532
+ ### 客户端连接
533
+
534
+ ```python
535
+ xt = XtQuantRemote(
536
+ host="192.168.1.100",
537
+ use_ssl=True,
538
+ ssl_verify=False # 自签名证书需禁用验证
539
+ )
540
+ ```
541
+
542
+ ---
543
+
544
+ ## 断线重连
545
+
546
+ 自动检测连接断开并重连:
547
+ - **检测机制**:心跳超时、调用异常
548
+ - **重连策略**:指数退避(1s → 2s → 4s → 8s → 16s...)
549
+ - **最大重试**:默认 5 次
550
+ - **自动恢复订阅**:重连后自动重新订阅行情
551
+
552
+ ```python
553
+ xt = XtQuantRemote(
554
+ host="192.168.1.100",
555
+ auto_reconnect=True,
556
+ max_retries=10,
557
+ heartbeat_interval=15,
558
+ )
559
+ ```
560
+
561
+ ---
562
+
563
+ ## 项目结构
564
+
565
+ ```
566
+ xqshare/
567
+ ├── xqshare/ # 包目录
568
+ │ ├── __init__.py # 包入口
569
+ │ ├── client.py # 客户端
570
+ │ ├── server.py # 服务端
571
+ │ └── tools/ # 命令行工具
572
+ │ ├── __init__.py
573
+ │ ├── common.py # 共享模块
574
+ │ ├── xtdata.py # 行情命令行工具
575
+ │ └── xttrader.py # 交易命令行工具
576
+ ├── examples/ # 示例代码
577
+ │ ├── get_stock_list.py # 获取股票列表
578
+ │ ├── download_history_data.py # 下载历史数据(回调版本)
579
+ │ ├── download_history_data2.py # 下载历史数据(服务端封装版本)
580
+ │ ├── get_market_data.py # 获取K线数据
581
+ │ ├── get_market_data_ex.py # 获取K线数据(推荐,格式更直观)
582
+ │ ├── get_tick_data.py # 获取实时行情
583
+ │ ├── subscribe_quote.py # 订阅行情推送
584
+ │ └── query_positions.py # 查询账户持仓
585
+ ├── tests/ # 测试目录
586
+ │ ├── __init__.py
587
+ │ ├── test_client.py # 客户端测试
588
+ │ ├── test_server.py # 服务端测试
589
+ │ └── test_integration.py # 集成测试
590
+ ├── README.md # 文档
591
+ ├── pyproject.toml # 包配置
592
+ ├── pytest.ini # 测试配置
593
+ └── LICENSE # GPLv3 许可证
594
+ ```
595
+
596
+ ---
597
+
598
+ ## 开发
599
+
600
+ ### 运行测试
601
+
602
+ ```bash
603
+ # 安装开发依赖
604
+ pip install -e ".[dev]"
605
+
606
+ # 运行单元测试
607
+ pytest tests/
608
+
609
+ # 运行集成测试(需要启动服务端)
610
+ pytest tests/ -m integration
611
+ ```
612
+
613
+ ### 代码风格
614
+
615
+ ```bash
616
+ # 格式化代码
617
+ black xqshare/
618
+
619
+ # 检查代码
620
+ flake8 xqshare/
621
+ ```
622
+
623
+ ---
624
+
625
+ ## 打包与发布
626
+
627
+ ### 环境准备
628
+
629
+ ```bash
630
+ # 安装打包和发布工具
631
+ pip install build twine
632
+ ```
633
+
634
+ | 工具 | 用途 |
635
+ |------|------|
636
+ | `build` | 打包生成 `.whl` + `.tar.gz` |
637
+ | `twine` | 上传到 PyPI |
638
+
639
+ ### 本地打包
640
+
641
+ ```bash
642
+ # 清理旧的构建文件
643
+ rm -rf dist/ build/ *.egg-info
644
+
645
+ # 执行打包
646
+ python -m build
647
+
648
+ # 检查生成的包
649
+ ls -la dist/
650
+ # dist/
651
+ # ├── xqshare-1.0.0-py3-none-any.whl
652
+ # └── xqshare-1.0.0.tar.gz
653
+
654
+ # 验证包格式
655
+ twine check dist/*
656
+ ```
657
+
658
+ ### 发布到 PyPI
659
+
660
+ **前置条件:**
661
+ 1. 注册 [PyPI 账号](https://pypi.org/account/register/)
662
+ 2. 创建 API Token:Account settings → API tokens → Add API token
663
+ 3. 保存 Token(格式:`pypi-xxxxxx...`,只显示一次!)
664
+
665
+ **执行发布:**
666
+
667
+ ```bash
668
+ twine upload dist/*
669
+ ```
670
+
671
+ **输入:**
672
+ - Username: `__token__`(字面意思,就是输入这个字符串)
673
+ - Password: 粘贴你的 API Token
674
+
675
+ ### 测试发布(可选)
676
+
677
+ 先在 [TestPyPI](https://test.pypi.org/) 测试:
678
+
679
+ ```bash
680
+ # 发布到 TestPyPI
681
+ twine upload --repository testpypi dist/*
682
+
683
+ # 从 TestPyPI 安装测试
684
+ pip install --index-url https://test.pypi.org/simple/ xqshare
685
+ ```
686
+
687
+ ### 发布后验证
688
+
689
+ ```bash
690
+ # 从 PyPI 安装
691
+ pip install xqshare
692
+
693
+ # 验证安装
694
+ python -c "from xqshare import XtQuantRemote; print('OK')"
695
+ ```
696
+
697
+ ---
698
+
699
+ ## 注意事项
700
+
701
+ 1. **网络延迟**:远程调用有网络延迟,高频场景建议批量获取
702
+ 2. **数据序列化**:复杂对象通过 pickle 序列化,确保两端 Python 版本兼容
703
+ 3. **安全性**:生产环境建议启用 SSL + 强密码认证
704
+ 4. **防火墙**:确保服务端端口(默认 18812)可访问
705
+ 5. **日志清理**:定期清理日志文件,避免磁盘占用过大
706
+
707
+ ---
708
+
709
+ ## 故障排查
710
+
711
+ ### 查看日志
712
+
713
+ ```bash
714
+ # 服务端
715
+ tail -f logs/api_calls_*.log
716
+
717
+ # 客户端
718
+ tail -f logs/client_*.log
719
+ ```
720
+
721
+ ### 连接失败
722
+
723
+ ```bash
724
+ # 检查网络
725
+ ping 192.168.1.100
726
+ telnet 192.168.1.100 18812
727
+ ```
728
+
729
+ ### 查看服务状态
730
+
731
+ ```python
732
+ # 客户端查询服务端状态
733
+ status = xt.get_service_status()
734
+ print(status)
735
+ # {'uptime': 3600, 'active_tokens': 2, 'active_callbacks': 5}
736
+ ```
737
+
738
+ ---
739
+
740
+ ## 更新历史
741
+
742
+ | 版本 | 日期 | 更新内容 |
743
+ |------|------|----------|
744
+ | 1.1.1 | 2026-03-18 | 新增 xtview 模块支持(视图控制、调度任务管理),兼容不同 xtquant 版本 |
745
+ | 1.1.0 | 2026-03-17 | 交易功能优化完善、`xqshare-server` 命令、`.env` 配置支持、远程对象传输性能优化 |
746
+ | 1.0.4 | 2026-03-09 | JSON 输出优化:远程 DataFrame 高效序列化、`--compact` 参数、全局参数位置灵活、嵌套结构支持 |
747
+ | 1.0.3 | 2026-03-09 | 统一环境变量命名:XQSHARE_ 前缀,QMT 客户端配置使用 QMT_ 前缀 |
748
+ | 1.0.2 | 2026-03-09 | 精简快速启动章节 |
749
+ | 1.0.1 | 2026-02-28 | 支持配置文件热更新、多级账号权限控制 |
750
+ | 1.0.0 | 2026-02-20 | 首次发布 |
751
+
752
+ ---
753
+
754
+ ## License
755
+
756
+ GNU General Public License v3.0