feat(data): 添加每日指标接口并优化因子引擎

- 新增 api_daily_basic.py 封装 Tushare 每日指标接口
- 因子引擎移除 lookback_days,支持 daily_basic 表字段路由
- 将每日指标纳入自动同步流程
- 删除废弃的 training/main.py
This commit is contained in:
2026-03-03 17:09:39 +08:00
parent 780284af7f
commit 53225b9443
12 changed files with 1132 additions and 433 deletions

131
AGENTS.md
View File

@@ -82,20 +82,21 @@ ProStock/
│ │
│ ├── data/ # 数据获取与存储
│ │ ├── api_wrappers/ # Tushare API 封装
│ │ │ ├── base_sync.py # 同步基础抽象类(BaseDataSync/StockBasedSync/DateBasedSync)
│ │ │ ├── api_daily.py # 日线数据接口(DailySync)
│ │ │ ├── api_pro_bar.py # Pro Bar 数据接口(ProBarSync)
│ │ │ ├── api_stock_basic.py # 股票基础信息接口
│ │ │ ├── api_trade_cal.py # 交易日历接口
│ │ │ ├── api_bak_basic.py # 历史股票列表接口(BakBasicSync)
│ │ │ ├── api_namechange.py # 股票名称变更接口
│ │ │ ├── financial_data/ # 财务数据接口
│ │ │ │ ├── api_income.py # 利润表接口
│ │ │ ├── base_sync.py # 同步基础抽象类(BaseDataSync/StockBasedSync/DateBasedSync)
│ │ │ ├── api_daily.py # 日线数据接口(DailySync)
│ │ │ ├── api_pro_bar.py # Pro Bar 数据接口(ProBarSync)
│ │ │ ├── api_stock_basic.py # 股票基础信息接口
│ │ │ ├── api_trade_cal.py # 交易日历接口
│ │ │ ├── api_bak_basic.py # 历史股票列表接口(BakBasicSync)
│ │ │ ├── api_namechange.py # 股票名称变更接口
│ │ │ ├── financial_data/ # 财务数据接口
│ │ │ │ ├── api_income.py # 利润表接口
│ │ │ │ └── api_financial_sync.py # 财务数据同步
│ │ │ └── __init__.py
│ │ ├── __init__.py
│ │ ├── client.py # Tushare API 客户端(带速率限制)
│ │ ├── config.py # 数据模块配置
│ │ ├── data_router.py # 数据路由器factors/engine 专用)
│ │ ├── db_inspector.py # 数据库信息查看工具
│ │ ├── db_manager.py # DuckDB 表管理和同步
│ │ ├── rate_limiter.py # 令牌桶速率限制器
@@ -104,20 +105,29 @@ ProStock/
│ │ └── utils.py # 数据模块工具函数
│ │
│ ├── factors/ # 因子计算框架DSL 表达式驱动)
│ │ ├── engine/ # 执行引擎子模块
│ │ │ ├── __init__.py # 导出引擎组件
│ │ │ ├── data_spec.py # 数据规格定义(DataSpec, ExecutionPlan)
│ │ │ ├── data_router.py # 数据路由器
│ │ │ ├── planner.py # 执行计划生成器(ExecutionPlanner)
│ │ │ ├── compute_engine.py # 计算引擎(ComputeEngine)
│ │ │ └── factor_engine.py # 因子引擎统一入口(FactorEngine)
│ │ ├── __init__.py # 导出所有公开 API
│ │ ├── dsl.py # DSL 表达式层 - 节点定义和运算符重载
│ │ ├── api.py # API 层 - 常用符号(close/open等)和函数(ts_mean/cs_rank等)
│ │ ├── compiler.py # AST 编译器 - 依赖提取
│ │ ├── translator.py # Polars 表达式翻译器
│ │ ── engine.py # 因子执行引擎 - 统一入口
│ │ ── parser.py # 字符串公式解析器(FormulaParser)
│ │ ├── registry.py # 函数注册表(FunctionRegistry)
│ │ └── exceptions.py # 异常定义(FormulaParseError等)
│ │
│ ├── pipeline/ # 模型训练管道
│ │ ├── __init__.py
│ │ ├── pipeline.py # 处理流水线
│ │ ├── registry.py # 插件注册中心
│ │ ├── pipeline.py # 处理流水线(ProcessingPipeline)
│ │ ├── registry.py # 插件注册中心(PluginRegistry)
│ │ ├── core/ # 核心抽象
│ │ │ ├── __init__.py
│ │ │ ├── base.py # 基类定义
│ │ │ ├── base.py # 基类定义(BaseProcessor/BaseModel/BaseSplitter等)
│ │ │ └── splitter.py # 时间序列划分策略
│ │ ├── models/ # 模型实现
│ │ │ ├── __init__.py
@@ -128,14 +138,23 @@ ProStock/
│ │
│ └── training/ # 训练入口
│ ├── __init__.py
│ ├── main.py # 训练主程序
│ ├── pipeline.py # 训练流程配置
│ └── output/ # 训练输出
│ └── top_stocks.tsv # 推荐股票结果
├── tests/ # 测试文件
│ ├── test_sync.py
── test_daily.py
── test_daily.py
│ ├── test_factor_engine.py
│ ├── test_factor_integration.py
│ ├── test_pro_bar.py
│ ├── test_601117_factors.py
│ ├── test_two_stocks_string_factors.py
│ ├── test_db_manager.py
│ ├── test_daily_storage.py
│ ├── test_tushare_api.py
│ └── pipeline/
│ └── test_core.py
├── config/ # 配置文件
│ └── .env.local # 环境变量(不在 git 中)
├── data/ # 数据存储DuckDB
@@ -266,10 +285,13 @@ except Exception as e:
### 依赖项
关键包:
- `pandas>=2.0.0` - 数据处理
- `polars>=0.20.0` - 高性能数据处理(因子计算)
- `numpy>=1.24.0` - 数值计算
- `tushare>=2.0.0` - A股数据 API
- `pydantic>=2.0.0``pydantic-settings>=2.0.0` - 配置
- `tqdm>=4.65.0` - 进度条
- `lightgbm>=4.0.0` - 机器学习模型
- `catboost>=1.2.0` - 机器学习模型
- `pytest` - 测试(开发)
### 环境变量
@@ -292,6 +314,9 @@ 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)"
# 运行因子计算测试
uv run pytest tests/test_factor_engine.py -v
```
## 架构变更历史
@@ -309,8 +334,16 @@ uv run python -c "from src.data.sync import sync_all; sync_all(max_workers=20)"
- 新增 `api.py`: 常用符号close/open/volume等和函数ts_mean/cs_rank等
- 新增 `compiler.py`: AST 编译器,提取表达式依赖
- 新增 `translator.py`: 将 DSL 表达式翻译为 Polars 表达式
- 重构 `engine.py`: 统一执行引擎入口,整合 DataRouter、ExecutionPlanner、ComputeEngine
- 移除: `base.py``composite.py``data_loader.py``data_spec.py`
- 新增 `parser.py`: 字符串公式解析器FormulaParser支持从字符串解析 DSL 表达式
- 新增 `registry.py`: 函数注册表FunctionRegistry管理字符串函数名到 Python 函数的映射
- 新增 `exceptions.py`: 公式解析异常定义FormulaParseError、UnknownFunctionError等
- 重构 `engine/` 子模块:
- `factor_engine.py`: 因子引擎统一入口FactorEngine
- `data_spec.py`: 数据规格定义DataSpec, ExecutionPlan
- `data_router.py`: 数据路由器
- `planner.py`: 执行计划生成器ExecutionPlanner
- `compute_engine.py`: 计算引擎ComputeEngine
- 移除: `base.py``composite.py``data_loader.py`、根目录的 `data_spec.py`
- 移除: `factors/momentum/``factors/financial/` 子目录
**使用方式对比**:
```python
@@ -328,6 +361,11 @@ uv run python -c "from src.data.sync import sync_all; sync_all(max_workers=20)"
engine = FactorEngine()
engine.register("ma20", ma20)
result = engine.compute(["ma20"], "20240101", "20240131")
# 字符串公式解析Phase 1 新增)
from src.factors import FormulaParser, FunctionRegistry
parser = FormulaParser(FunctionRegistry())
expr = parser.parse("ts_mean(close, 20) / close") # 从字符串解析
```
#### data 模块补充完善
@@ -411,10 +449,20 @@ DSL 层 (dsl.py) <- 因子表达式 (Node)
Compiler (compiler.py) <- AST 依赖提取
|
v
Parser (parser.py) <- 字符串公式解析器
|
v
Registry (registry.py) <- 函数注册表
|
v
Translator (translator.py) <- 翻译为 Polars 表达式
|
v
Engine (engine.py) <- 执行引擎 (DataRouter/ExecutionPlanner/ComputeEngine)
Engine (engine/) <- 执行引擎
| - FactorEngine: 统一入口
| - DataRouter: 数据路由
| - ExecutionPlanner: 执行计划
| - ComputeEngine: 计算引擎
|
v
数据层 (data_router.py + DuckDB) <- 数据获取和存储
@@ -422,7 +470,7 @@ Engine (engine.py) <- 执行引擎 (DataRouter/ExecutionPlanner/ComputeEngi
### 使用方式
#### 1. 基础表达式
#### 1. 基础表达式DSL 方式)
```python
from src.factors.api import close, open, ts_mean, cs_rank
@@ -435,15 +483,37 @@ price_rank = cs_rank(close) # 收盘价截面排名
alpha = ma20 * 0.6 + price_rank * 0.4
```
#### 2. 注册和执行
#### 2. 字符串公式解析Phase 1 新增)
```python
from src.factors import FormulaParser, FunctionRegistry
# 创建解析器(自动加载 api.py 中的所有函数)
parser = FormulaParser(FunctionRegistry())
# 从字符串解析公式
expr = parser.parse("ts_mean(close, 20) / close")
complex_expr = parser.parse("cs_rank(ts_mean(close, 5) - ts_mean(close, 20))")
# 支持完整运算符和函数调用
expr2 = parser.parse("(close - open) / open * 100") # 涨跌幅
expr3 = parser.parse("ts_corr(close, volume, 20)") # 量价相关性
```
#### 3. 注册和执行
```python
from src.factors import FactorEngine
engine = FactorEngine()
# 注册 DSL 表达式
engine.register("ma20", ma20)
engine.register("price_rank", price_rank)
# 或注册字符串解析的表达式
engine.register("alpha", parser.parse("ma20 * 0.6 + price_rank * 0.4"))
# 执行计算
result = engine.compute(
factor_names=["ma20", "price_rank"],
@@ -504,6 +574,27 @@ expr3 = -change # 涨跌额取反
expr4 = ts_mean(cs_rank(close), 20) # 排名后的20日平滑
```
### 异常处理
框架提供清晰的异常类型帮助定位问题:
- `FormulaParseError` - 公式解析错误基类
- `UnknownFunctionError` - 未知函数错误(提供模糊匹配建议)
- `InvalidSyntaxError` - 语法错误
- `EmptyExpressionError` - 空表达式错误
- `DuplicateFunctionError` - 函数重复注册错误
示例:
```python
from src.factors import FormulaParser, FunctionRegistry, UnknownFunctionError
parser = FormulaParser(FunctionRegistry())
try:
expr = parser.parse("unknown_func(close)")
except UnknownFunctionError as e:
print(e) # 显示错误位置和可用函数建议
```
## AI 行为准则
## AI 行为准则