carrotquant-data 1.2.1__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 (45) hide show
  1. carrotquant_data-1.2.1.dist-info/METADATA +327 -0
  2. carrotquant_data-1.2.1.dist-info/RECORD +45 -0
  3. carrotquant_data-1.2.1.dist-info/WHEEL +4 -0
  4. carrotquant_data-1.2.1.dist-info/entry_points.txt +2 -0
  5. cqdata/__init__.py +56 -0
  6. cqdata/config/__init__.py +3 -0
  7. cqdata/config/settings.py +106 -0
  8. cqdata/entrypoints/__init__.py +39 -0
  9. cqdata/entrypoints/accessors/__init__.py +38 -0
  10. cqdata/entrypoints/accessors/aindex.py +60 -0
  11. cqdata/entrypoints/accessors/ashare.py +162 -0
  12. cqdata/entrypoints/accessors/base.py +134 -0
  13. cqdata/entrypoints/cli.py +185 -0
  14. cqdata/entrypoints/python_api.py +159 -0
  15. cqdata/entrypoints/rest_api.py +745 -0
  16. cqdata/provider/__init__.py +0 -0
  17. cqdata/provider/baostock_provider.py +395 -0
  18. cqdata/provider/base.py +71 -0
  19. cqdata/provider/data_cleaner.py +105 -0
  20. cqdata/provider/eastmoney_provider.py +713 -0
  21. cqdata/provider/em_utils.py +154 -0
  22. cqdata/provider/provider_manager.py +43 -0
  23. cqdata/provider/tdx_provider.py +235 -0
  24. cqdata/provider/tdx_utils.py +478 -0
  25. cqdata/service/__init__.py +1 -0
  26. cqdata/service/data_reader.py +308 -0
  27. cqdata/service/metadata_manager.py +51 -0
  28. cqdata/service/metadata_reader.py +263 -0
  29. cqdata/service/sync_manager.py +303 -0
  30. cqdata/service/sync_tracker.py +128 -0
  31. cqdata/service/task_planner.py +108 -0
  32. cqdata/static/assets/index-BDBCqr4Y.js +19 -0
  33. cqdata/static/assets/index-Cpa46ehI.css +2 -0
  34. cqdata/static/favicon.svg +1 -0
  35. cqdata/static/icons.svg +24 -0
  36. cqdata/static/index.html +14 -0
  37. cqdata/storage/__init__.py +0 -0
  38. cqdata/storage/base.py +104 -0
  39. cqdata/storage/csv_storage.py +281 -0
  40. cqdata/storage/data_merger.py +68 -0
  41. cqdata/storage/parquet_storage.py +286 -0
  42. cqdata/storage/storage_factory.py +27 -0
  43. cqdata/utils/__init__.py +1 -0
  44. cqdata/utils/logger_utils.py +166 -0
  45. cqdata/utils/time_utils.py +99 -0
@@ -0,0 +1,327 @@
1
+ Metadata-Version: 2.5
2
+ Name: carrotquant-data
3
+ Version: 1.2.1
4
+ Summary: 高性能、轻量级 A 股与指数金融数据增量同步与持久化流水线
5
+ Author-email: Carrot <11172391+CRThu@users.noreply.github.com>
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: baostock>=0.9.1
8
+ Requires-Dist: curl-cffi>=0.7.4
9
+ Requires-Dist: fastapi>=0.135.1
10
+ Requires-Dist: loguru>=0.7.3
11
+ Requires-Dist: polars>=1.39.0
12
+ Requires-Dist: pydantic>=2.12.5
13
+ Requires-Dist: pyyaml>=6.0.3
14
+ Requires-Dist: tdxpy>=0.2.7
15
+ Requires-Dist: tenacity>=9.1.4
16
+ Requires-Dist: typer>=0.24.1
17
+ Requires-Dist: uvicorn>=0.41.0
18
+ Description-Content-Type: text/markdown
19
+
20
+ # CarrotQuant.Data
21
+
22
+ ![Python Version](https://img.shields.io/badge/python-%3E%3D3.12-blue)
23
+ ![License](https://img.shields.io/badge/license-Apache%202.0-blue)
24
+
25
+ CarrotQuant.Data 是一个为量化交易体系设计的轻量级、模块化的本地数据同步与管理工具。它致力于从各类免费数据源(如 Baostock、东方财富等)获取金融数据,并将数据清洗、转换为统一格式(支持 CSV, Parquet 等),持久化到本地存储中以供各类量化研究和回测使用。
26
+
27
+ ## 🌟 核心特性 (Features)
28
+
29
+ - **多数据源支持**:内置 [Baostock](http://baostock.com/)、东方财富、[通达信 (tdxpy)](https://github.com/rainx/tdxPy) 等金融数据源引擎,易于弹性拓展更多的数据源提供商。
30
+ - **灵活的存储格式**:原生支持 `csv` 和基于列式存储的高效 `parquet` 格式,以满足不同体量的数据读写需求。
31
+ - **增量与全量同步**:基于时间戳水位线的同步机制,支持从断点智能续接(增量拉取),以及强制全量覆盖更新刷新数据。
32
+ - **现代化多通道接入支持**:
33
+ - **React Web 终端**:现代暗黑极速金融终端 (`web/`),基于 Bun + Vite 6 + React 19 + TradingView Lightweight Charts (3-Pane 单屏无滚动图表) + 拼音/代码/名称通用搜索组件 `SearchInput` + **独立 `数据矩阵` 视图 + 数据中心与 Loguru SSE 日志流视窗与悬浮 Widget**。
34
+ - **Python SDK**:简单直观的 `import cqdata` API,支持高性能跨年份数据切片读取 (`cqdata.read`)、`columns` 按需字段选择、格式识别与元数据探查。
35
+ - **命令行工具 (CLI)**:统一的 `cqdata` 命令行工具,提供数据同步 (`cqdata sync`)、数据表探索 (`cqdata tables`)、元数据查询 (`cqdata info`) 与 HTTP 服务启动 (`cqdata server`)。
36
+ - **REST API 服务**:基于 FastAPI 的 REST API,为远程微服务与 Web 终端提供 HTTP 数据切片、SSE 实时日志流与同步触发。
37
+ - **优秀的底层性能**:使用 [Polars](https://pola.rs/) 库进行高性能的数据加工和清洗。
38
+
39
+ ## 📁 目录结构 (Project Structure)
40
+
41
+ ```text
42
+ CarrotQuant.Data/
43
+ ├── cqdata/ # 核心代码包 (支持 import cqdata)
44
+ │ ├── entrypoints/ # 接入层 (python_api, cli, rest_api)
45
+ │ ├── config/ # 配置管理模块
46
+ │ ├── provider/ # 数据源驱动 (BaostockProvider, EastMoneyProvider, TDXProvider)
47
+ │ ├── service/ # 核心业务逻辑 (DataReader, MetadataReader, SyncManager 等)
48
+ │ ├── storage/ # 本地持久化存储 (CSVStorage, ParquetStorage)
49
+ │ └── utils/ # 通用工具箱
50
+ ├── web/ # React Web 金融终端 (Bun + Vite 6 + React 19 + TradingView 3-Pane)
51
+ │ ├── src/ # 视图 View、组件 Component、Hooks 与转换服务
52
+ │ └── package.json
53
+ ├── scripts/
54
+ │ ├── wizard.py # 交互向导脚本 (也可通过 cqdata wizard 运行)
55
+ │ └── download_tdx.py # 通达信数据下载脚本
56
+ ├── tests/ # 单元测试与集成测试
57
+ ├── config/ # 项目配置文件存放目录
58
+ ├── logs/ # 系统运行日志目录
59
+ ├── AGENTS.md # AI Agent 架构指南
60
+ └── pyproject.toml # 项目构建及依赖配置
61
+ ```
62
+
63
+ ## 🏗️ 系统架构
64
+
65
+ ```mermaid
66
+ graph TB
67
+ subgraph Entrypoints["接入层 (cqdata/entrypoints)"]
68
+ PYTHON_API["python_api.py<br/>(Python SDK)"]
69
+ CLI["cli.py<br/>(Typer CLI)"]
70
+ REST["rest_api.py<br/>(FastAPI REST)"]
71
+ WIZARD["wizard.py<br/>(交互向导)"]
72
+ end
73
+
74
+ subgraph Service["业务逻辑层 (cqdata/service)"]
75
+ SM["SyncManager<br/>同步总调度"]
76
+ DR["DataReader<br/>切片与按列投影"]
77
+ MR["MetadataReader<br/>探查与过滤 API"]
78
+ TASK_PLANNER["TaskPlanner<br/>任务规划器"]
79
+ MM["MetadataManager<br/>元数据 IO"]
80
+ end
81
+
82
+ subgraph Provider["采集层 (cqdata/provider)"]
83
+ PM["ProviderManager"]
84
+ BP["BaostockProvider"]
85
+ EP["EastMoneyProvider"]
86
+ TDX_PROV["TDXProvider"]
87
+ end
88
+
89
+ subgraph Storage["存储层 (cqdata/storage)"]
90
+ SF["StorageFactory"]
91
+ CSV["CSVStorage"]
92
+ PQ["ParquetStorage"]
93
+ end
94
+
95
+ PYTHON_API --> DR
96
+ PYTHON_API --> MR
97
+ PYTHON_API --> SM
98
+ CLI --> SM
99
+ CLI --> MR
100
+ REST --> DR
101
+ REST --> MR
102
+ REST --> SM
103
+ WIZARD --> SM
104
+
105
+ SM --> TASK_PLANNER
106
+ SM --> PM
107
+ SM --> SF
108
+ TASK_PLANNER --> MM
109
+ SM --> MM
110
+ PM --> BP
111
+ PM --> EP
112
+ PM --> TDX_PROV
113
+ SF --> CSV
114
+ SF --> PQ
115
+ ```
116
+
117
+ ## 📊 支持的数据表 (Supported Tables)
118
+
119
+ | Table ID | 类型 | 说明 |
120
+ |----------|------|------|
121
+ | `ashare.kline.1d.adj.baostock` | TS | A 股日线后复权 |
122
+ | `ashare.kline.1d.raw.baostock` | TS | A 股日线不复权 |
123
+ | `ashare.kline.5m.adj.baostock` | TS | A 股 5 分钟线后复权 |
124
+ | `ashare.kline.5m.raw.baostock` | TS | A 股 5 分钟线不复权 |
125
+ | `aindex.kline.1d.raw.baostock` | TS | A 股指数日线 |
126
+ | `ashare.adj_factor.baostock` | EV | A 股复权因子 |
127
+ | `ashare.concept.eastmoney` | EV | 概念板块成分股 |
128
+ | `ashare.industry.eastmoney` | EV | 行业板块成分股 |
129
+ | `ashare.dragon_tiger.eastmoney` | EV | 龙虎榜 |
130
+ | `ashare.inst_trade.eastmoney` | EV | 机构买卖每日统计 |
131
+ | `ashare.kline.1d.raw.tdx` | TS | A 股日线 (通达信) |
132
+ | `ashare.kline.5m.raw.tdx` | TS | A 股 5 分钟线 (通达信) |
133
+ | `ashare.kline.1m.raw.tdx` | TS | A 股 1 分钟线 (通达信) |
134
+ | `aindex.kline.1d.raw.tdx` | TS | 指数日线 (通达信) |
135
+ | `aindex.kline.5m.raw.tdx` | TS | 指数 5 分钟线 (通达信) |
136
+ | `aindex.kline.1m.raw.tdx` | TS | 指数 1 分钟线 (通达信) |
137
+
138
+ ## 🛠️ 安装指南 (Installation)
139
+
140
+ 环境要求:**Python >= 3.12**。本项目推荐使用现代化的 Python 包管理器 [uv](https://github.com/astral-sh/uv) 进行极速安装与管理。
141
+
142
+ 1. **克隆项目并安装**
143
+ ```bash
144
+ git clone https://github.com/CRThu/CarrotQuant.Data.git
145
+ cd CarrotQuant.Data
146
+
147
+ # 可选:可编辑模式挂载命令行 cqdata
148
+ uv pip install -e .
149
+ ```
150
+
151
+ ## ⚙️ 配置说明 (Configuration)
152
+
153
+ CarrotQuant.Data 秉承 **“显式胜于隐式 (Explicit is better than implicit)”** 的配置契约,支持以下显式加载与覆盖方式(优先级从高到低):
154
+
155
+ 1. **代码程序化修改**:直接设置单例属性 `cqdata.settings.data_dir = "/path/to/data"` 或调用 `cqdata.configure("/path/to/config.yaml")`(最高优先级)。
156
+ 2. **环境变量 `CQDATA_DATA_DIR`**:如 `export CQDATA_DATA_DIR="/my/data/path"`(适合 Docker / CLI / 自动化部署)。
157
+ 3. **环境变量 `CQDATA_CONFIG_PATH`**:指定自定义 YAML 配置文件路径,如 `export CQDATA_CONFIG_PATH="/path/to/config.yaml"`。
158
+ 4. **内置默认配置**:默认存储路径 `data_dir = "data"`,默认日志 `log_dir = "logs"`, `log_level = "INFO"`。
159
+
160
+ 完整配置文件结构参考 [config.yaml.sample](file:///d:/Quant/CarrotQuant.Data/config/config.yaml.sample):
161
+
162
+ ```yaml
163
+ # config.yaml
164
+ data_dir: "data" # 数据存储根目录
165
+ log_dir: "logs" # 日志输出目录
166
+ log_level: "INFO" # 日志级别 (DEBUG/INFO/WARNING/ERROR)
167
+
168
+ # OOP 访问层全局默认配置链
169
+ defaults:
170
+ source: "baostock"
171
+ format: "parquet"
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 🚀 快速开始 (Quick Start)
177
+
178
+ ### 方式一:使用 Python SDK (`import cqdata`) - 推荐
179
+
180
+ 在量化研究与 Python 策略脚本中直接读取本地清洗好的数据:
181
+
182
+ ```python
183
+ import cqdata
184
+
185
+ # 0. (可选) 从 YAML 配置文件加载全局配置
186
+ cqdata.configure("./config.yaml")
187
+
188
+ # 或者直接修改属性
189
+ cqdata.settings.data_dir = "./custom_data"
190
+
191
+ # 1. OOP 便捷读取 (界面极简,干净清爽)
192
+ df_kline = cqdata.ashare.kline.get(symbols="sh.600000", start_date="2024-01-01")
193
+
194
+ # 2. 查阅代码清单、时间跨度、Schema 映射与物理总行数
195
+ symbols = cqdata.list_symbols("ashare.kline.1d.raw.baostock")
196
+ start_dt, end_dt = cqdata.get_time_range("ashare.kline.1d.raw.baostock")
197
+ schema = cqdata.get_schema("ashare.kline.1d.raw.baostock") # {'timestamp': 'Int64', ...}
198
+ total_rows = cqdata.get_row_count("ashare.kline.1d.raw.baostock") # 13570685
199
+
200
+ # 3. 统一切片读取 K 线时序数据 (支持 columns 按需挑选列,极节省内存)
201
+ df = cqdata.read(
202
+ table_id="ashare.kline.1d.raw.baostock",
203
+ symbols=["sh.600000", "sz.000001"],
204
+ start_date="2024-01-01",
205
+ end_date="2024-06-30",
206
+ columns=["timestamp", "datetime", "symbol", "close", "volume"]
207
+ )
208
+ print(df)
209
+
210
+ # 4. 统一切片读取板块/龙虎榜事件数据
211
+ events_df = cqdata.read(
212
+ table_id="ashare.concept.eastmoney",
213
+ symbols=["sh.600000"]
214
+ )
215
+
216
+ # 5. 代码中触发全自动数据同步
217
+ cqdata.sync(table_ids=["ashare.kline.1d.raw.baostock"], formats=["parquet"])
218
+ ```
219
+
220
+ ### 方式二:使用统一 CLI 命令行工具 (`cqdata`)
221
+
222
+ 可在终端或 Cron 定时任务中直接调用 `cqdata` 交互:
223
+
224
+ ```bash
225
+ # 查看本地存储的所有数据表概览
226
+ cqdata tables
227
+
228
+ # 查看某张表的物理行数、代码列表与 Schema 详细元数据
229
+ cqdata info ashare.kline.1d.raw.baostock
230
+
231
+ # 触发自动增量同步
232
+ cqdata sync --tables "ashare.kline.1d.raw.baostock,ashare.adj_factor.baostock"
233
+
234
+ # 指定日期区间与保存格式进行全量强制更新
235
+ cqdata sync -t ashare.kline.1d.raw.baostock -f parquet -s 2023-01-01 -e 2023-12-31 --force
236
+ ```
237
+
238
+ #### 💡 通达信 (TDX) 最佳同步实践说明
239
+
240
+ 通达信驱动支持 **Local (离线 vipdoc 导包)** 与 **Online (在线 TCP 协议)** 两种模式。两者的输出格式和字段完全对齐,落地在同一个 `table_id` 下,数据会自动无缝去重与合并。
241
+
242
+ - **Local 离线模式读取能力**:原生支持解析本地 `vipdoc` 目录下的 **日线 (`.day`)、5分钟线 (`.lc5`) 以及 1分钟线 (`.lc1`)** 等所有离线二进制文件(包含通达信软件自行下载导出的分钟线文件)。
243
+ - **极速初始化脚本 (`cqdata tdx download`)**:用于一键拉取并解压通达信官方服务器的全量日线行情包(`hsjday.zip`),实现数十年日线历史数据的秒级导入。
244
+
245
+ > [!TIP]
246
+ > **强烈推荐的最佳实践流程**:
247
+ > 1. **首次极速初始化(Local 模式)**:通过 `cqdata tdx download` 下载官方 `vipdoc` 日线离线包(或直接挂载本地已有的通达信客户端 `vipdoc` 目录)解析导入,秒级完成历史数据装载。
248
+ > 2. **日常增量更新(Online 模式)**:日常收盘后直接执行在线增量同步,系统会自动根据水位线补全最新几日的增量 K 线(支持 1d / 5m / 1m)。
249
+
250
+ ```bash
251
+ # 步骤 1: 极速初始化 - 下载并解压通达信官方全量日线行情包 (hsjday.zip)
252
+ cqdata tdx download
253
+ # 或使用 uv 直接运行下载脚本 (也可通过 --tdx-vipdoc 指定本地已有通达信客户端目录)
254
+ uv run scripts/download_tdx.py
255
+
256
+ # 步骤 2: 日常盘后增量 - 触发通达信在线按水位线追加最新数据 (支持 1d 日线 / 5m / 1m 分钟线)
257
+ cqdata sync -t ashare.kline.1d.raw.tdx
258
+ ```
259
+
260
+ **命令行关键参数:**
261
+ - `-t` / `--tables`: 必填,要同步的表 ID,多表用逗号分隔。
262
+ - `-f` / `--formats`: 选填,保存格式(默认 `parquet,csv`)。
263
+ - `-s` / `--start` & `-e` / `--end`: 选填,时间范围,留空则是自动接续水位线增量同步。
264
+ - `--force`: 选填,强制全量刷新覆盖。
265
+ - `--limit`: 选填,限制同步代码数量(调试用)。
266
+
267
+ ### 方式三:使用终端交互向导 (Wizard)
268
+
269
+ ```bash
270
+ cqdata wizard
271
+ ```
272
+
273
+ ### 方式四:一键启动服务器与 Web 终端 (支持 --open / -o 自动打开浏览器)
274
+ ```bash
275
+ # 启动后端 API 服务并自动调起系统浏览器打开 Web 终端
276
+ cqdata server --port 8888 --open
277
+
278
+ # (也可使用 -c 指定配置文件: cqdata server -p 8888 -c ./config.yaml -o)
279
+ ```
280
+
281
+ 启动后内置托管 React Web 终端并提供基于 FastAPI 的 RESTful HTTP 接口(全量端点汇总):
282
+
283
+ | 端点 | 方法 | 说明 |
284
+ |------|------|------|
285
+ | `/` | GET | 内置托管的 React Web 金融终端主界面 |
286
+ | `/api/v1/health` | GET | 系统健康检查与服务运行状态探针 |
287
+ | `/api/v1/tables` | GET | 列出本地所有数据表总览 (平铺列表,含 `category` 属性) |
288
+ | `/api/v1/tables/{table_id}/formats` | GET | 获取指定表已存储的物理格式列表 (`['parquet', 'csv']`) |
289
+ | `/api/v1/tables/{table_id}/symbols` | GET | 获取指定表已下载的股票/证券代码列表 |
290
+ | `/api/v1/tables/{table_id}/time_range` | GET | 获取指定表的时间跨度 tuple `(start_datetime, end_datetime)` |
291
+ | `/api/v1/tables/{table_id}/schema` | GET | 获取指定表的字段列名与类型字典 |
292
+ | `/api/v1/tables/{table_id}/row_count` | GET | 获取指定表的记录总条数/行数 |
293
+ | `/api/v1/query` | GET | 统一切片查询接口(支持 `symbols`, `start_date`, `end_date`, `columns`, `page`, `page_size`),按 `table_id` 自动智能路由,输出 `columns` 表头与 `data` 二维 List 矩阵 |
294
+ | `/api/v1/sync` | POST | 异步触发后台数据同步任务 |
295
+ | `/api/v1/tasks` | GET | 查询活跃同步任务状态 |
296
+ | `/api/v1/filesystem/list` | GET | 通用本地文件与目录探查接口 (为 Web 文件探查器 Modal 提供支持) |
297
+
298
+ ### 方式五:前端 UI 开发与热重载调试 (`web/`)
299
+
300
+ 进行前端界面开发或组件调试时,可启动 Vite 热重载服务:
301
+
302
+ ```bash
303
+ # 1. 启动后端 REST API 服务
304
+ cqdata server --port 8888
305
+
306
+
307
+ # 2. 在另一个终端启动 Vite 开发调试服务 (支持 HMR 热更新)
308
+ cd web
309
+ bun install
310
+ bun dev
311
+ ```
312
+
313
+ 打开浏览器访问 `http://localhost:5173/` 体验 Vite HMR 极速实时编译调试。
314
+ 详细使用指南与架构说明请参阅 [docs/web_terminal_guide.md](docs/web_terminal_guide.md)。
315
+
316
+
317
+ ## 📚 相关文档 (Documentation)
318
+
319
+ - [Python SDK 使用指南](docs/python_sdk_guide.md)
320
+ - [REST API 接口文档](docs/rest_api_guide.md)
321
+ - [React Web 终端指南](docs/web_terminal_guide.md)
322
+ - [示例代码与脚本](examples/README.md)
323
+
324
+ ## 📝 许可证 (License)
325
+
326
+ 本项目遵循 [Apache License 2.0](LICENSE) - 详细请参阅 LICENSE 文件。
327
+
@@ -0,0 +1,45 @@
1
+ cqdata/__init__.py,sha256=WEjU3GmLtD4rUjTrMPDET6vYv-eshtzdiHY3bdXWggk,1460
2
+ cqdata/config/__init__.py,sha256=p17OON5m7vL4cKdddcVhcURIgG2Nx2LLs8r_sZNWFeA,55
3
+ cqdata/config/settings.py,sha256=W6NIe-u_4BaEmC0AcYY632W7EcfcWBlI6oOql_UZFi8,3432
4
+ cqdata/entrypoints/__init__.py,sha256=1bBQQUmKy981Tu8tcsgH5u-UuHe-LFZ5FZmvPw50bkk,586
5
+ cqdata/entrypoints/cli.py,sha256=37MkCWzwic7_jMne0Ng7d5znt8YdX4WTjp5tD4Z2t1k,6986
6
+ cqdata/entrypoints/python_api.py,sha256=re-exu10eiyIKznqa0X_TGDUcXqIMa5ZQtnWGUGOi8A,5519
7
+ cqdata/entrypoints/rest_api.py,sha256=Blqjqd6cA6OnMIYu9Vq3ZGaNDXbQGiQ4Q2ft-CkJCE8,26519
8
+ cqdata/entrypoints/accessors/__init__.py,sha256=KfrgaWyHllJyRAMlAEhGnLOFkqGX3AgUJz5DRpmqaMk,839
9
+ cqdata/entrypoints/accessors/aindex.py,sha256=kjAlt-c4MeUsx0GHE4fiMRIKAXVdC3FLiZpTYtbudEQ,1932
10
+ cqdata/entrypoints/accessors/ashare.py,sha256=iYvlRIjxc_1EeQKxMiTZAKWRJz6U7-SisppxhPC79T0,5888
11
+ cqdata/entrypoints/accessors/base.py,sha256=i5R5O_UWbjZ_WVSCUFCnnm3sxlFh6dJvoZ1yqJ53NQU,4441
12
+ cqdata/provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ cqdata/provider/baostock_provider.py,sha256=fQBfmfcG4kVzR7kl4hz3s8lBDN45lWwPF4Y70d47-Mw,16752
14
+ cqdata/provider/base.py,sha256=-myhZXCP_8Bw2QyHpbESEhA4uNb9hri6mOQFlMGZIF4,2145
15
+ cqdata/provider/data_cleaner.py,sha256=uOefzYB1wEgAI1aZZFX_FTh_xct7whtU8KTeMGv2pnc,4647
16
+ cqdata/provider/eastmoney_provider.py,sha256=NsHgD7ZYOl66Z5JxwDc6ikQp2HbH1q5fljEIZvbV8Xo,30817
17
+ cqdata/provider/em_utils.py,sha256=Qi4GDuDGDLDLRJ_mUIY4w38tI3Lp-Ck9Dt9hhFdHXZQ,5294
18
+ cqdata/provider/provider_manager.py,sha256=fhBCv7zpj6s8mjR_EfkziowzQBVaUbsZr4IXW3qW_pM,1512
19
+ cqdata/provider/tdx_provider.py,sha256=RwyBbmS3WL_pfShiJyFUAIVHo9XaDB642F88LLCLb60,10345
20
+ cqdata/provider/tdx_utils.py,sha256=WXGSLvjbv4N7btQEXmM9xk7IuvRr0QEDoh-X1sYjTuo,16070
21
+ cqdata/service/__init__.py,sha256=Ty-Rju8PMatz5Ty1HEDe-XWB-8lWzJbN6J7lPdMK5Ko,22
22
+ cqdata/service/data_reader.py,sha256=HU0h3dSKyaPedSY1NLDxwKqzd8XxBXp0OFkI28az7Xw,11258
23
+ cqdata/service/metadata_manager.py,sha256=telEfWgdqfdrlqujRoa41qbJ3x7sKWminEeDZXGThkI,1913
24
+ cqdata/service/metadata_reader.py,sha256=GLTt7Bt7RzSOFWzN4_dtIOo3CymPx1FxOiy_8b3hFqU,10114
25
+ cqdata/service/sync_manager.py,sha256=lx3Y8c1msdhet6roud1xY5_dTx-qvkj-fmJyFUDhF7s,14249
26
+ cqdata/service/sync_tracker.py,sha256=fclIyCGOgoBDSR7XEl3VcJmxEcmGnDqzrHmObQb2j2Y,4787
27
+ cqdata/service/task_planner.py,sha256=mP0ci8JXBDhIn6Gc2M_ZYFExG9zWr7eKbbNkOhH_U7I,4343
28
+ cqdata/static/favicon.svg,sha256=YbyaFh3lgkgojmkFQl1xgPBiTChlAHuX12P9rBIEOmY,9522
29
+ cqdata/static/icons.svg,sha256=tF-lBhlc_N70BrqfDHezbdwafCJAQJJuxwq8L96nuTo,5031
30
+ cqdata/static/index.html,sha256=H6K5eU5FVri-wAecR8K9FKqinh2ldD1OfNLyBN1rhzA,453
31
+ cqdata/static/assets/index-BDBCqr4Y.js,sha256=vcbK96Wwgq-vu6lg5CnZ3iQi8CPCY61tjycC4Qkm2wQ,524158
32
+ cqdata/static/assets/index-Cpa46ehI.css,sha256=J4a2JywT2KSMzWx-YhrqtiDjKgFDJwsZ-5njrW3q3ZY,56047
33
+ cqdata/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ cqdata/storage/base.py,sha256=3GGUwXYrkpjmf6HDnsdFh9z8et0h8ajY2ko4oqL4Pj0,3023
35
+ cqdata/storage/csv_storage.py,sha256=ga7cCsQWWnODtZfyMyiSPjjklN-IavZy3kiAGXKCSqI,12382
36
+ cqdata/storage/data_merger.py,sha256=FhIBhTB5Hjlxe_4IPg3cC81HYvcfi9SEWG-f7lfhQo0,2071
37
+ cqdata/storage/parquet_storage.py,sha256=03P3wZg3CgVLQ2gjxo7_Alo0y1t0kXwUSdEZjLYW1ko,12340
38
+ cqdata/storage/storage_factory.py,sha256=GhSYGHNORQ4BhA8ko7XQH9Jrt-G3-Kc43c-5QQqmg_0,1038
39
+ cqdata/utils/__init__.py,sha256=2lIhukCPD_bkmyf_qrU4_LNcJbmh8PHWzEmO0oEiXg4,20
40
+ cqdata/utils/logger_utils.py,sha256=o9ByqRluLYRPfJsXLU5iQJe8q6soc6PhQ-uABFJf6q0,5414
41
+ cqdata/utils/time_utils.py,sha256=D9jNFNthniMHXcxUkA6GhaKGMSGRhM8OP8IMp8rMiRA,3520
42
+ carrotquant_data-1.2.1.dist-info/METADATA,sha256=Q5HEygIIWn8QU1t4eeg2-NPdMMFrwgNXJz0pO3KM3N0,14737
43
+ carrotquant_data-1.2.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
44
+ carrotquant_data-1.2.1.dist-info/entry_points.txt,sha256=ClCSWUAIDIjLN6LZTxcPZ3z2U_Uze4WwwCkC2_4mWuc,54
45
+ carrotquant_data-1.2.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cqdata = cqdata.entrypoints.cli:app
cqdata/__init__.py ADDED
@@ -0,0 +1,56 @@
1
+ """
2
+ CarrotQuant.Data (cqdata)
3
+
4
+ 轻量级、模块化的本地金融数据同步与管理工具。
5
+
6
+ 对外暴露的统一 Python SDK API:
7
+ - read: 统一切片读取 K 线/分笔/板块/龙虎榜等金融数据 (自动按分类智能路由)
8
+ - ashare / aindex: OOP 极简便捷数据访问命名空间 (如 cqdata.ashare.kline.get())
9
+ - default: 链式默认值配置 (cqdata.default.source = "tdx")
10
+ - configure: 全局配置函数 (支持配置文件与参数混合设置)
11
+ - settings: 全局 Settings 实例
12
+ - list_tables: 列出本地已有的全量数据表清单 (含 category 属性)
13
+ - list_formats: 查看某表已有的存储格式
14
+ - list_symbols: 查看某表已有的股票/指数代码列表
15
+ - get_time_range: 获取某表的时间起止跨度
16
+ - get_schema: 获取某表的字段列定义与类型
17
+ - get_row_count: 获取某表物理存储记录条数
18
+ - sync: 触发数据全自动同步
19
+ """
20
+
21
+ from cqdata.entrypoints import (
22
+ read,
23
+ list_tables,
24
+ list_formats,
25
+ list_symbols,
26
+ get_time_range,
27
+ get_schema,
28
+ get_row_count,
29
+ list_boards,
30
+ sync,
31
+ configure,
32
+ default,
33
+ ashare,
34
+ aindex
35
+ )
36
+ from cqdata.config import settings
37
+
38
+ __version__ = "1.2.1"
39
+
40
+ __all__ = [
41
+ "read",
42
+ "list_tables",
43
+ "list_formats",
44
+ "list_symbols",
45
+ "get_time_range",
46
+ "get_schema",
47
+ "get_row_count",
48
+ "list_boards",
49
+ "sync",
50
+ "configure",
51
+ "default",
52
+ "ashare",
53
+ "aindex",
54
+ "settings",
55
+ "__version__"
56
+ ]
@@ -0,0 +1,3 @@
1
+ from .settings import settings
2
+
3
+ __all__ = ["settings"]
@@ -0,0 +1,106 @@
1
+ """
2
+ cqdata/config/settings.py
3
+
4
+ 全局配置管理模块。
5
+ 纯 Python 实现轻量 Settings,支持显式配置加载与程序化动态修改:
6
+ 1. 环境变量 CQDATA_CONFIG_PATH / CQDATA_DATA_DIR (显式指定)
7
+ 2. 显式 configure(config_path) 加载 YAML 配置文件
8
+ 3. 显式修改 cqdata.settings 属性
9
+ """
10
+
11
+ import os
12
+ from pathlib import Path
13
+ from typing import Optional, Union, Dict, Any
14
+ import yaml
15
+
16
+
17
+ class Settings:
18
+ """
19
+ 全局 Settings 类 (纯 Python 实现,无 pydantic-settings 依赖)
20
+ """
21
+
22
+ def __init__(self):
23
+ # 核心配置字段默认值
24
+ self.data_dir: str = "data"
25
+ self.log_dir: str = "logs"
26
+ self.log_level: str = "INFO"
27
+ self.defaults: Dict[str, Any] = {}
28
+
29
+ # 初始化时自动加载配置
30
+ self._load_initial_config()
31
+
32
+ def _load_initial_config(self) -> None:
33
+ """
34
+ 按优先级规则初始化加载配置:
35
+ 1. 内置默认值
36
+ 2. 环境变量 CQDATA_CONFIG_PATH 显式指定配置文件
37
+ 3. 环境变量 CQDATA_DATA_DIR 显式覆盖 data_dir
38
+ """
39
+ # 1. 环境变量 CQDATA_CONFIG_PATH 显式指定 YAML 配置文件
40
+ config_path_env = os.getenv("CQDATA_CONFIG_PATH")
41
+ if config_path_env:
42
+ path = Path(config_path_env)
43
+ if path.exists():
44
+ self.load_from_file(path)
45
+
46
+ # 2. 环境变量 CQDATA_DATA_DIR 显式覆盖 data_dir
47
+ if os.getenv("CQDATA_DATA_DIR"):
48
+ self.data_dir = os.getenv("CQDATA_DATA_DIR")
49
+
50
+ def load_from_file(self, config_path: Union[str, Path]) -> "Settings":
51
+ """
52
+ 显式从指定 YAML 配置文件加载配置
53
+ """
54
+ path = Path(config_path)
55
+ if not path.exists():
56
+ raise FileNotFoundError(f"Config file not found: {config_path}")
57
+
58
+ with open(path, "r", encoding="utf-8") as f:
59
+ config_data = yaml.safe_load(f)
60
+
61
+ if isinstance(config_data, dict):
62
+ if "data_dir" in config_data:
63
+ self.data_dir = str(config_data["data_dir"])
64
+
65
+ if "log_dir" in config_data:
66
+ self.log_dir = str(config_data["log_dir"])
67
+
68
+ if "log_level" in config_data:
69
+ self.log_level = str(config_data["log_level"]).upper()
70
+
71
+ if "defaults" in config_data and isinstance(config_data["defaults"], dict):
72
+ self.defaults = config_data["defaults"]
73
+ self._update_accessor_defaults()
74
+
75
+ return self
76
+
77
+ def configure(self, config_path: Union[str, Path]) -> "Settings":
78
+ """
79
+ 从指定 YAML 配置文件加载全局参数。
80
+
81
+ 示例:
82
+ cqdata.configure("./config.yaml")
83
+ """
84
+ self.load_from_file(config_path)
85
+ self._refresh_logger()
86
+ return self
87
+
88
+ def _refresh_logger(self) -> None:
89
+ """配置变更后安全刷新 loggerHandler"""
90
+ try:
91
+ from cqdata.utils.logger_utils import setup_logger
92
+ setup_logger(log_level=self.log_level, log_dir=self.log_dir)
93
+ except Exception:
94
+ pass
95
+
96
+ def _update_accessor_defaults(self) -> None:
97
+ """更新全局 accessor defaults 链"""
98
+ try:
99
+ from cqdata.entrypoints.accessors import default
100
+ default.update_from_dict(self.defaults)
101
+ except (ImportError, AttributeError):
102
+ pass
103
+
104
+
105
+ # 全局 Settings 单例实例
106
+ settings = Settings()
@@ -0,0 +1,39 @@
1
+ """
2
+ cqdata/entrypoints/__init__.py
3
+
4
+ 网关层统一导出
5
+ """
6
+
7
+ from cqdata.entrypoints.python_api import (
8
+ read,
9
+ list_tables,
10
+ list_formats,
11
+ list_symbols,
12
+ get_time_range,
13
+ get_schema,
14
+ get_row_count,
15
+ list_boards,
16
+ sync,
17
+ configure
18
+ )
19
+ from cqdata.entrypoints.accessors import (
20
+ default,
21
+ ashare,
22
+ aindex
23
+ )
24
+
25
+ __all__ = [
26
+ "read",
27
+ "list_tables",
28
+ "list_formats",
29
+ "list_symbols",
30
+ "get_time_range",
31
+ "get_schema",
32
+ "get_row_count",
33
+ "list_boards",
34
+ "sync",
35
+ "configure",
36
+ "default",
37
+ "ashare",
38
+ "aindex"
39
+ ]
@@ -0,0 +1,38 @@
1
+ """
2
+ cqdata/entrypoints/accessors/__init__.py
3
+
4
+ OOP 便捷访问层包导出。
5
+ 向外导出 default, ashare, aindex 单例与主要访问类。
6
+ """
7
+
8
+ from cqdata.entrypoints.accessors.base import DefaultConfig, default
9
+ from cqdata.entrypoints.accessors.ashare import (
10
+ AShare,
11
+ AShareKline,
12
+ AShareAdjFactor,
13
+ AShareConcept,
14
+ AShareIndustry,
15
+ AShareDragonTiger,
16
+ AShareInstTrade
17
+ )
18
+ from cqdata.entrypoints.accessors.aindex import AIndex, AIndexKline
19
+
20
+ # 实例化命名空间单例
21
+ ashare = AShare(parent_default=default)
22
+ aindex = AIndex(parent_default=default)
23
+
24
+ __all__ = [
25
+ "DefaultConfig",
26
+ "default",
27
+ "ashare",
28
+ "aindex",
29
+ "AShare",
30
+ "AIndex",
31
+ "AShareKline",
32
+ "AShareAdjFactor",
33
+ "AShareConcept",
34
+ "AShareIndustry",
35
+ "AShareDragonTiger",
36
+ "AShareInstTrade",
37
+ "AIndexKline",
38
+ ]