Files
ProStock/AGENTS.md
liaozhaorun 593ec99466 refactor: 存储层迁移DuckDB + 模块重构
- 存储层重构: HDF5 → DuckDB(UPSERT模式、线程安全存储)
- Sync类迁移: DataSync从sync.py迁移到api_daily.py(职责分离)
- 模型模块重构: src/models → src/pipeline(更清晰的命名)
- 新增因子模块: factors/momentum (MA、收益率排名)、factors/financial
- 新增API接口: api_namechange、api_bak_basic
- 新增训练入口: training模块(main.py、pipeline配置)
- 工具函数统一: get_today_date等移至utils.py
- 文档更新: AGENTS.md添加架构变更历史
2026-02-23 16:23:53 +08:00

332 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ProStock 代理指南
A股量化投资框架 - Python 项目,用于量化股票投资分析。
## 交流语言要求
**⚠️ 强制要求:所有沟通和思考过程必须使用中文。**
所有与 AI Agent 的交流必须使用中文
代码中的注释和文档字符串使用中文
禁止使用英文进行思考或沟通
## 构建/检查/测试命令
**⚠️ 重要:本项目强制使用 uv 作为 Python 包管理器和运行工具。禁止直接使用 `python``pip` 命令。**
```bash
# 安装依赖(必须使用 uv
uv pip install -e .
# 运行所有测试
uv run pytest
# 运行单个测试文件
uv run pytest tests/test_sync.py
# 运行单个测试类
uv run pytest tests/test_sync.py::TestDataSync
# 运行单个测试方法
uv run pytest tests/test_sync.py::TestDataSync::test_get_all_stock_codes_from_daily
# 使用详细输出运行
uv run pytest -v
# 运行覆盖率测试(如果安装了 pytest-cov
uv run pytest --cov=src --cov-report=term-missing
```
### 禁止的命令 ❌
以下命令在本项目中**严格禁止**
```bash
# 禁止直接使用 python
python -c "..." # 禁止!
python script.py # 禁止!
python -m pytest # 禁止!
python -m pip install # 禁止!
# 禁止直接使用 pip
pip install -e . # 禁止!
pip install package # 禁止!
pip list # 禁止!
```
### 正确的 uv 用法 ✅
```bash
# 运行 Python 代码
uv run python -c "..." # ✅ 正确
uv run python script.py # ✅ 正确
# 安装依赖
uv pip install -e . # ✅ 正确
uv pip install package # ✅ 正确
# 运行测试
uv run pytest # ✅ 正确
uv run pytest tests/test_sync.py # ✅ 正确
```
## 项目结构
```
ProStock/
├── src/ # 源代码
│ ├── config/ # 配置管理
│ │ ├── __init__.py
│ │ └── settings.py # pydantic-settings 配置
│ │
│ ├── data/ # 数据获取与存储
│ │ ├── api_wrappers/ # Tushare API 封装
│ │ │ ├── API_INTERFACE_SPEC.md # 接口规范文档
│ │ │ ├── api.md # API 接口定义
│ │ │ ├── api_daily.py # 日线数据接口
│ │ │ ├── api_stock_basic.py # 股票基础信息接口
│ │ │ ├── api_trade_cal.py # 交易日历接口
│ │ │ └── __init__.py
│ │ ├── __init__.py
│ │ ├── client.py # Tushare API 客户端(带速率限制)
│ │ ├── config.py # 数据模块配置
│ │ ├── db_inspector.py # 数据库信息查看工具
│ │ ├── db_manager.py # DuckDB 表管理和同步
│ │ ├── rate_limiter.py # 令牌桶速率限制器
│ │ ├── storage.py # 数据存储核心
│ │ └── sync.py # 数据同步主逻辑
│ │
│ ├── factors/ # 因子计算框架
│ │ ├── __init__.py
│ │ ├── base.py # 因子基类(截面/时序)
│ │ ├── composite.py # 组合因子和标量运算
│ │ ├── data_loader.py # 数据加载器
│ │ ├── data_spec.py # 数据规格定义
│ │ ├── engine.py # 因子执行引擎
│ │ ├── momentum/ # 动量因子
│ │ │ ├── __init__.py
│ │ │ ├── ma.py # 移动平均线
│ │ │ └── return_rank.py # 收益排名
│ │ └── financial/ # 财务因子
│ │ └── __init__.py
│ │
│ ├── pipeline/ # 模型训练管道
│ │ ├── __init__.py
│ │ ├── pipeline.py # 处理流水线
│ │ ├── registry.py # 插件注册中心
│ │ ├── core/ # 核心抽象
│ │ │ ├── __init__.py
│ │ │ ├── base.py # 基类定义
│ │ │ └── splitter.py # 时间序列划分策略
│ │ ├── models/ # 模型实现
│ │ │ ├── __init__.py
│ │ │ └── models.py # LightGBM、CatBoost 等
│ │ └── processors/ # 数据处理器
│ │ ├── __init__.py
│ │ └── processors.py # 标准化、缩尾、中性化等
│ │
│ └── training/ # 训练入口
│ ├── __init__.py
│ ├── main.py # 训练主程序
│ ├── pipeline.py # 训练流程配置
│ └── output/ # 训练输出
│ └── top_stocks.tsv # 推荐股票结果
├── tests/ # 测试文件
│ ├── test_sync.py
│ └── test_daily.py
├── config/ # 配置文件
│ └── .env.local # 环境变量(不在 git 中)
├── data/ # 数据存储DuckDB
├── docs/ # 文档
├── pyproject.toml # 项目配置
└── README.md
```
## 代码风格指南
### Python 版本
- **需要 Python 3.10+**
- 使用现代 Python 特性match/case、海象运算符、类型提示
### 导入
```python
# 标准库优先
import os
import time
from datetime import datetime, timedelta
from pathlib import Path
from typing import Optional, Dict, Callable
from concurrent.futures import ThreadPoolExecutor
import threading
# 第三方包
import pandas as pd
import numpy as np
from tqdm import tqdm
from pydantic_settings import BaseSettings
# 本地模块(使用来自 src 的绝对导入)
from src.data.client import TushareClient
from src.data.storage import Storage
from src.config.settings import get_settings
```
### 类型提示
- **始终使用类型提示** 用于函数参数和返回值
- 对可空类型使用 `Optional[X]`
- 当可用时使用现代联合语法 `X | Y`Python 3.10+
-`typing` 导入类型:`Optional``Dict``Callable`
```python
def sync_single_stock(
self,
ts_code: str,
start_date: str,
end_date: str,
) -> pd.DataFrame:
...
```
### 文档字符串
- 使用 **Google 风格文档字符串**
- 包含 Args、Returns 部分
- 第一行保持简短摘要
```python
def get_next_date(date_str: str) -> str:
"""获取给定日期之后的下一天。
Args:
date_str: YYYYMMDD 格式的日期
Returns:
YYYYMMDD 格式的下一天日期
"""
...
```
### 命名约定
- 变量、函数、方法使用 `snake_case`
- 类使用 `PascalCase`
- 常量使用 `UPPER_CASE`
- 私有方法:`_leading_underscore`
- 受保护属性:`_single_underscore`
### 错误处理
- 使用特定的异常,不要使用裸 `except:`
- 使用上下文记录错误:`print(f"[ERROR] 上下文: {e}")`
- 对 API 调用使用指数退避重试逻辑
- 在关键错误时立即停止(设置停止标志)
```python
try:
data = api.query(...)
except Exception as e:
print(f"[ERROR] 获取 {ts_code} 失败: {e}")
raise # 记录后重新抛出
```
### 配置
- 对所有配置使用 **pydantic-settings**
-`config/.env.local` 文件加载
- 环境变量自动转换:`tushare_token``TUSHARE_TOKEN`
- 对配置单例使用 `@lru_cache()`
### 数据存储
- 使用 **DuckDB** 嵌入式 OLAP 数据库进行持久化
- 存储在 `data/` 目录中(通过 `DATA_PATH` 环境变量配置)
- 使用 UPSERT 模式(`INSERT OR REPLACE`)处理重复数据
- 多线程场景使用 `ThreadSafeStorage.queue_save()` + `flush()` 模式
### 线程与并发
- 对 I/O 密集型任务API 调用)使用 `ThreadPoolExecutor`
- 实现停止标志以实现优雅关闭:`threading.Event()`
- 数据同步默认工作线程数10
- 出错时始终使用 `executor.shutdown(wait=False, cancel_futures=True)`
### 日志记录
- 使用带前缀的 print 语句:`[模块名] 消息`
- 错误格式:`[ERROR] 上下文: 异常`
- 进度:循环中使用 `tqdm`
### 测试
- 使用 **pytest** 框架
- 模拟外部依赖Tushare API
- 使用 `@pytest.fixture` 进行测试设置
- 在导入位置打补丁:`patch('src.data.sync.Storage')`
- 测试成功和错误两种情况
### 日期格式
- 使用 `YYYYMMDD` 字符串格式表示日期
- 辅助函数:`get_today_date()``get_next_date()`
- 完全同步的默认开始日期:`20180101`
### 依赖项
关键包:
- `pandas>=2.0.0` - 数据处理
- `numpy>=1.24.0` - 数值计算
- `tushare>=2.0.0` - A股数据 API
- `pydantic>=2.0.0``pydantic-settings>=2.0.0` - 配置
- `tqdm>=4.65.0` - 进度条
- `pytest` - 测试(开发)
### 环境变量
创建 `config/.env.local`
```bash
TUSHARE_TOKEN=your_token_here
DATA_PATH=data
RATE_LIMIT=100
THREADS=10
```
## 常见任务
```bash
# 同步所有股票(增量)
uv run python -c "from src.data.sync import sync_all; sync_all()"
# 强制完全同步
uv run python -c "from src.data.sync import sync_all; sync_all(force_full=True)"
# 自定义线程数
uv run python -c "from src.data.sync import sync_all; sync_all(max_workers=20)"
```
## 架构变更历史
### v2.0 (2026-02-23) - 重要更新
#### 存储层重构
**变更**: 从 HDF5 迁移到 DuckDB
**原因**: DuckDB 提供更好的查询性能、SQL 下推能力、并发支持
**影响**: 所有数据表现在使用 DuckDB 存储,旧 HDF5 文件可手动迁移
#### Sync 类迁移
**变更**: `DataSync` 类从 `sync.py` 迁移到 `api_daily.py`
**原因**: 实现代码职责分离,每个 API 文件包含自己的同步逻辑
**影响**:
- `sync.py` 保留为调度中心
- `api_daily.py` 包含 `DailySync` 类和 `sync_daily` 函数
#### 新增模块
**pipeline 模块**: 机器学习流水线组件(处理器、模型、划分策略)
**training 模块**: 训练入口程序
**factors/momentum**: 动量因子MA、收益率排名
**factors/financial**: 财务因子框架
**data/utils.py**: 日期工具函数集中管理
#### 新增 API 接口
`api_namechange.py`: 股票曾用名接口(手动同步)
`api_bak_basic.py`: 历史股票列表接口
#### 工具函数统一
`get_today_date()``get_next_date()``DEFAULT_START_DATE` 等函数统一在 `src/data/utils.py` 中管理
其他模块应从 `utils.py` 导入这些函数,避免重复定义
### v1.x (历史版本)
初始版本,使用 HDF5 存储
数据同步逻辑集中在 `sync.py`